diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/.quarto/xref/1893bfdc b/.quarto/xref/1893bfdc index 6abc991..8cb276d 100644 --- a/.quarto/xref/1893bfdc +++ b/.quarto/xref/1893bfdc @@ -1 +1 @@ -{"entries":[],"headings":["instructor","outline","get-course-materials","install-required-software","get-the-notes","useful-resources","references","license"]} \ No newline at end of file +{"headings":["instructor","outline","get-course-materials","install-required-software","get-the-notes","useful-resources","references","license"],"entries":[]} \ No newline at end of file diff --git a/.quarto/xref/1b4954b9 b/.quarto/xref/1b4954b9 index 830aec5..13dafd2 100644 --- a/.quarto/xref/1b4954b9 +++ b/.quarto/xref/1b4954b9 @@ -1 +1 @@ -{"headings":["mise-en-place-development-environment","the-structure-flour-and-sugar","the-description-file","keeping-notes","useful-links"],"entries":[]} \ No newline at end of file +{"entries":[],"headings":["mise-en-place-development-environment","the-structure-flour-and-sugar","the-description-file","keeping-notes","useful-links"]} \ No newline at end of file diff --git a/.quarto/xref/a07a8c4b b/.quarto/xref/a07a8c4b index 1acf430..9d3d9c7 100644 --- a/.quarto/xref/a07a8c4b +++ b/.quarto/xref/a07a8c4b @@ -1 +1 @@ -{"headings":["why-do-you-want-to-use-shiny","hello-shiny","how-a-shiny-app-works","building-blocks","ids","organisation","plots","user-interface","server","the-shiny-app","customising-the-theme","using-built-in-themes","using-a-custom-theme","customizing-a-theme","constructing-a-shiny-app-using-shinydashboards","taking-advantage-of-good-defaults","using-shinydashboard","populating-the-layout","challenge","see-the-completed-app","constructing-a-shiny-app-using-golem","golem-modules","selecting-the-volcanoes","barplot-of-continents"],"entries":[]} \ No newline at end of file +{"entries":[],"headings":["why-do-you-want-to-use-shiny","hello-shiny","how-a-shiny-app-works","building-blocks","ids","organisation","plots","user-interface","server","the-shiny-app","customising-the-theme","using-built-in-themes","using-a-custom-theme","customizing-a-theme","constructing-a-shiny-app-using-shinydashboards","taking-advantage-of-good-defaults","using-shinydashboard","populating-the-layout","challenge","see-the-completed-app","constructing-a-shiny-app-using-golem","golem-modules","selecting-the-volcanoes","barplot-of-continents"]} \ No newline at end of file diff --git a/_quarto.yml b/_quarto.yml index 189b7d4..fe29c00 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -1,5 +1,6 @@ project: type: website + output-dir: docs website: title: "BIOS2 Education resources" diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/Bios2_reverse.png b/docs/Bios2_reverse.png new file mode 100644 index 0000000..2ed28ee Binary files /dev/null and b/docs/Bios2_reverse.png differ diff --git a/docs/about.html b/docs/about.html new file mode 100644 index 0000000..745bc86 --- /dev/null +++ b/docs/about.html @@ -0,0 +1,290 @@ + + + + + + + + + +BIOS2 Education resources - About + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+ + + + +
+ +
+
+

About

+
+
+
+
+

About this blog

+ + +
+
+ +
+ + +
+ + + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..7178d48 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,764 @@ + + + + + + + + + +BIOS2 Education resources + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + + + \ No newline at end of file diff --git a/docs/listings.json b/docs/listings.json new file mode 100644 index 0000000..e9e9796 --- /dev/null +++ b/docs/listings.json @@ -0,0 +1,18 @@ +[ + { + "listing": "/index.html", + "items": [ + "/posts/2021-06-22-introduction-to-shiny-apps/index.html", + "/posts/2021-07-19-glm-community-ecology/index.html", + "/posts/2021-05-04-building-r-packages/index.html", + "/posts/2021-03-25-point-count-data-analysis/index.html", + "/posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/index.html", + "/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html", + "/posts/2020-12-07-making-websites-with-hugo/index.html", + "/posts/2020-09-21-data-visualization/index.html", + "/posts/2020-06-15-science-communication/index.html", + "/posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/index.html", + "/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/index.html" + ] + } +] \ No newline at end of file diff --git a/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/StabilityPictures.jpg b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/StabilityPictures.jpg new file mode 100644 index 0000000..bf90a33 Binary files /dev/null and b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/StabilityPictures.jpg differ diff --git a/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/StabilityPictures.png b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/StabilityPictures.png new file mode 100644 index 0000000..10ad9ab Binary files /dev/null and b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/StabilityPictures.png differ diff --git a/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/BIOS2_WorkshopMathematica.nb b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/BIOS2_WorkshopMathematica.nb new file mode 100644 index 0000000..3af6c71 --- /dev/null +++ b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/BIOS2_WorkshopMathematica.nb @@ -0,0 +1,4479 @@ +(* Content-type: application/mathematica *) + +(*** Wolfram Notebook File ***) +(* http://www.wolfram.com/nb *) + +(* CreatedBy='Mathematica 6.0' *) + +(*CacheID: 234*) +(* Internal cache information: +NotebookFileLineBreakTest +NotebookFileLineBreakTest +NotebookDataPosition[ 145, 7] +NotebookDataLength[ 173181, 4471] +NotebookOptionsPosition[ 153188, 4185] +NotebookOutlinePosition[ 153778, 4205] +CellTagsIndexPosition[ 153735, 4202] +WindowFrame->Normal*) + +(* Beginning of Notebook Content *) +Notebook[{ + +Cell[CellGroupData[{ +Cell[TextData[{ + StyleBox["An Introduction to Mathematical Modeling in Ecology and Evolution\n\ +\t\t", + FontSize->24], + StyleBox["Sally Otto (2020)", "Text", + FontSize->24] +}], "Title", + CellChangeTimes->{{3.5139469945181007`*^9, 3.5139470031089993`*^9}, { + 3.5139470749751873`*^9, 3.51394707739872*^9}, 3.514081679254755*^9, + 3.5635847030731*^9, 3.589034444732832*^9, 3.619865854931665*^9, { + 3.787357889985818*^9, + 3.78735789006644*^9}},ExpressionUUID->"bf3838d1-38f9-4115-ac68-\ +fd6a09d867b9"], + +Cell[TextData[{ + StyleBox["Sponsors:\n", + FontWeight->"Bold"], + "BIOS2 (NSERC - CREATE Training program)\n", + StyleBox["\nResources:\n* ", + FontWeight->"Bold"], + StyleBox["An Introduction to Mathematical Modeling in Ecology and Evolution", + + FontSlant->"Italic"], + " (2007) by Otto and Day\n* Biomathematical modeling lecture notes \ +(http://www.zoology.ubc.ca/~bio301/Bio301/Lectures.html)\n* ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " labs (http://www.zoology.ubc.ca/biomath/labs.htm)" +}], "Text", + CellChangeTimes->{{3.787357970535242*^9, + 3.787358015823761*^9}},ExpressionUUID->"471d3ee9-dbba-4c5e-b100-\ +311cbd91d468"], + +Cell[CellGroupData[{ + +Cell["\<\ +Part 1: Classic one-variable models in ecology and evolution\ +\>", "Section", + CellChangeTimes->{{3.513947212490135*^9, 3.513947218035974*^9}, { + 3.5139498791123238`*^9, 3.513949882837112*^9}, {3.5139528239741087`*^9, + 3.513952837318131*^9}, {3.5141651837854567`*^9, + 3.514165197895406*^9}},ExpressionUUID->"84d066d3-ebc0-421e-aa4d-\ +b53a2c930db2"], + +Cell[CellGroupData[{ + +Cell["Exponential growth", "Subsection", + CellChangeTimes->{{3.513947230674706*^9, + 3.513947234068375*^9}},ExpressionUUID->"745d7dae-e470-43ab-ba1e-\ +0b8f85831fd6"], + +Cell[TextData[{ + "Assumes that each individual replicates at a constant rate over time:\n\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", " ", + RowBox[{"R", " ", + RowBox[{"n", "[", "t", "]"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"6754c45d-9391-4ea2-903e-8263f7d22e7e"], + "\t\tDiscrete-time model (\"", + StyleBox["Recursion equation", + FontColor->RGBColor[1, 0, 0]], + "\")\n\t\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + FractionBox["dn", "dt"], "=", + RowBox[{ + RowBox[{ + SuperscriptBox["n", "\[Prime]", + MultilineFunction->None], "[", "t", "]"}], "=", " ", + RowBox[{"r", " ", + RowBox[{"n", "[", "t", "]"}]}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"e2cfd871-1b78-43f6-9ccc-975596eb6bf5"], + "\t\tContinuous-time model (\"", + StyleBox["Differential equation", + FontColor->RGBColor[1, 0, 0]], + "\")\n\t\nn[t]:\tThe population size at time t \nR:\tThe number of offspring \ +per parent in a time unit (from t to t+1).\nr:\tThe growth rate per parent \ +per time unit." +}], "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.513947390108379*^9, 3.5139474220813217`*^9}, {3.513947452990963*^9, + 3.5139475208704576`*^9}, {3.513947727092204*^9, 3.513947731187154*^9}, { + 3.513947812189878*^9, 3.513947902559455*^9}, {3.513947984682602*^9, + 3.513948011709552*^9}, {3.513948963092691*^9, 3.51394897018489*^9}, { + 3.513954053195573*^9, 3.513954074185573*^9}, {3.5145474240085497`*^9, + 3.5145474291411467`*^9}, {3.514547460954069*^9, 3.5145474627557096`*^9}, + 3.5146778392129917`*^9},ExpressionUUID->"bf485b3e-2c6f-400c-ab53-\ +06b746d14258"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Logistic growth", "Subsection", + CellChangeTimes->{{3.513947230674706*^9, 3.513947234068375*^9}, { + 3.513947350245451*^9, + 3.5139473511317797`*^9}},ExpressionUUID->"7e4e226d-5b30-4966-af1c-\ +68299633d063"], + +Cell[TextData[{ + "Assumes that each individual replicates at a rate that declines as a linear \ +function of the current population size:\n\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}]}]}], ")"}], + RowBox[{"n", "[", "t", "]"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"a28c89c7-9f57-4e13-af49-331e42fb4947"], + "\t\t\t\tDiscrete-time model\n\t\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dn", "dt"], "=", + RowBox[{ + RowBox[{ + SuperscriptBox["n", "\[Prime]", + MultilineFunction->None], "[", "t", "]"}], "=", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}], " ", + RowBox[{"n", "[", "t", "]"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"0211dff7-ae2d-46aa-8776-0158dfbce1b6"], + "\t\t\t\t\tContinuous-time model\n\t\nr: \tThe \"intrinsic\" growth rate \ +per parent per unit time, realized when competition is weak (population size \ +small)\nK: \tThe \"carrying capacity\" defined as the population size at \ +which competition causes the population to neither grow nor shrink" +}], "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.5139475325082417`*^9, 3.51394758040838*^9}, {3.5139476417549477`*^9, + 3.513947714905636*^9}, {3.513947913524728*^9, 3.513947982531314*^9}, { + 3.513948017290382*^9, 3.513948113203456*^9}, {3.5139488721875877`*^9, + 3.513948951376718*^9}},ExpressionUUID->"cff61acc-ee75-4f59-96c5-\ +dae0b0ceb4e0"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Haploid model of selection", "Subsection", + CellChangeTimes->{{3.513947230674706*^9, 3.513947234068375*^9}, { + 3.513947350245451*^9, + 3.513947360443203*^9}},ExpressionUUID->"c26cf99e-7540-4a41-a320-\ +0c4f3a6dcf47"], + +Cell[TextData[{ + "Assumes that each individual carrying A has a fitness of 1+s relative to \ +individuals carrying a, where p is the frequency of A:\n\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + RowBox[{"p", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"7ab90b12-1f55-4aff-a121-afc9a4557c18"], + "\t\t\t\t\tDiscrete-time model\n\t\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dp", "dt"], "=", + RowBox[{ + RowBox[{ + SuperscriptBox["p", "\[Prime]", + MultilineFunction->None], "[", "t", "]"}], "=", + RowBox[{"s", " ", + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"52b7b944-d423-4a29-a02a-dfca40ec6411"], + "\t\t\t\t\tContinuous-time model\n\t\np:\tFrequency of allele ", + StyleBox["A", + FontSlant->"Italic"], + " at a locus with two alleles (", + StyleBox["a", + FontSlant->"Italic"], + " and ", + StyleBox["A", + FontSlant->"Italic"], + "). ", + StyleBox["p", + FontSlant->"Italic"], + " must lie between 0 and 1.\ns:\tSelection coefficient favoring allele ", + StyleBox["A", + FontSlant->"Italic"], + " over ", + StyleBox["a.", + FontSlant->"Italic"] +}], "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.5139475325082417`*^9, 3.51394758040838*^9}, {3.5139476417549477`*^9, + 3.513947714905636*^9}, {3.513947913524728*^9, 3.513947982531314*^9}, { + 3.513948017290382*^9, 3.513948113203456*^9}, {3.51394894565186*^9, + 3.513949092099876*^9}, {3.5145478284401484`*^9, + 3.5145478519562063`*^9}},ExpressionUUID->"3b7b6503-c41a-4e20-9a83-\ +6f25e3cfbe8b"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[TextData[{ + "Getting used to ", + StyleBox["Mathematica", + FontSlant->"Italic"] +}], "Subsection", + CellChangeTimes->{{3.513948127281714*^9, + 3.513948137855798*^9}},ExpressionUUID->"95c63cef-fb38-4dcf-9888-\ +321aa7d31904"], + +Cell[TextData[{ + StyleBox["Mathematica", + FontSlant->"Italic"], + " can be used as a sophisticated calculator." +}], "Text", + CellChangeTimes->{{3.513948198540515*^9, + 3.513948235067747*^9}},ExpressionUUID->"fcedfe7d-5fc9-45a3-8197-\ +a29be16f17da"], + +Cell["\<\ +For example, if r = 0.3, K = 100, and n = 90 at some time, what population \ +size do we expect in the next generation given logistic growth?\ +\>", "Text", + CellChangeTimes->{{3.513948237712743*^9, 3.513948264443959*^9}, { + 3.513948665451997*^9, 3.513948670365511*^9}, {3.514515557424759*^9, + 3.514515560446452*^9}},ExpressionUUID->"133bf198-51fd-4008-8758-\ +ff51032495c2"], + +Cell[BoxData[ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox["n", "K"]}], ")"}]}]}], ")"}], "n"}], "/.", + RowBox[{"n", "\[Rule]", "90"}]}], "/.", + RowBox[{"r", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"K", "\[Rule]", "100"}]}]], "Input", + CellChangeTimes->{{3.513948287127791*^9, 3.513948302422172*^9}, { + 3.513948679036108*^9, + 3.5139486822503233`*^9}},ExpressionUUID->"b5c7ed8d-60c0-4377-a2ad-\ +e75b37ffeb73"], + +Cell[TextData[{ + StyleBox["Mathematica", + FontSlant->"Italic"], + " can also plot functions.\n\nFor example, the per capita number of \ +offspring per parent in the logistic model:" +}], "Text", + CellChangeTimes->{{3.513948237712743*^9, 3.513948264443959*^9}, { + 3.51394832016193*^9, 3.513948337930262*^9}, {3.513948397404797*^9, + 3.513948401530624*^9}, {3.5139484555709047`*^9, 3.513948474384674*^9}, + 3.514515568645393*^9},ExpressionUUID->"fdbf74a1-a883-4b86-9148-\ +4e8d40ad0715"], + +Cell[BoxData[ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox["n", "K"]}], ")"}]}]}], ")"}], "/.", + RowBox[{"r", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"K", "\[Rule]", "100"}]}], ",", + RowBox[{"{", + RowBox[{"n", ",", "0", ",", "250"}], "}"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{"Automatic", ",", + RowBox[{"{", + RowBox[{"0", ",", "1.5"}], "}"}]}], "}"}]}], ",", + RowBox[{"AxesLabel", "\[Rule]", + RowBox[{"{", + RowBox[{"\"\\"", ",", "\"\\""}], "}"}]}]}], "]"}]], "Input", + CellChangeTimes->{{3.513948425105887*^9, 3.513948439648486*^9}, { + 3.5139486842958097`*^9, 3.513948685978443*^9}, {3.619896451951356*^9, + 3.619896469558881*^9}},ExpressionUUID->"1ffba96a-cf11-4216-b7a0-\ +a137e9401287"], + +Cell[BoxData[ + RowBox[{"Manipulate", "[", + RowBox[{ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox["n", "K"]}], ")"}]}]}], ")"}], ",", + RowBox[{"{", + RowBox[{"n", ",", "0", ",", "250"}], "}"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{"Automatic", ",", + RowBox[{"{", + RowBox[{"0", ",", "1.5"}], "}"}]}], "}"}]}]}], "]"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"r", ",", "0.3"}], "}"}], ",", "0.01", ",", "0.5"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"K", ",", "100"}], "}"}], ",", "10", ",", "200"}], "}"}]}], + "]"}]], "Input", + CellChangeTimes->{{3.563585040878352*^9, + 3.5635850910666943`*^9}},ExpressionUUID->"3605d36d-880a-4e26-a4a9-\ +10a5fa3fc0c7"], + +Cell["\<\ +Or the number of offspring produced by the entire population in the logistic \ +model:\ +\>", "Text", + CellChangeTimes->{{3.513948485746283*^9, + 3.5139485180034647`*^9}},ExpressionUUID->"5670437f-1e21-4a0e-a658-\ +5fff83586f07"], + +Cell[BoxData[ + RowBox[{"Manipulate", "[", + RowBox[{ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox["n", "K"]}], ")"}]}]}], ")"}], "*", "n"}], ",", + RowBox[{"{", + RowBox[{"n", ",", "0", ",", "250"}], "}"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{"Automatic", ",", + RowBox[{"{", + RowBox[{"0", ",", "200"}], "}"}]}], "}"}]}]}], "]"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"r", ",", "0.3"}], "}"}], ",", "0.01", ",", "0.5"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"K", ",", "100"}], "}"}], ",", "10", ",", "200"}], "}"}]}], + "]"}]], "Input", + CellChangeTimes->{{3.563585040878352*^9, 3.563585127124732*^9}, { + 3.563585248119401*^9, + 3.5635852635674353`*^9}},ExpressionUUID->"d8e9a96d-7418-46d3-99a8-\ +7dc4cb1515de"], + +Cell[TextData[{ + "The real power of ", + StyleBox["Mathematica,", + FontSlant->"Italic"], + " however, is that it can handle commands involving variables and parameters \ +without having to specify their values.\n\nFor example, at what population \ +size do we see the largest total number of offspring produced in the logistic \ +model?" +}], "Text", + CellChangeTimes->{{3.513948159513774*^9, 3.5139481895673933`*^9}, { + 3.513948535766183*^9, 3.5139485481480093`*^9}, {3.513948581393544*^9, + 3.5139486416127234`*^9}},ExpressionUUID->"a1d927fc-113b-441f-82b7-\ +e01b7f1d81eb"], + +Cell[BoxData[ + RowBox[{"D", "[", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox["n", "K"]}], ")"}]}]}], ")"}], "n"}], ",", "n"}], + "]"}]], "Input", + CellChangeTimes->{{3.513948648902672*^9, 3.513948654246675*^9}, { + 3.5139487005589743`*^9, + 3.513948705274877*^9}},ExpressionUUID->"95c08a0f-8e7d-402e-a130-\ +9b84f90c70b1"], + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"%", "\[Equal]", "0"}], ",", "n"}], "]"}]], "Input", + CellChangeTimes->{{3.513948714912499*^9, 3.513948731598783*^9}, { + 3.5139487802271013`*^9, + 3.513948788486806*^9}},ExpressionUUID->"cf7c98ff-8700-4454-97ec-\ +f12cf2371db3"], + +Cell[CellGroupData[{ + +Cell["Question 1: At what speed does an allele rise in frequency?", \ +"Subsubsection", + CellChangeTimes->{{3.51394814025489*^9, 3.513948145584239*^9}, { + 3.513948808098681*^9, 3.5139488496649723`*^9}, {3.5139491033219757`*^9, + 3.513949116352789*^9}},ExpressionUUID->"1eec161d-e632-4814-9fe6-\ +b8661bb5d925"], + +Cell[TextData[{ + "Using the continuous-time model, plot the rate of change ", + Cell[BoxData[ + RowBox[{"s", " ", "p", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"ca5c2ef6-2225-4e94-84dc-8bed159e69c6"], + "as a function of ", + Cell[BoxData["p"], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"2b3ef13d-e10e-4c8c-91bd-02822b8666c8"], + " (between 0 and 1). Choose whatever numerical value of ", + Cell[BoxData["s"], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"2c1f2fe8-2f93-495f-bb3e-264c1ec6bb1d"], + " you wish." +}], "Text", + CellChangeTimes->{{3.513948852926982*^9, 3.5139488676243277`*^9}, { + 3.513949099585382*^9, 3.5139492404693527`*^9}, 3.513949389000252*^9, { + 3.51395287009256*^9, 3.513952871211212*^9}, {3.619895319232109*^9, + 3.619895321155569*^9}, {3.620040594068589*^9, + 3.62004059447488*^9}},ExpressionUUID->"e0260936-e603-4b32-9684-\ +b635c9d33231"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Question 2: When is evolutionary change fastest?", "Subsubsection", + CellChangeTimes->{{3.51394814025489*^9, 3.513948145584239*^9}, { + 3.513948808098681*^9, 3.5139488496649723`*^9}, {3.5139491033219757`*^9, + 3.513949116352789*^9}, {3.513949233431561*^9, 3.5139492553327103`*^9}, { + 3.513954323615156*^9, + 3.513954325807782*^9}},ExpressionUUID->"db38a225-790f-4cf5-a3dc-\ +74ac97c02ad9"], + +Cell[TextData[{ + "Again, using the continuous-time model, ", + Cell[BoxData[ + RowBox[{ + FractionBox["dp", "dt"], "=", + RowBox[{"s", " ", + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"deaaff0c-6472-414b-815c-63f30882300d"], + ", what value of ", + Cell[BoxData["p"], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"3d8b3479-bdc5-4ec6-b864-5f2b79b5c3fc"], + " maximizes the rate of allele frequency change? Use D[ ] to find this \ +result analytically, for any possible value of ", + Cell[BoxData["s"], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"7525cb58-3de9-4878-aeae-081339c2f9fb"], + ". " +}], "Text", + CellChangeTimes->{{3.513948852926982*^9, 3.5139488676243277`*^9}, { + 3.513949099585382*^9, 3.5139492193176947`*^9}, {3.513949257533883*^9, + 3.5139492748936996`*^9}, {3.513949321630436*^9, 3.513949394617585*^9}, { + 3.5139497524605*^9, 3.5139497575494204`*^9}, {3.514423008423018*^9, + 3.5144230126819553`*^9}, + 3.5145156793980703`*^9},ExpressionUUID->"fdde2cf5-3d40-4a83-84f1-\ +875a1e64f492"] +}, Open ]] +}, Open ]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Part 2: Equilibria and their stability", "Section", + CellChangeTimes->{{3.513947212490135*^9, 3.513947218035974*^9}, { + 3.5139498791123238`*^9, 3.513949882837112*^9}, {3.5139527893987713`*^9, + 3.513952819590952*^9}, {3.514165147827382*^9, + 3.514165180112595*^9}},ExpressionUUID->"c18e009c-3dae-4f4a-8cf0-\ +a2572f70c129"], + +Cell[CellGroupData[{ + +Cell["Equilibria", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, + 3.513952890146652*^9}},ExpressionUUID->"b043ff20-0483-4750-827a-\ +153fee482437"], + +Cell[TextData[{ + StyleBox["DEFINITION: ", + FontWeight->"Bold"], + " An ", + StyleBox["equilibrium", + FontColor->RGBColor[1, 0, 0]], + " is a special value of a variable such that if a system starts at that \ +value, it stays there.\n\n", + StyleBox["RECIPE: ", + FontWeight->"Bold"], + "We find equilibria by:\n\t* Setting the variable at one time and the next \ +(n[t + 1] and n[t]) to the same equilibrium value, ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]],ExpressionUUID-> + "9b169aa2-de1a-4142-9155-146a01490711"], + ",\t(Discrete-time model)\n\t* Setting the change in a variable (", + Cell[BoxData[ + FractionBox["dn", "dt"]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"78e93962-d8a1-4fbb-9d2e-d99789225de6"], + ") to zero when started at ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]],ExpressionUUID-> + "2246eeb1-8595-41b1-9e45-589f4a7e7274"], + ",\t\t\t\t\t(Continuous-time model)\nand then solving for the value(s) of ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]],ExpressionUUID-> + "852be1c6-bfab-443a-9799-46d78a4840b7"], + " that satisfy the resulting equations." +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117310317294*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"68d497e4-d5c7-4d55-aeee-2a9cd096f91e"], + +Cell[TextData[{ + "E.g., in the logistic model, if the population size at time t is ", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "=", + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"94896a3d-e4c4-4428-95d8-ff8ef519aaa6"], + ", it will remain at this value only if ", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "=", + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"b2a53a4d-f198-4a63-8068-bbb6f88cdff0"], + ".\nThis gives us an equation that we can solve for ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"99aaf38b-5280-4e8e-bd85-2299195650c4"], + ", by replacing all instances of ", + Cell[BoxData["n"], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"0b326f2e-166d-445a-8ad9-edef57873adf"], + " with", + Cell[BoxData[ + RowBox[{" ", + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"49389f2f-0674-4300-9693-1c6d421a96de"], + " in ", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}]}]}], ")"}], + RowBox[{"n", "[", "t", "]"}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"56ce21f4-1d2b-4fdf-a31c-f71c1a9fa204"], + "." +}], "Text", + CellChangeTimes->{{3.513953444457696*^9, 3.513953665480241*^9}, { + 3.513953828786998*^9, 3.513953835425035*^9}, {3.514515726867031*^9, + 3.514515730170032*^9}},ExpressionUUID->"8d7d772e-5c56-417f-9450-\ +62a6ae2cc0a9"], + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{ + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm], " ", "==", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm], "K"]}], ")"}]}]}], ")"}], + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}]}], ",", + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}], "]"}]], "Input", + CellChangeTimes->{{3.5139532622009068`*^9, + 3.513953273073205*^9}},ExpressionUUID->"24b4094a-be36-4137-a546-\ +ef831b6e73ac"], + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"n", "==", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"n", "/", "K"}]}], ")"}]}]}], ")"}], "n"}]}], ",", "n"}], + "]"}]], "Input", + CellChangeTimes->{{3.514552345442418*^9, + 3.514552383521345*^9}},ExpressionUUID->"54f620a3-189d-45ae-bc4b-\ +0f82c9186d99"], + +Cell[TextData[{ + "NOTE: We use == instead of = here because we don't want to set ", + Cell[BoxData[ + RowBox[{ + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm], " "}]], + CellChangeTimes->{{3.5139532622009068`*^9, 3.513953273073205*^9}}, + ExpressionUUID->"51cf3536-0b82-4646-af68-7484100181b7"], + "equal to the right-hand side, we want TO TEST when the left and right will \ +be equal." +}], "Text", + CellChangeTimes->{{3.513953845501972*^9, + 3.513953878628409*^9}},ExpressionUUID->"1735d295-10d7-4b5e-89bf-\ +5368211fa09d"], + +Cell[TextData[{ + "Similarly, in continuous-time, we determine what value of ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"62ae01c3-3b3c-4cbb-8753-16d1bf4de9a9"], + " causes ", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + FractionBox["dn", "dt"], "=", " ", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}], " ", + RowBox[{"n", "[", "t", "]"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"2940bac1-e7f7-4084-9bd7-8bb1cdec3afd"], + " to equal zero:" +}], "Text", + CellChangeTimes->{{3.513953444457696*^9, 3.513953748754612*^9}, { + 3.513953787893159*^9, + 3.5139537887802153`*^9}},ExpressionUUID->"56c603b0-c515-4b59-9f2f-\ +0873f0f987bc"], + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"0", "==", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm], "K"]}], ")"}], + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}]}], ",", + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}], "]"}]], "Input", + CellChangeTimes->{{3.513953324623784*^9, + 3.5139533313577223`*^9}},ExpressionUUID->"b5627452-f3f9-47e3-8db4-\ +d31e757ecbeb"], + +Cell[CellGroupData[{ + +Cell["\<\ +Question 3: What are the equilibria for the haploid model of selection?\ +\>", "Subsubsection", + CellChangeTimes->{{3.51394814025489*^9, 3.513948145584239*^9}, { + 3.513948808098681*^9, 3.5139488496649723`*^9}, {3.5139491033219757`*^9, + 3.513949116352789*^9}, {3.5139539142255583`*^9, 3.513953950682358*^9}, { + 3.513954320569996*^9, + 3.513954332097341*^9}},ExpressionUUID->"f528b24c-43e5-496e-af92-\ +4205e4487846"], + +Cell[TextData[{ + "Find ", + Cell[BoxData[ + FormBox[ + OverscriptBox["p", "^"], TraditionalForm]],ExpressionUUID-> + "3a44c4f9-640c-4ffe-b8b6-ebc02e3683aa"], + " for both the discrete-time and continuous-time models:\n\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + RowBox[{"p", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"31375f4a-73b3-4599-99e7-94bf56d89e38"], + "\t\t\t\t\tDiscrete-time model\n\t\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dp", "dt"], "=", + RowBox[{ + RowBox[{ + SuperscriptBox["p", "\[Prime]", + MultilineFunction->None], "[", "t", "]"}], "=", + RowBox[{"s", " ", + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"fce0f0ba-b4c6-45ca-8dbf-e70635558808"], + "\t\t\t\t\tContinuous-time model\n\t\nFirst, use ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " to solve for ", + Cell[BoxData[ + FormBox[ + OverscriptBox["p", "^"], TraditionalForm]],ExpressionUUID-> + "13546116-98e2-45bc-80a6-13251b948e55"], + " analytically, then carry out the calculations by hand to confirm your \ +answer." +}], "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.5139475325082417`*^9, 3.51394758040838*^9}, {3.5139476417549477`*^9, + 3.513947714905636*^9}, {3.513947913524728*^9, 3.513947982531314*^9}, { + 3.513948017290382*^9, 3.513948113203456*^9}, {3.51394894565186*^9, + 3.513949092099876*^9}, {3.513953965380247*^9, 3.513954016760906*^9}, { + 3.513954339220845*^9, 3.513954345520956*^9}, {3.513954414894065*^9, + 3.513954469204207*^9}, {3.514515787509324*^9, + 3.514515816945612*^9}},ExpressionUUID->"66ab879c-0122-4ccd-8248-\ +80befefb0463"] +}, Open ]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Stability", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.51395448884634*^9, + 3.513954489788062*^9}},ExpressionUUID->"f0dd8c75-3e97-47c8-8eba-\ +3d8ae0aaec88"], + +Cell["\<\ +A system may or may not move toward a particular equilibrium.\ +\>", "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.513954558138726*^9, + 3.513954567740512*^9}, {3.513954646641127*^9, 3.513954959224346*^9}, { + 3.51395503435863*^9, 3.513955036549271*^9}, {3.513955808112068*^9, + 3.513955827145928*^9}, {3.5139562760990334`*^9, 3.513956403467185*^9}, { + 3.5139565012215347`*^9, 3.513956531165784*^9}, 3.513956573839028*^9, { + 3.513956783731927*^9, 3.5139568012276773`*^9}, {3.514116820097149*^9, + 3.5141168314840097`*^9}, {3.514116935475194*^9, 3.5141169358821573`*^9}, { + 3.5141174296927032`*^9, + 3.514117449201955*^9}},ExpressionUUID->"5ae67325-e62f-436a-ab79-\ +cec5bbfa6bf2"], + +Cell[TextData[{ + StyleBox["DEFINITION: ", + FontWeight->"Bold"], + " An equilibrium is ", + StyleBox["locally stable", + FontColor->RGBColor[1, 0, 0]], + " if a system near the equilibrium approaches it (attracting). An \ +equilibrium is ", + StyleBox["unstable", + FontColor->RGBColor[1, 0, 0]], + " if a system near the equilibrium moves away from it (repelling). " +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117377492393*^9}, { + 3.5141174250611267`*^9, 3.5141174260424957`*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"3e9805f3-ef36-490e-b855-cf728407b7cc"], + +Cell[TextData[{ + "A ", + StyleBox["local stability analysis", + FontColor->RGBColor[1, 0, 0]], + " determines whether a system that starts near an equilibrium moves toward \ +(stable) or away from it (unstable).\n\n", + StyleBox["The idea: ", + FontWeight->"Bold"], + " We approximate the dynamics of a model near an equilibrium and then \ +determine how it moves. To do so, we use an incredibly useful approximation \ +tool: the ", + StyleBox["Taylor Series", + FontColor->RGBColor[1, 0, 0]], + "." +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.513954558138726*^9, + 3.513954567740512*^9}, {3.513954646641127*^9, 3.513954959224346*^9}, { + 3.51395503435863*^9, 3.513955036549271*^9}, {3.513955808112068*^9, + 3.513955827145928*^9}, {3.5139562760990334`*^9, 3.513956403467185*^9}, { + 3.5139565012215347`*^9, 3.513956531165784*^9}, 3.513956573839028*^9, { + 3.513956783731927*^9, 3.5139568012276773`*^9}, {3.514116820097149*^9, + 3.5141168314840097`*^9}, {3.514116935475194*^9, 3.5141169358821573`*^9}, { + 3.514117452739401*^9, + 3.514117453475349*^9}},ExpressionUUID->"25e1c6a1-e8dc-4834-84b9-\ +ac7e0b040ecb"], + +Cell[TextData[{ + StyleBox["Taylor series: ", + FontWeight->"Bold"], + " For any nicely behaved function, f, of a variable, x[t], we can write the \ +function around ", + Cell[BoxData[ + FormBox[ + OverscriptBox["x", "^"], TraditionalForm]],ExpressionUUID-> + "c096dcc9-772f-4a6f-b723-4e570a73e017"], + " as a series of terms, ", + Cell[BoxData[ + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}], "i"]], + CellChangeTimes->{3.513956480106298*^9},ExpressionUUID-> + "d3f4e048-0693-48df-a19a-164616e3b052"], + ":" +}], "Text", + CellChangeTimes->{{3.514116887206808*^9, 3.5141168895317717`*^9}, + 3.5141174643724527`*^9}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"41742680-6e08-4ab6-be2e-53086ccd98eb"], + +Cell[BoxData[ + RowBox[{"Series", "[", + RowBox[{ + RowBox[{"f", "[", + RowBox[{"x", "[", "t", "]"}], "]"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], ",", + FormBox[ + OverscriptBox["x", "^"], + TraditionalForm], ",", "10"}], " ", "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5139564742034597`*^9, 3.513956478521184*^9}, + 3.513956539263496*^9, {3.513956806733952*^9, 3.513956817279278*^9}, { + 3.619898638797448*^9, 3.619898647846127*^9}, {3.6198987016273003`*^9, + 3.6198987021717854`*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"ca40814b-154f-4bed-830f-cccb4753cfe2"], + +Cell["\<\ +For example, Sin[x] can be rewritten as the following function around the \ +point 1/2:\ +\>", "Text", + CellChangeTimes->{{3.513956684327486*^9, 3.513956690461039*^9}, { + 3.513956834878943*^9, 3.513956849921122*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"eb354cf0-c358-417d-a500-b53500dad939"], + +Cell[BoxData[ + RowBox[{"Series", "[", + RowBox[{ + RowBox[{"Sin", "[", "x", "]"}], ",", + RowBox[{"{", + RowBox[{"x", ",", + RowBox[{"1", "/", "2"}], ",", "4"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{ + 3.513956695872752*^9, 3.5139568287948*^9, {3.5141168469483747`*^9, + 3.514116850046146*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"7f8f3a8e-904f-486e-9660-12ea77f934bc"], + +Cell[TextData[{ + "If we are close enough to the point of interest, then ", + Cell[BoxData[ + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}], "i"]], + CellChangeTimes->{3.513956480106298*^9},ExpressionUUID-> + "f056cbc6-8335-413f-aba9-381c22cd492e"], + " will be small, and we can drop terms that we consider to be negligible.\n\n\ +Constant approximation (drops ", + Cell[BoxData[ + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}], "i"]], + CellChangeTimes->{3.513956480106298*^9},ExpressionUUID-> + "4b42366f-f362-48e4-8266-3b71d797d719"], + " for i > 0):" +}], "Text", + CellChangeTimes->{{3.5139565789357862`*^9, 3.513956637482334*^9}, { + 3.513956711646802*^9, 3.513956776923006*^9}, {3.513956862553155*^9, + 3.513956940432847*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"e4e578da-8f49-4cd7-b4aa-a8ac0cd33a78"], + +Cell[BoxData[ + RowBox[{"const", "=", + RowBox[{"Normal", "[", + RowBox[{"Series", "[", + RowBox[{ + RowBox[{"Sin", "[", "x", "]"}], ",", + RowBox[{"{", + RowBox[{"x", ",", + RowBox[{"1", "/", "2"}], ",", "0"}], "}"}]}], "]"}], "]"}]}]], "Input",\ + + CellChangeTimes->{ + 3.513956604309889*^9, {3.51395663986055*^9, 3.513956645179866*^9}, { + 3.513956988009224*^9, 3.513956988657848*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"e12bb329-4c90-44ae-8276-770f12f46899"], + +Cell[TextData[{ + "Linear approximation (drops ", + Cell[BoxData[ + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}], "i"]], + CellChangeTimes->{3.513956480106298*^9},ExpressionUUID-> + "a661c87f-0af0-4662-b355-7a92e5201bea"], + " for i > 1):" +}], "Text", + CellChangeTimes->{{3.5139565789357862`*^9, 3.5139566583618107`*^9}, { + 3.51395694691525*^9, 3.513956949849147*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"4348be8d-f55f-4fd7-8215-853b0dc8ff41"], + +Cell[BoxData[ + RowBox[{"lin", "=", + RowBox[{"Normal", "[", + RowBox[{"Series", "[", + RowBox[{ + RowBox[{"Sin", "[", "x", "]"}], ",", + RowBox[{"{", + RowBox[{"x", ",", + RowBox[{"1", "/", "2"}], ",", "1"}], "}"}]}], "]"}], "]"}]}]], "Input",\ + + CellChangeTimes->{ + 3.513956604309889*^9, {3.51395663986055*^9, 3.513956662387927*^9}, { + 3.51395698248169*^9, 3.513956983793758*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"433ed097-393b-4a78-82fb-2e9f8e872eba"], + +Cell[TextData[{ + "Quadratic approximation (drops ", + Cell[BoxData[ + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}], "i"]], + CellChangeTimes->{3.513956480106298*^9},ExpressionUUID-> + "a9629aca-7ff9-49d4-846e-59472a5c8a71"], + " for i > 2):" +}], "Text", + CellChangeTimes->{{3.5139565789357862`*^9, 3.5139566583618107`*^9}, { + 3.51395694691525*^9, 3.51395696674475*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"68e80445-bbfd-4fe0-bcfe-010f2e8d0316"], + +Cell[BoxData[ + RowBox[{"quad", "=", + RowBox[{"Normal", "[", + RowBox[{"Series", "[", + RowBox[{ + RowBox[{"Sin", "[", "x", "]"}], ",", + RowBox[{"{", + RowBox[{"x", ",", + RowBox[{"1", "/", "2"}], ",", "2"}], "}"}]}], "]"}], "]"}]}]], "Input",\ + + CellChangeTimes->{ + 3.513956604309889*^9, {3.51395663986055*^9, 3.513956662387927*^9}, { + 3.513956967929291*^9, 3.513956980025131*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"6a30f12f-4807-413c-8a7e-9071f49c1fb8"], + +Cell[BoxData[ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"Sin", "[", "x", "]"}], ",", "const", ",", "lin", ",", " ", + "quad"}], "}"}], ",", + RowBox[{"{", + RowBox[{"x", ",", "0", ",", "Pi"}], "}"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{"Automatic", ",", + RowBox[{"{", + RowBox[{"0", ",", "1"}], "}"}]}], "}"}]}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Automatic", ",", + RowBox[{"Dashing", "[", "0.1", "]"}], ",", + RowBox[{"Dashing", "[", "0.04", "]"}], ",", + RowBox[{"Dashing", "[", "0.01", "]"}]}], "}"}]}]}], "]"}]], "Input", + CellChangeTimes->{{3.513955887387858*^9, 3.513955998091051*^9}, { + 3.5139569938743477`*^9, 3.5139571060317707`*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"61e5de36-0817-4c9b-8efb-40f3aff693e8"], + +Cell["\<\ +In a local stability analysis, we assume that we are near an equilibrium, and \ +use the Taylor series to approximate the recursion or differential equation, \ +f[n], to linear order:\ +\>", "Text", + CellChangeTimes->{{3.5139571281952057`*^9, 3.5139571519990273`*^9}, { + 3.514116962346078*^9, 3.5141170073176403`*^9}, {3.514117051831397*^9, + 3.514117105747826*^9}},ExpressionUUID->"0afcec9b-a710-45ce-8054-\ +3cc0dad38e69"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Normal", "[", + RowBox[{"Series", "[", + RowBox[{ + RowBox[{"f", "[", + RowBox[{"n", "[", "t", "]"}], "]"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], ",", + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm], " ", ",", "1"}], "}"}]}], "]"}], "]"}]], "Input", + CellChangeTimes->{ + 3.514117055166052*^9, {3.5141171281161003`*^9, + 3.5141171328914623`*^9}},ExpressionUUID->"e3459fe3-0a4c-4ca4-84ed-\ +8c02815a121b"], + +Cell[BoxData[ + RowBox[{ + RowBox[{"f", "[", + OverscriptBox["n", "^"], "]"}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]}]], "Output", + CellChangeTimes->{ + 3.619898944642654*^9},ExpressionUUID->"60bf7265-f2af-4704-bce7-\ +a963048511e2"] +}, Open ]], + +Cell[TextData[{ + "Describing the recursion equation as a function (f), where ", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "=", + RowBox[{"f", "[", + RowBox[{"n", "[", "t", "]"}], "]"}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"ff0cb3e8-fbd3-4b87-8381-5004422a92aa"], + ", the Taylor series tells us that:\n\n\t", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "\[TildeTilde]", + RowBox[{ + RowBox[{"f", "[", + OverscriptBox["n", "^"], "]"}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"4d8b9520-9134-4a6d-bc2c-a61c24cd8572"], + "\t(note that ", + Cell[BoxData[ + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"ce442ac5-3c4e-4605-a5c3-5a28592cf5b1"], + " is the derivative of f with respect to n, evaluated at ", + Cell[BoxData[ + OverscriptBox["n", "^"]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"2ce553e4-f5bf-4644-8544-d444a3e3b110"], + ": ", + Cell[BoxData[ + SubscriptBox[ + RowBox[{"(", + FractionBox["df", "dn"], ")"}], + RowBox[{"n", "=", + OverscriptBox["n", "^"]}]]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"803a24a3-18a8-4398-980c-20c20ad1a114"], + ")\n\t", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "\[TildeTilde]", + RowBox[{ + OverscriptBox["n", "^"], " ", "+", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"e84b37d0-a689-4a19-bdcd-040ed049ceda"], + "\t(", + Cell[BoxData[ + RowBox[{ + RowBox[{"f", "[", + OverscriptBox["n", "^"], "]"}], "=", + OverscriptBox["n", "^"]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"36e0f78a-e5ee-4d5c-9d6d-b4f19cb66bbe"], + " because the recursion started at an equilibrium returns the equilibrium)\n\ +\t", + Cell[BoxData[ + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], "\[TildeTilde]", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"f80667d1-f425-48a5-ba47-ec2a3484bf88"], + "\t(moving ", + Cell[BoxData[ + OverscriptBox["n", "^"]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"eeae4a96-4123-40a5-8d67-77cae777a078"], + " to the left)\n\nso the distance to the equilibrium ", + Cell[BoxData[ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"3a31b8d8-cafc-4b9d-8ef6-09185ecec95a"], + " changes by a factor ", + Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"a8e42ad5-1bed-494d-b457-1a778e9cfc43"], + " each generation." +}], "Text", + CellChangeTimes->{{3.514117113606474*^9, 3.514117142561469*^9}, { + 3.514117477536956*^9, 3.514117590046109*^9}, {3.5141176961194553`*^9, + 3.5141177246657267`*^9}, {3.514117780492716*^9, 3.5141177900252123`*^9}, { + 3.563585746817067*^9, 3.563585775387279*^9}, {3.563585855165455*^9, + 3.563585922937891*^9}, {3.563585993990931*^9, 3.5635860062314653`*^9}, { + 3.5635860429884644`*^9, 3.56358607363433*^9}, {3.563586136139804*^9, + 3.5635861420353737`*^9}, {3.563586277538406*^9, + 3.563586380345704*^9}},ExpressionUUID->"ac395172-fae0-4583-be5e-\ +5a25165c801c"], + +Cell[TextData[{ + "Describing the differential equation as a function (f), where ", + Cell[BoxData[ + RowBox[{ + FractionBox["dn", "dt"], "=", + RowBox[{"f", "[", + RowBox[{"n", "[", "t", "]"}], "]"}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"ab1d4246-035b-415a-9cc5-1f74762f6ef5"], + ", the Taylor series tells us that:\n\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dn", "dt"], "\[TildeTilde]", + RowBox[{ + RowBox[{"f", "[", + OverscriptBox["n", "^"], "]"}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"95c45f33-0993-4411-b1e6-f9339d049896"], + "\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dn", "dt"], "\[TildeTilde]", + RowBox[{"0", " ", "+", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"7e7c061d-c0d2-4c88-8562-4d746274d4b4"], + "\t\t(", + Cell[BoxData[ + RowBox[{"f", "[", + OverscriptBox["n", "^"], "]"}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"11813740-2855-4a52-8bc7-ca88d8e3ea7e"], + "=0 because there is no change at an equilibrium)\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox[ + RowBox[{"d", + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}]}], "dt"], "\[TildeTilde]", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"655a9979-0be5-47b2-adf4-91a08a873a9f"], + "\t\t(because ", + Cell[BoxData[ + RowBox[{ + FractionBox[ + RowBox[{"d", + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}]}], "dt"], "=", + RowBox[{ + RowBox[{ + FractionBox[ + RowBox[{"d", + RowBox[{"(", + RowBox[{"n", "[", "t", "]"}], ")"}]}], "dt"], "-", + FractionBox[ + RowBox[{"d", + RowBox[{"(", + OverscriptBox["n", "^"], ")"}]}], "dt"]}], "=", " ", + RowBox[{ + FractionBox[ + RowBox[{"d", + RowBox[{"(", + RowBox[{"n", "[", "t", "]"}], ")"}]}], "dt"], "-", "0"}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"2dba6dd1-864a-4c68-bd65-c81a4375520b"], + ")\n\nso the distance to the equilibrium changes at a rate ", + Cell[BoxData[ + RowBox[{"r", "=", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"72f021a7-8ebc-431e-b34c-70ea666a8d9c"], + "." +}], "Text", + CellChangeTimes->{{3.514117113606474*^9, 3.514117142561469*^9}, { + 3.514117477536956*^9, 3.5141176140394173`*^9}, {3.514117741485834*^9, + 3.5141177720952053`*^9}, {3.5141178064765463`*^9, + 3.5141178346782017`*^9}, {3.514117971849181*^9, 3.514117974071348*^9}, + 3.563585778522565*^9, {3.5635860769026747`*^9, 3.563586124671801*^9}, { + 3.563586176720563*^9, + 3.563586238144927*^9}},ExpressionUUID->"f5493d30-5c32-4668-b537-\ +4ab555b9164f"], + +Cell[TextData[{ + StyleBox["RECIPE: ", + FontWeight->"Bold"], + "To determine the stability of an equilibrium:\n\t* Take the derivative of \ +the recursion equation with respect to the variable, ", + Cell[BoxData[ + FractionBox["df", "dn"]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"e5c8ff69-51c4-49b7-8404-65dfc9f7cff1"], + ", and evaluate at an equilibrium ", + Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + SubscriptBox[ + RowBox[{"(", + FractionBox["df", "dn"], ")"}], + RowBox[{"n", "=", + OverscriptBox["n", "^"]}]]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"8efd9f6d-f8c5-41e6-a8bc-368b2f06536a"], + ".\n\t\t\[Rule] The equilibrium is stable only if -1<\[Lambda]<1\t\t\t\t\t\t\ +(Discrete-time model)\n\t\t\tIf 1<\[Lambda], equilibrium is unstable with \ +exponential growth away from it\n\t\t\tIf 0<\[Lambda]<1, equilibrium is \ +stable with exponential growth toward it\n\t\t\tIf -1<\[Lambda]<0, \ +equilibrium is stable with damped oscillations toward it\n\t\t\tIf \ +\[Lambda]<-1, equilibrium is unstable with growing oscillations away from it\n\ + \t* Take the derivative of the differential equation with respect to the \ +variable, ", + Cell[BoxData[ + FractionBox["df", "dn"]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"5165d5b4-38f2-4052-9f3d-f6a138d4308c"], + ", and evaluate at an equilibrium ", + Cell[BoxData[ + RowBox[{"r", "=", + SubscriptBox[ + RowBox[{"(", + FractionBox["df", "dn"], ")"}], + RowBox[{"n", "=", + OverscriptBox["n", "^"]}]]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"b656a2b2-147c-4460-88f7-9d08c8adfc01"], + ".\n\t\t\[Rule] The equilibrium is stable only if r < 0\t\t\t\t\t\t\ +(Continuous-time model)\n\t\t\tIf 0{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117377492393*^9}, { + 3.514117840393688*^9, 3.5141181925597687`*^9}, {3.514118250452888*^9, + 3.5141182831133347`*^9}, {3.514679013185034*^9, 3.514679183553279*^9}, { + 3.563586414874763*^9, 3.563586438231552*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"4bc80bb2-a72f-4697-a163-8e0568937161"], + +Cell[TextData[{ + "For example, consider the logistic model in discrete time. When will the \ +system approach ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"0d1f89c9-f80c-491b-a349-3e674d8cd6ae"], + " = 0, causing the system to go extinct?" +}], "Text", + CellChangeTimes->{{3.514118260182096*^9, 3.51411834422397*^9}, { + 3.514164209875112*^9, + 3.514164212833427*^9}},ExpressionUUID->"33b669bc-3ddf-478d-ab03-\ +953ddd50fb3b"], + +Cell[BoxData[ + RowBox[{"derivative", "=", + RowBox[{"D", "[", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}]}]}], ")"}], + RowBox[{"n", "[", "t", "]"}]}], ",", + RowBox[{"n", "[", "t", "]"}]}], "]"}]}]], "Input", + CellChangeTimes->{{3.514118347956435*^9, 3.5141183994468813`*^9}, { + 3.514118454362989*^9, 3.514118457111812*^9}, + 3.5145541519167633`*^9},ExpressionUUID->"3eaf7f3d-dcb5-48df-8b66-\ +58a38df7c9c8"], + +Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{"derivative", "/.", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", "0"}]}]}]], "Input", + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9},ExpressionUUID->"555f49fd-4f41-404c-8f7e-\ +0ece6eb96921"], + +Cell[TextData[{ + "For \[Lambda] to lie between -1 and +1, r must lie between -2 and 0. \ +[Technically, because 1+r measures the number of offspring per parent when \ +competition is weak, r cannot fall below -1 or it becomes biologically \ +meaningless.]\n\nWhen will the system approach ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"c9ae6ee1-aa3c-4183-b141-e095e9f8b896"], + " = K, causing the system to remain stably at carrying capacity?" +}], "Text", + CellChangeTimes->{{3.514118260182096*^9, 3.51411834422397*^9}, { + 3.5141184400986767`*^9, 3.5141184515365677`*^9}, {3.514164168341901*^9, + 3.514164312407412*^9}, {3.563586483359206*^9, + 3.56358648413232*^9}},ExpressionUUID->"82ccea7b-3f80-48f8-8539-\ +2ce7e112201e"], + +Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{"derivative", "/.", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", "K"}]}]}]], "Input", + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, { + 3.514118467115301*^9, + 3.51411847142483*^9}},ExpressionUUID->"c82ab463-4bbc-406e-a40d-\ +7617c120aad3"], + +Cell[TextData[{ + "This will be greater than one if:\tr<0\t\t", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"77575fe0-699d-4657-ba95-8974b839d202"], + "=K is an unstable equilibrium\nThis will be between 0 and 1 if:\t0{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"da0ef5b8-f198-4bfd-a34f-a16dbc16bb10"], + "=K is a stable equilibrium\nThis will be between -1 and 0 if:\t1{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"f2f730e0-769f-455b-a13f-54db53d5bda7"], + "=K is a stable equilibrium with damped oscillations\nThis will be less than \ +-1 if:\t\tr>2\t\t", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"836a676c-cbdf-4dbb-85ea-734723550f21"], + "=K is an unstable equilibrium with growing oscillations" +}], "Text", + CellChangeTimes->{{3.51455433531047*^9, 3.514554502230818*^9}, { + 3.514678601815401*^9, 3.514678606006456*^9}, {3.788203607042227*^9, + 3.78820360781523*^9}},ExpressionUUID->"86ee511d-1b4d-47be-9475-\ +ef5f0a51568e"], + +Cell[CellGroupData[{ + +Cell["\<\ +Question 4: What determines stability of the equilibria for the haploid model \ +of selection?\ +\>", "Subsubsection", + CellChangeTimes->{{3.51394814025489*^9, 3.513948145584239*^9}, { + 3.513948808098681*^9, 3.5139488496649723`*^9}, {3.5139491033219757`*^9, + 3.513949116352789*^9}, {3.5139539142255583`*^9, 3.513953950682358*^9}, { + 3.513954320569996*^9, 3.513954332097341*^9}, {3.51416490831287*^9, + 3.5141649260473633`*^9}},ExpressionUUID->"330b50ca-3cf0-415a-954e-\ +484180ad73fa"], + +Cell[TextData[{ + "Under what conditions is ", + Cell[BoxData[ + FormBox[ + RowBox[{ + OverscriptBox["p", "^"], "=", "0"}], TraditionalForm]],ExpressionUUID-> + "53c8cdf3-e7f3-41e4-a9bc-60898d7a1cfa"], + " stable? " +}], "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.5139475325082417`*^9, 3.51394758040838*^9}, {3.5139476417549477`*^9, + 3.513947714905636*^9}, {3.513947913524728*^9, 3.513947982531314*^9}, { + 3.513948017290382*^9, 3.513948113203456*^9}, {3.51394894565186*^9, + 3.513949092099876*^9}, {3.513953965380247*^9, 3.513954016760906*^9}, { + 3.513954339220845*^9, 3.513954345520956*^9}, {3.513954414894065*^9, + 3.513954469204207*^9}, {3.514164930898707*^9, 3.5141650047514763`*^9}, { + 3.514515996708687*^9, + 3.514515998201612*^9}},ExpressionUUID->"4ea8db2b-1166-4031-ad39-\ +755caeff97e5"], + +Cell[TextData[{ + "Under what conditions is ", + Cell[BoxData[ + FormBox[ + RowBox[{ + OverscriptBox["p", "^"], "=", "1"}], TraditionalForm]],ExpressionUUID-> + "5937e8b0-b59a-4daa-bd09-54c8418c56c2"], + " stable? " +}], "Text", + CellChangeTimes->{ + 3.514165000145801*^9},ExpressionUUID->"5351055e-7f66-4f90-a522-\ +216f6edfc8aa"], + +Cell[TextData[{ + "You can use either the discrete-time or the continuous-time model:\n\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + RowBox[{"p", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"2f780483-d2a8-4fcf-b587-f3c9a18c9367"], + "\t\t\t\t\tDiscrete-time model\n\t\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dp", "dt"], "=", + RowBox[{ + RowBox[{ + SuperscriptBox["p", "\[Prime]", + MultilineFunction->None], "[", "t", "]"}], "=", + RowBox[{"s", " ", + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"d5ad9e02-1cb2-49ce-a907-406f14fb962b"], + "\t\t\t\t\tContinuous-time model\n\nNote that, in the discrete-time model, \ +the fitness of ", + StyleBox["A", + FontSlant->"Italic"], + " individuals is 1+s times greater than the fitness of ", + StyleBox["a", + FontSlant->"Italic"], + " individuals, where 1+s must be positive (fitness can't be negative)." +}], "Text", + CellChangeTimes->{{3.5141650094602737`*^9, + 3.514165129390822*^9}},ExpressionUUID->"8f70b6b3-c98e-43e0-a271-\ +a77ebacaa169"] +}, Open ]] +}, Closed]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Part 3: Beyond equilibria", "Section", + CellChangeTimes->{{3.5141651627789507`*^9, 3.514165208361671*^9}, + 3.514421631908485*^9},ExpressionUUID->"0669503b-97b4-42d3-9f43-\ +e5d90bd63cb6"], + +Cell[CellGroupData[{ + +Cell["General solutions", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.51395448884634*^9, 3.513954489788062*^9}, {3.514421636657851*^9, + 3.5144216396486893`*^9}},ExpressionUUID->"337c5123-44ce-4d0f-aa70-\ +7a1eef246c34"], + +Cell["\<\ +Some models can be solved generally, allowing us to predict the future state \ +at any time in the future and how this depends on the parameters.\ +\>", "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.513954558138726*^9, + 3.513954567740512*^9}, {3.513954646641127*^9, 3.513954959224346*^9}, { + 3.51395503435863*^9, 3.513955036549271*^9}, {3.513955808112068*^9, + 3.513955827145928*^9}, {3.5139562760990334`*^9, 3.513956403467185*^9}, { + 3.5139565012215347`*^9, 3.513956531165784*^9}, 3.513956573839028*^9, { + 3.513956783731927*^9, 3.5139568012276773`*^9}, {3.514116820097149*^9, + 3.5141168314840097`*^9}, {3.514116935475194*^9, 3.5141169358821573`*^9}, { + 3.5141174296927032`*^9, 3.514117449201955*^9}, {3.514421641290387*^9, + 3.514421687132519*^9}},ExpressionUUID->"e4d5ca47-3b2d-43ae-9d2d-\ +041527f387b4"], + +Cell[TextData[{ + StyleBox["DEFINITION: ", + FontWeight->"Bold"], + " A ", + StyleBox["general solution", + FontColor->RGBColor[1, 0, 0]], + " describes the state of a system at any future point in time." +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117377492393*^9}, { + 3.5141174250611267`*^9, 3.5141174260424957`*^9}, {3.514421694846284*^9, + 3.514421705133667*^9}, {3.514422248108547*^9, 3.51442226455268*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"c95aa361-aabd-4f79-b626-7187ed035d57"], + +Cell["\<\ +There are many methods for finding general solutions (see Chapters 6 & 9), \ +including iterating recursions to deduce a general rule and using recipes to \ +solve differential equations (e.g., separation of variables).\ +\>", "Text", + CellChangeTimes->{{3.514422868946821*^9, 3.514422878860903*^9}, { + 3.514423189942401*^9, + 3.514423305497418*^9}},ExpressionUUID->"e50b458d-661c-4a93-875f-\ +18ce10de9d6c"], + +Cell[TextData[{ + StyleBox["Mathematica", + FontSlant->"Italic"], + " makes it easy to find general solutions for many of the simpler models." +}], "Text", + CellChangeTimes->{{3.514422268916256*^9, 3.514422287097013*^9}, { + 3.51442332643711*^9, + 3.514423377884426*^9}},ExpressionUUID->"e1c11abc-3f72-42e1-a159-\ +64edbfe8ab87"], + +Cell["Recursion equations:", "Text", + CellChangeTimes->{{3.514422302039283*^9, + 3.514422305265853*^9}},ExpressionUUID->"3f9285ad-c731-449c-ad3a-\ +79a5039144d9"], + +Cell[BoxData[ + RowBox[{"RSolve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "\[Equal]", " ", + RowBox[{"R", "*", + RowBox[{"n", "[", "t", "]"}]}]}], ",", + RowBox[{ + RowBox[{"n", "[", "0", "]"}], "\[Equal]", "n0"}]}], "}"}], ",", + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}]], "Input", + CellChangeTimes->{{3.514422306626211*^9, + 3.514422346637411*^9}},ExpressionUUID->"6ef85025-a1c5-4378-904b-\ +9fb0b330e6d8"], + +Cell[TextData[{ + "NOTE: Again, we use == instead of = here because we don't want to set ", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], " "}]], + CellChangeTimes->{{3.5139532622009068`*^9, 3.513953273073205*^9}}, + ExpressionUUID->"b44786c3-3c1c-438e-8b92-df0625849c37"], + "equal to the right-hand side, we want TO TEST when the left and right will \ +be equal." +}], "Text", + CellChangeTimes->{{3.514423032910853*^9, + 3.514423041749639*^9}},ExpressionUUID->"25c38607-86ed-4de2-b571-\ +4a4196e7943b"], + +Cell[BoxData[ + RowBox[{"RSolve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"p", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "==", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]]}], ",", + RowBox[{ + RowBox[{"p", "[", "0", "]"}], "\[Equal]", "p0"}]}], "}"}], ",", + RowBox[{"p", "[", "t", "]"}], ",", "t"}], "]"}]], "Input",ExpressionUUID->\ +"2062c569-f473-44ed-8600-946f8e708cbf"], + +Cell["Differential equations:", "Text", + CellChangeTimes->{{3.514422453198406*^9, 3.514422456164042*^9}, { + 3.514422577047386*^9, + 3.514422579516485*^9}},ExpressionUUID->"fdbd9a62-d5eb-4673-80fb-\ +043dd1bc94bd"], + +Cell[BoxData[ + RowBox[{"DSolve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"D", "[", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}], " ", "\[Equal]", " ", + RowBox[{"R", "*", + RowBox[{"n", "[", "t", "]"}]}]}], ",", + RowBox[{ + RowBox[{"n", "[", "0", "]"}], "\[Equal]", "n0"}]}], "}"}], ",", + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}]], "Input", + CellChangeTimes->{{3.514422306626211*^9, 3.514422346637411*^9}, { + 3.51442258600113*^9, 3.514422593641465*^9}, {3.5144228115485783`*^9, + 3.5144228119806643`*^9}},ExpressionUUID->"8464d527-ba54-4ca9-acec-\ +a015cab710a5"], + +Cell[BoxData[ + RowBox[{"DSolve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"D", "[", + RowBox[{ + RowBox[{"p", "[", "t", "]"}], ",", "t"}], "]"}], " ", "==", + RowBox[{"s", " ", + RowBox[{"p", "[", "t", "]"}], + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]}], ",", + RowBox[{ + RowBox[{"p", "[", "0", "]"}], "\[Equal]", "p0"}]}], "}"}], ",", + RowBox[{"p", "[", "t", "]"}], ",", "t"}], "]"}]], "Input", + CellChangeTimes->{{3.514422306626211*^9, 3.5144223727675056`*^9}, { + 3.514422818087641*^9, + 3.51442283933525*^9}},ExpressionUUID->"3539e093-0107-4f13-ad69-\ +0cbffe726d68"], + +Cell["These can then be used to predict where the system will be:", "Text", + CellChangeTimes->{{3.514423057756749*^9, + 3.514423067565619*^9}},ExpressionUUID->"619da990-af6e-4153-81f1-\ +df6c4f0887cb"], + +Cell[BoxData[ + RowBox[{"Manipulate", "[", + RowBox[{ + RowBox[{"Plot", "[", + RowBox[{ + FractionBox[ + RowBox[{ + SuperscriptBox["\[ExponentialE]", + RowBox[{"s", " ", "t"}]], " ", "p0"}], + RowBox[{"1", "-", "p0", "+", + RowBox[{ + SuperscriptBox["\[ExponentialE]", + RowBox[{"s", " ", "t"}]], " ", "p0"}]}]], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{"Automatic", ",", + RowBox[{"{", + RowBox[{"0", ",", "1"}], "}"}]}], "}"}]}]}], "]"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"s", ",", "0.1"}], "}"}], ",", + RowBox[{"-", "0.2"}], ",", "0.2"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"p0", ",", "0.05"}], "}"}], ",", "0.01", ",", "0.99"}], "}"}]}], + "]"}]], "Input", + CellChangeTimes->{{3.514423073379549*^9, 3.5144230885136223`*^9}, { + 3.563586610276767*^9, + 3.563586716031848*^9}},ExpressionUUID->"c56cc435-02c8-4b5b-9ae1-\ +8722f5e39af5"], + +Cell[CellGroupData[{ + +Cell["\<\ +Question 5: Show that the logistic model in discrete time does not have a \ +solution, but the model in continuous time does and then plot this solution.\ +\>", "Subsubsection", + CellChangeTimes->{{3.51394814025489*^9, 3.513948145584239*^9}, { + 3.513948808098681*^9, 3.5139488496649723`*^9}, {3.5139491033219757`*^9, + 3.513949116352789*^9}, {3.5139539142255583`*^9, 3.513953950682358*^9}, { + 3.513954320569996*^9, 3.513954332097341*^9}, {3.51416490831287*^9, + 3.5141649260473633`*^9}, {3.5144228942244473`*^9, 3.514422927032115*^9}, { + 3.514423175354671*^9, 3.5144231788669167`*^9}, {3.563586746463619*^9, + 3.5635867508855953`*^9}},ExpressionUUID->"02653e6c-8ad0-4b5c-bd8b-\ +1cbc61076317"], + +Cell[TextData[{ + "Use: \n\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}]}]}], ")"}], + RowBox[{"n", "[", "t", "]"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"c130ba53-486c-4b0a-979f-7b357cd3bace"], + "\t\t\t\tDiscrete-time model\n\t\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dn", "dt"], "=", + RowBox[{ + RowBox[{ + SuperscriptBox["n", "\[Prime]", + MultilineFunction->None], "[", "t", "]"}], "=", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}], " ", + RowBox[{"n", "[", "t", "]"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"c58b6ab7-6bd3-498d-8e5a-74d71bf77dba"], + "\t\t\t\t\tContinuous-time model\t" +}], "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.5139475325082417`*^9, 3.51394758040838*^9}, {3.5139476417549477`*^9, + 3.513947714905636*^9}, {3.513947913524728*^9, 3.513947982531314*^9}, { + 3.513948017290382*^9, 3.513948113203456*^9}, {3.51394894565186*^9, + 3.513949092099876*^9}, {3.513953965380247*^9, 3.513954016760906*^9}, { + 3.513954339220845*^9, 3.513954345520956*^9}, {3.513954414894065*^9, + 3.513954469204207*^9}, {3.514164930898707*^9, 3.5141650047514763`*^9}, { + 3.5144229374662333`*^9, 3.514422939223877*^9}, {3.514423130160406*^9, + 3.514423131507475*^9}},ExpressionUUID->"88247085-1b12-4e56-a22e-\ +8a079f79ea2e"] +}, Open ]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Simulations", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.514421605669952*^9, + 3.51442160694818*^9}},ExpressionUUID->"2ec15f1f-4de6-4d00-b5da-\ +92d5fd79ac55"], + +Cell["\<\ +Some models, however, are too complicated to solve. Some cannot be solved \ +(e.g., the logistic in discrete time), while others may not be worth the time \ +needed to obtain a general solution when all that is needed are solutions to \ +specific cases.\ +\>", "Text", + CellChangeTimes->{{3.5144216199985*^9, 3.514421620816608*^9}, { + 3.5144233861823177`*^9, + 3.514423486185019*^9}},ExpressionUUID->"c2a98a5f-4c45-4bcd-a087-\ +e95801a9d4dd"], + +Cell[TextData[{ + StyleBox["DEFINITION: ", + FontWeight->"Bold"], + " A ", + StyleBox["simulation", + FontColor->RGBColor[1, 0, 0]], + " explores a model using specific parameter values and initial states by \ +applying the model's equations repeatedly." +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117310317294*^9}, { + 3.514423493433316*^9, 3.514423525555004*^9}, {3.514423974786891*^9, + 3.514423997472085*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"9fac8228-d0a5-4ab7-9873-8ea94ab897cd"], + +Cell[CellGroupData[{ + +Cell[BoxData[{ + RowBox[{"Clear", "[", "logistic", "]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"r_", ",", "K_", ",", "n0_", ",", "t_"}], "]"}], ":=", + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"r", ",", "K", ",", "n0", ",", "t"}], "]"}], "=", + "\[IndentingNewLine]", + RowBox[{"Block", "[", + RowBox[{ + RowBox[{"{", + RowBox[{"n", "=", + RowBox[{"logistic", "[", + RowBox[{"r", ",", "K", ",", "n0", ",", + RowBox[{"t", "-", "1"}]}], "]"}]}], "}"}], ",", + "\[IndentingNewLine]", "\t", + RowBox[{"n", "+", + RowBox[{"r", " ", "n", " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"n", "/", "K"}]}], ")"}]}]}]}], "\[IndentingNewLine]", "\t", + "]"}]}]}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"r_", ",", "K_", ",", "n0_", ",", "0"}], "]"}], "=", + "n0"}]}], "Input", + CellChangeTimes->{{3.514424045707509*^9, 3.514424061967498*^9}, { + 3.5144255050950212`*^9, 3.514425607017445*^9}, {3.514425642488206*^9, + 3.514425669408059*^9}, {3.514425734177042*^9, 3.514425737442438*^9}, { + 3.514426238427285*^9, 3.5144262538256493`*^9}, {3.514426381804556*^9, + 3.514426383523755*^9}, 3.5144264576520653`*^9, {3.5144266314259853`*^9, + 3.5144266539839983`*^9}, {3.514427148128552*^9, 3.5144271570026703`*^9}, + 3.51455764587731*^9, {3.5145577020626297`*^9, 3.5145577196429243`*^9}, { + 3.514557809731855*^9, 3.5145578387179317`*^9}, {3.514557911737157*^9, + 3.514557912918582*^9}, {3.514558160949648*^9, 3.514558190734005*^9}, { + 3.514679901094386*^9, + 3.514679905884348*^9}},ExpressionUUID->"f4fad38c-20e5-433a-ba4d-\ +f808002eb306"], + +Cell[BoxData["n0"], "Output", + CellChangeTimes->{{3.51455764780307*^9, 3.514557665850696*^9}, { + 3.514557706400259*^9, 3.514557720460586*^9}, {3.514557841048443*^9, + 3.5145578490297413`*^9}, 3.514557916292965*^9, 3.514558191558956*^9, + 3.514679906580071*^9},ExpressionUUID->"eeaf7619-9c0a-4479-84be-\ +368e230c80fe"] +}, Open ]], + +Cell["\<\ +Some notes: +\t* Block keeps a set of calculations together, defining local variables in \ +the first {}. The output will be the last entry of the Block. +\t* := sets the left to the right-hand side only after being called and \ +remembers this value. +\t* We have to set a starting point or else the system will end up in an \ +infinite loop going backwards in time.\ +\>", "Text", + CellChangeTimes->{{3.514426408190782*^9, + 3.51442655970971*^9}},ExpressionUUID->"3f2851a7-99f5-4c23-84f4-\ +f6297e5fda88"], + +Cell["We can then make a table of population sizes:", "Text", + CellChangeTimes->{{3.514426311595162*^9, + 3.514426337581416*^9}},ExpressionUUID->"8116e108-33b9-40c2-9aaf-\ +3e9c5e03bdaf"], + +Cell[BoxData[ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"1.5", ",", "100", ",", "10", ",", "t"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5144262691718893`*^9, 3.514426294228351*^9}, { + 3.5144263455531607`*^9, 3.5144263905959597`*^9}, {3.514426567695655*^9, + 3.514426611405775*^9}, {3.51442669599331*^9, 3.514426706329217*^9}, { + 3.5145581014379787`*^9, 3.514558102017756*^9}, {3.5146799155461397`*^9, + 3.514679916036666*^9}},ExpressionUUID->"13f9e422-7257-49e4-b3f8-\ +490fff188fa3"], + +Cell["and plot this list:", "Text", + CellChangeTimes->{{3.5144263221305637`*^9, 3.514426329021406*^9}, { + 3.514426565192073*^9, + 3.5144265653575697`*^9}},ExpressionUUID->"74a2b478-3314-48df-8eba-\ +aa01af87d1a4"], + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"1.5", ",", "100", ",", "10", ",", "t"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"0", ",", "100"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "140"}], "}"}]}], "}"}]}], ",", + RowBox[{"Joined", "\[Rule]", "True"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5144263013250847`*^9, 3.514426303622571*^9}, { + 3.514557739381982*^9, 3.514557772550335*^9}, {3.514557901303247*^9, + 3.5145579032214327`*^9}, {3.514557943096458*^9, 3.514557977886798*^9}, { + 3.5145580164968977`*^9, 3.5145580286244183`*^9}, {3.514558071237792*^9, + 3.514558091907551*^9}, {3.51455837347204*^9, 3.51455839902334*^9}, { + 3.514679925881418*^9, + 3.514679930922433*^9}},ExpressionUUID->"b2da604a-35ef-4465-a1c4-\ +9616701046c4"], + +Cell[TextData[{ + "For r values between 0 and 2, we see a stable equilibrium, as we would \ +expect from the local stability analysis of ", + Cell[BoxData[ + FormBox[ + RowBox[{ + OverscriptBox["n", "^"], "=", "k"}], TraditionalForm]],ExpressionUUID-> + "2cf8291b-e41a-411c-90b8-8c155c5a993f"], + ". For 2{{3.514426786255549*^9, 3.5144268854843693`*^9}, + 3.514426993070139*^9},ExpressionUUID->"dafbb20a-3ff2-4d30-bdda-\ +20bee74c7d51"], + +Cell[CellGroupData[{ + +Cell["Question 6: Simulating extinction", "Subsubsection", + CellChangeTimes->{{3.51394814025489*^9, 3.513948145584239*^9}, { + 3.513948808098681*^9, 3.5139488496649723`*^9}, {3.5139491033219757`*^9, + 3.513949116352789*^9}, {3.5139539142255583`*^9, 3.513953950682358*^9}, { + 3.513954320569996*^9, 3.513954332097341*^9}, {3.514426735708166*^9, + 3.514426752358864*^9}},ExpressionUUID->"6421db11-3ab7-4935-a814-\ +d38aa207bd45"], + +Cell["\<\ +Add an If[ ] statement to the above simulation to return zero if ever the \ +population size is predicted to be negative. + +Use this simulation to explore what happens with r = 3.01 (generate a table \ +as above, and ListPlot it).\ +\>", "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.5139475325082417`*^9, 3.51394758040838*^9}, {3.5139476417549477`*^9, + 3.513947714905636*^9}, {3.513947913524728*^9, 3.513947982531314*^9}, { + 3.513948017290382*^9, 3.513948113203456*^9}, {3.51394894565186*^9, + 3.513949092099876*^9}, {3.513953965380247*^9, 3.513954016760906*^9}, { + 3.513954339220845*^9, 3.513954345520956*^9}, {3.513954414894065*^9, + 3.513954469204207*^9}, {3.5144267563054047`*^9, 3.514426782297421*^9}, { + 3.5144269059322367`*^9, 3.514426945753895*^9}, {3.5144269968666162`*^9, + 3.514426997273953*^9}, 3.514516234152482*^9, {3.5635869214025097`*^9, + 3.563586945192173*^9}},ExpressionUUID->"fea86190-799e-449f-92dd-\ +2e6254c0a10a"] +}, Open ]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Numerical solutions", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.514421605669952*^9, 3.51442160694818*^9}, {3.514427010309041*^9, + 3.514427012729041*^9}},ExpressionUUID->"550e7194-bb09-44ca-8202-\ +7aa8509b7163"], + +Cell[TextData[{ + "Differential equations can also be solved numerically using ", + StyleBox["Mathematica", + FontSlant->"Italic"], + "'s NDSolve routines, which can work even for models that cannot be solved \ +analytically." +}], "Text", + CellChangeTimes->{{3.5144216199985*^9, 3.514421620816608*^9}, { + 3.5144233861823177`*^9, 3.514423486185019*^9}, {3.5144270172409153`*^9, + 3.514427088047944*^9}},ExpressionUUID->"d7813717-471b-4423-af8b-\ +e482c761f031"], + +Cell[BoxData[ + RowBox[{ + RowBox[{"logisticD", "[", + RowBox[{"r_", ",", "K_", ",", "n0_"}], "]"}], ":=", + RowBox[{"NDSolve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"D", "[", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}], "==", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}], " ", + RowBox[{"n", "[", "t", "]"}]}]}], ",", + RowBox[{ + RowBox[{"n", "[", "0", "]"}], "\[Equal]", "n0"}]}], "}"}], ",", + RowBox[{"n", "[", "t", "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]}]], "Input", + CellChangeTimes->{{3.51442706851635*^9, 3.51442712755998*^9}, { + 3.514427174650832*^9, + 3.5144272211635733`*^9}},ExpressionUUID->"eab8fe8a-7e93-4137-a706-\ +5c11219140cf"], + +Cell[BoxData[ + RowBox[{"logisticD", "[", + RowBox[{"0.5", ",", "100", ",", "10"}], "]"}]], "Input", + CellChangeTimes->{{3.514427227417859*^9, + 3.514427235453794*^9}},ExpressionUUID->"13b67bf0-d454-4601-b2d9-\ +df9392a2fce9"], + +Cell[TextData[{ + "Some notes: \n\t* We must use := here because we don't want the routine to \ +start calculating until we call it with specific values of the parameters.\n\t\ +* The code is very similar to DSolve, except that we must specify the time \ +frame over which we want a solution (here 0-100)\n\t* When we do call the \ +function, ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " tells us that it has represented the solution as a function, which we can \ +interrogate." +}], "Text", + CellChangeTimes->{{3.5144272409234343`*^9, 3.514427375818904*^9}, { + 3.563586990771734*^9, + 3.5635869929190807`*^9}},ExpressionUUID->"fb65784d-2258-40cf-8a96-\ +3db69f900324"], + +Cell["\<\ +We can then evaluate this function at specific values or in a plot:\ +\>", "Text", + CellChangeTimes->{{3.514427526380866*^9, + 3.514427546611237*^9}},ExpressionUUID->"25fffab2-3284-41a2-b331-\ +bf1bc51218cc"], + +Cell[BoxData[ + RowBox[{"Evaluate", "[", + RowBox[{ + RowBox[{"logisticD", "[", + RowBox[{"0.1", ",", "100", ",", "10"}], "]"}], "/.", + RowBox[{"t", "\[Rule]", "20"}]}], "]"}]], "Input", + CellChangeTimes->{{3.514427379422018*^9, 3.514427381555149*^9}, + 3.514427439152773*^9, {3.514427551423128*^9, + 3.514427555189413*^9}},ExpressionUUID->"f748301f-0f91-46f7-a32d-\ +c8a713c6db14"], + +Cell[BoxData[ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{"Evaluate", "[", + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "/.", + RowBox[{"logisticD", "[", + RowBox[{"0.1", ",", "100", ",", "10"}], "]"}]}], ")"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5144273849703627`*^9, + 3.514427432709642*^9}},ExpressionUUID->"0e0b1980-60e0-4b1f-8e1d-\ +0ac9a6353b59"] +}, Closed]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Part 4: Example of building a model from scratch", "Section", + CellChangeTimes->{{3.513954497848974*^9, 3.513954512594667*^9}, + 3.514165209759124*^9, {3.5145122512870913`*^9, + 3.514512262071327*^9}},ExpressionUUID->"dc9ee782-89de-48e5-b2b8-\ +58f448d8238b"], + +Cell[TextData[{ + StyleBox["Scenario: ", + FontWeight->"Bold"], + " Let's model the number of species on a large landmass over long periods of \ +evolutionary time, where the number of species is primarily influenced by \ +speciation and extinction events within the landmass. If extinction risk, d, \ +is constant per species but speciation rate declines from an initial value, \ +b, exponentially with the number of species already present (because of \ +competition for overlapping resources/niches), then develop a model that \ +might describe the number of species, n, on the landmass." +}], "Text", + CellChangeTimes->{{3.514512133202097*^9, 3.514512218390479*^9}, { + 3.5145122751264963`*^9, 3.514512297988493*^9}, {3.514514376589346*^9, + 3.514514458902255*^9}, {3.514514572866433*^9, 3.5145145941994133`*^9}, { + 3.514514631370022*^9, 3.514514661182852*^9}, {3.5145150056463737`*^9, + 3.514515014249876*^9}, {3.514516051417109*^9, 3.514516052808075*^9}, { + 3.5145620960392513`*^9, 3.5145621716588097`*^9}, {3.514680625208153*^9, + 3.514680626166531*^9}, {3.5635870492632713`*^9, + 3.563587049589624*^9}},ExpressionUUID->"d3fb88cc-95fa-4056-8059-\ +f58a6f713a1f"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Part 5: Extending to models with more than one variable", "Section", + CellChangeTimes->{{3.514165215616572*^9, + 3.514165236893621*^9}},ExpressionUUID->"84e5f518-7484-462b-ab6b-\ +9d8e8b20e3e7"], + +Cell["\<\ +The above models were all in one variable (e.g., the population size or the \ +allele frequency). Fortunately, the ideas are the same (but the methods more \ +cumbersome) with models involving more than one variable. As an example, \ +let's work with a model of an alternation of generations between haploids and \ +diploids. + +Alternation of generations is a life history common to many algae, in which \ +both the haploid and the diploid phases exist as independently growing and \ +reproducing organisms. + +Haploid individuals (gametophytes) produce diploid individuals by producing \ +haploid gametes that then unite. + +Diploid individuals (sporophytes) produce haploid individuals by meiosis. + +During a year, we assume that parents reproduce and then die, where: + +\ta = the number of diploid offspring produced per haploid parent +\tb = the number of haploid offspring produced per diploid parent +\t +Then, if h[t] represents the number of haploid individuals and d[t] the \ +number of diploid individuals, we can track the size of both populations over \ +time using discrete-time recursions: + +Haploids: \th[t+1] = b d[t] +Diploids:\td[t+1] = a h[t] + +We can describe analogous procedures for continuous-time models, but to keep \ +matters simple, we'll focus here only on discrete-time models\ +\>", "Text", + CellChangeTimes->{{3.514427943218479*^9, 3.514427992056077*^9}, { + 3.514430456335277*^9, 3.514430650251234*^9}, {3.514431049360495*^9, + 3.514431099211742*^9}, {3.514563936156959*^9, 3.514563982941115*^9}, { + 3.514564020204131*^9, 3.5145640221764383`*^9}, {3.563595358885549*^9, + 3.563595359703944*^9}, {3.563595417824901*^9, 3.563595418837987*^9}, { + 3.563667261172076*^9, + 3.563667264989525*^9}},ExpressionUUID->"3255a60a-d601-40f2-849b-\ +461e1e6b2c7c"], + +Cell[CellGroupData[{ + +Cell["Equilibria", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, + 3.513952890146652*^9}},ExpressionUUID->"64ce6d46-be26-41b7-8a0a-\ +bf920b092106"], + +Cell[TextData[{ + "An equilibrium is defined in the same way, as a special point at which the \ +system stays if started there. The only trick is to make sure that all of \ +the ", + StyleBox["variables", + FontColor->RGBColor[1, 0, 0]], + " remain constant." +}], "Text", + CellChangeTimes->{{3.514428019317086*^9, 3.514428101517205*^9}, { + 3.5144281484116297`*^9, 3.514428153504444*^9}, {3.514428229695262*^9, + 3.5144282331832857`*^9}, {3.563667251909068*^9, + 3.563667252892755*^9}},ExpressionUUID->"05dc1c71-fad7-4ccc-8017-\ +29ff2d1a1ac9"], + +Cell["For the model of alternating generations:", "Text", + CellChangeTimes->{{3.514428428226385*^9, 3.51442845235435*^9}, { + 3.514431111990419*^9, + 3.5144311178747377`*^9}},ExpressionUUID->"7cf0bd5a-445d-4b52-aea5-\ +e96839897d0d"], + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + FormBox[ + OverscriptBox["h", "^"], + TraditionalForm], " ", "==", + FormBox[ + RowBox[{"b", + OverscriptBox["d", "^"]}], + TraditionalForm]}], ",", + RowBox[{ + FormBox[ + OverscriptBox["d", "^"], + TraditionalForm], " ", "\[Equal]", + RowBox[{"a", + OverscriptBox["h", "^"]}]}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + OverscriptBox["h", "^"], ",", + OverscriptBox["d", "^"]}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.514428199117491*^9, 3.5144282532487717`*^9}, { + 3.514428327624214*^9, 3.514428414477846*^9}, {3.514431123543721*^9, + 3.514431166602357*^9}},ExpressionUUID->"31ae8fa9-a158-4ab8-b4b6-\ +fe691d67bf99"], + +Cell[TextData[{ + "Here we've asked ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " for all of the sets of solutions for the number of haploids and diploids \ +", + Cell[BoxData[ + RowBox[{"{", + RowBox[{ + OverscriptBox["h", "^"], ",", + OverscriptBox["d", "^"]}], "}"}]], + CellChangeTimes->{{3.514428199117491*^9, 3.5144282532487717`*^9}}, + ExpressionUUID->"4db6350a-7c69-49d9-a09e-77b3a02f7e75"], + " that cause both of these values to remain constant in the next generation. \ + The answer is that there's only one equilibrium point, with neither haploids \ +or diploids." +}], "Text", + CellChangeTimes->{{3.51442825542505*^9, 3.514428315406611*^9}, { + 3.514431180419536*^9, + 3.514431222791284*^9}},ExpressionUUID->"ae61509c-f98f-41ff-aa52-\ +75c59481b9a4"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Stability", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.514428463172866*^9, + 3.514428464250293*^9}},ExpressionUUID->"8b71d86c-41af-4763-a5f3-\ +583f374cf689"], + +Cell[TextData[{ + "To determine stability, we need to have a multi-dimensional analogue of \ +\[Lambda] that describes the factor by which the distance from the \ +equilibrium grows each generation.\n\n", + StyleBox["Idea: ", + FontWeight->"Bold"], + "We again approximate the recursions near an equilibrium point using the \ +Taylor series, but we do this for each recursion equation and each variable. \ +For example, if we have two recursion equations, f and g, describing changes \ +in two variables, n and m, we could apply the Taylor series as before and \ +rearrange the results as:\n\n\t\t", + Cell[BoxData[ + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], "=", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + SubscriptBox[ + RowBox[{"(", + FractionBox["df", "dn"], ")"}], + RowBox[{ + OverscriptBox["n", "^"], ",", + OverscriptBox["m", "^"]}]]}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"m", "[", "t", "]"}], "-", + OverscriptBox["m", "^"]}], ")"}], " ", + SubscriptBox[ + RowBox[{"(", + FractionBox["df", "dm"], ")"}], + RowBox[{ + OverscriptBox["n", "^"], ",", + OverscriptBox["m", "^"]}]]}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"8df5f0d3-99d0-487a-9e76-c4fe89ff338a"], + "\t\n\t\t", + Cell[BoxData[ + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"m", "[", + RowBox[{"t", "+", "1"}], "]"}], "-", + OverscriptBox["m", "^"]}], ")"}], "=", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + SubscriptBox[ + RowBox[{"(", + FractionBox["dg", "dn"], ")"}], + RowBox[{ + OverscriptBox["n", "^"], ",", + OverscriptBox["m", "^"]}]]}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"m", "[", "t", "]"}], "-", + OverscriptBox["m", "^"]}], ")"}], " ", + SubscriptBox[ + RowBox[{"(", + FractionBox["dg", "dm"], ")"}], + RowBox[{ + OverscriptBox["n", "^"], ",", + OverscriptBox["m", "^"]}]]}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"69c00ad8-527a-4eff-91dd-6cadf5158809"], + "\t\n \nBook-keeping is easier, however, and we can use the power of matrix \ +algebra, if we write this in matrix form:\n\n\t\tdistance to equilibrium in \ +next generation \t= ", + StyleBox["stability matrix", + FontColor->RGBColor[1, 0, 0]], + " times distance to equilibrium in previous generation\n\t\t\n\t\t\t\t", + Cell[BoxData[ + FormBox[ + RowBox[{"(", GridBox[{ + { + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "-", + OverscriptBox["n", "^"]}]}, + { + RowBox[{ + RowBox[{"m", "[", + RowBox[{"t", "+", "1"}], "]"}], "-", + OverscriptBox["m", "^"]}]} + }], ")"}], TraditionalForm]],ExpressionUUID-> + "b62dcfd9-64c9-42cb-8d9c-69f9e25e3ad2"], + " \t\t= ", + Cell[BoxData[ + FormBox[ + SubscriptBox[ + RowBox[{"(", GridBox[{ + { + FractionBox["df", "dn"], + FractionBox["df", "dm"]}, + { + FractionBox["dg", "dn"], + FractionBox["dg", "dm"]} + }], ")"}], + RowBox[{ + OverscriptBox["n", "^"], ",", + OverscriptBox["m", "^"]}]], TraditionalForm]],ExpressionUUID-> + "6e797e56-07a8-467d-ba78-f84ae71094ab"], + Cell[BoxData[ + FormBox[ + RowBox[{"(", GridBox[{ + { + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}]}, + { + RowBox[{ + RowBox[{"m", "[", "t", "]"}], "-", + OverscriptBox["m", "^"]}]} + }], ")"}], TraditionalForm]],ExpressionUUID-> + "297dbf54-a01c-4b4c-96cf-feb6d8a5daa6"], + " \n\t\t\t\t\nBut how do we tell if this matrix shrinks the distance or \ +expands the distance?" +}], "Text", + CellChangeTimes->{{3.514428471481825*^9, 3.5144286450102386`*^9}, { + 3.5144288254112473`*^9, 3.5144293727929068`*^9}, {3.5144294449727917`*^9, + 3.514429497649947*^9}, {3.514431777103921*^9, 3.514431792431275*^9}, { + 3.514564293740761*^9, + 3.514564317934805*^9}},ExpressionUUID->"d0f33504-04b3-45fc-ad86-\ +ae358e00270b"], + +Cell[TextData[{ + StyleBox["DEFINITION: ", + FontWeight->"Bold"], + "A matrix involving ", + StyleBox["d", + FontSlant->"Italic"], + " variables has ", + StyleBox["d", + FontSlant->"Italic"], + " eigenvalues that describe the factor by which the system grows along \ +different directions (called eigenvectors). The ", + StyleBox["leading eigenvalue", + FontColor->RGBColor[1, 0, 0]], + ", \[Lambda], of a matrix is the largest in magnitude of these eigenvalues, \ +and it predicts whether the matrix stretches (|\[Lambda]| > 1) or shrinks (|\ +\[Lambda]| < 1) a vector that it multiplies. If \[Lambda] is a complex \ +number, the system will cycle.\n\n", + StyleBox["CAUTION: ", + FontWeight->"Bold"], + "When calculating the stability matrix, decide on an order for the variables \ +and then take the derivative of the recursion for the first variable in the \ +first row with respect to the first variable in the first column. Keep the \ +order of the variables the same for all subsequent rows and columns." +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117377492393*^9}, { + 3.514117840393688*^9, 3.5141181925597687`*^9}, {3.514118250452888*^9, + 3.5141182831133347`*^9}, {3.514429521011125*^9, 3.514429568501519*^9}, { + 3.514429683894281*^9, 3.514429707893236*^9}, {3.514429743607738*^9, + 3.514429845831918*^9}, {3.514430368427335*^9, 3.5144303866734123`*^9}, { + 3.514432307183123*^9, 3.514432311402034*^9}, {3.51468076248174*^9, + 3.514680844022449*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"1c25a2ce-1726-4903-b230-20b8da935c20"], + +Cell["\<\ +For example, take the two recursion equations for the haploid-diploid model:\ +\>", "Text", + CellChangeTimes->{{3.514429858727319*^9, 3.514429896174037*^9}, { + 3.514431270800791*^9, + 3.51443127371848*^9}},ExpressionUUID->"7b1acad4-a948-4b4e-95c7-\ +b7c5e629ab55"], + +Cell[BoxData[{ + RowBox[{ + RowBox[{"eqnh", "=", + RowBox[{"b", " ", + RowBox[{"d", "[", "t", "]"}]}]}], ";"}], "\n", + RowBox[{ + RowBox[{"eqnd", "=", + RowBox[{"a", " ", + RowBox[{"h", "[", "t", "]"}]}]}], ";"}]}], "Input", + CellChangeTimes->{{3.514429904547501*^9, 3.51442992342336*^9}, { + 3.514431234883485*^9, 3.514431248744069*^9}, {3.514680729074066*^9, + 3.5146807309911327`*^9}},ExpressionUUID->"d978ddd8-d61c-4ab1-ab85-\ +b50367f0d5a1"], + +Cell["\<\ +The first equation gives us h[t+1], so we must take the derivatives first \ +with respect to h[t] and then d[t], and then evaluate at the equilibrium of \ +interest (here 0,0):\ +\>", "Text", + CellChangeTimes->{{3.5144312770812607`*^9, + 3.514431327404771*^9}},ExpressionUUID->"edeb5d4e-608b-4db8-b90d-\ +da46955cef3f"], + +Cell[BoxData[ + RowBox[{"matrix", "=", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"D", "[", + RowBox[{"eqnh", ",", + RowBox[{"h", "[", "t", "]"}]}], "]"}], ",", + RowBox[{"D", "[", + RowBox[{"eqnh", ",", + RowBox[{"d", "[", "t", "]"}]}], "]"}]}], "}"}], ",", + "\[IndentingNewLine]", + RowBox[{"{", + RowBox[{ + RowBox[{"D", "[", + RowBox[{"eqnd", ",", + RowBox[{"h", "[", "t", "]"}]}], "]"}], ",", + RowBox[{"D", "[", + RowBox[{"eqnd", ",", + RowBox[{"d", "[", "t", "]"}]}], "]"}]}], "}"}]}], "}"}], "/.", + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"h", "[", "t", "]"}], "\[Rule]", "0"}], ",", + RowBox[{ + RowBox[{"d", "[", "t", "]"}], "\[Rule]", "0"}]}], "}"}]}]}]], "Input", + CellChangeTimes->{{3.51442993198416*^9, 3.5144299850653954`*^9}, { + 3.5144300475033083`*^9, 3.514430056546912*^9}, {3.514431255563335*^9, + 3.5144312648468647`*^9}, {3.5144313318662977`*^9, 3.514431341037857*^9}, + 3.514564601334771*^9, 3.5145646391440372`*^9, {3.514680733307054*^9, + 3.514680739961896*^9}},ExpressionUUID->"7555bccd-74da-4d28-b19b-\ +a3a0635b49f8"], + +Cell["The eigenvalues of which are:", "Text", + CellChangeTimes->{{3.51442999874765*^9, 3.514430033710093*^9}, { + 3.514431354718349*^9, + 3.514431358603902*^9}},ExpressionUUID->"005d101d-ae26-4277-8238-\ +aa501f4ad9b7"], + +Cell[BoxData[ + RowBox[{"Eigenvalues", "[", "%", "]"}]], "Input", + CellChangeTimes->{{3.514430075822959*^9, + 3.514430078517954*^9}},ExpressionUUID->"ee32c7ed-08cc-4563-a7f6-\ +e0bc88892fdc"], + +Cell[TextData[{ + "Because a and b describe the number of offspring, these eigenvalues must be \ +positive. The magnitude of these two eigenvalues is the same, |\[Lambda]| = ", + Cell[BoxData[ + SqrtBox[ + RowBox[{"a", " ", "b"}]]], + CellChangeTimes->{3.514430079485057*^9, 3.514431346378005*^9}, + ExpressionUUID->"ed68c367-4c25-48c5-937f-0270947bce70"], + ", which tells us that the system will move away from the equilibrium at \ +{0,0} only if ", + Cell[BoxData[ + RowBox[{ + SqrtBox[ + RowBox[{"a", " ", "b"}]], ">", "1"}]], + CellChangeTimes->{3.514430079485057*^9, 3.514431346378005*^9}, + ExpressionUUID->"6e796733-413b-49cc-adbf-61db19e4c603"], + ", which implies that the product of a and b must be greater than one.\n\n\t\ +\[Rule] A haploid-diploid species can grow in size even if one phase \ +produces less than\n\ta replacement number of offspring (e.g., a < 1), as \ +long as the other phase compensates (e.g., b > 1)." +}], "Text", + CellChangeTimes->{{3.514431364358465*^9, 3.514431649578076*^9}, { + 3.5144322868208647`*^9, 3.51443229324233*^9}, {3.563667404999791*^9, + 3.563667421073494*^9}},ExpressionUUID->"ab55cf22-76ed-4d99-a9e9-\ +1d7d7272b4d9"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Simulation", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.514428463172866*^9, 3.514428464250293*^9}, {3.514432430011691*^9, + 3.514432431921852*^9}},ExpressionUUID->"fbd6ce0c-e917-4d48-9a6d-\ +c5304a73fe3c"], + +Cell["\<\ +We can use the same basic code as with the logistic model to track the size \ +of the haploid and diploid populations. The only difference is that the \ +result is now a vector {h,d}, whose first part is the number of haploids and \ +whose second part is the number of diploids.\ +\>", "Text", + CellChangeTimes->{{3.5144328332623262`*^9, + 3.514432913107875*^9}},ExpressionUUID->"9a4f93c5-3101-460b-ad32-\ +a65abf4e1270"], + +Cell[BoxData[{ + RowBox[{"Clear", "[", "hapdip", "]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a_", ",", "b_", ",", "h0_", ",", "d0_", ",", "t_"}], "]"}], ":=", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a", ",", "b", ",", "h0", ",", "d0", ",", "t"}], "]"}], "=", + "\[IndentingNewLine]", + RowBox[{"Block", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"h", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a", ",", "b", ",", "h0", ",", "d0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "1"}], "]"}]}], ",", + RowBox[{"d", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a", ",", "b", ",", "h0", ",", "d0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "2"}], "]"}]}]}], "}"}], + ",", "\[IndentingNewLine]", "\t", + RowBox[{"{", + RowBox[{ + RowBox[{"b", " ", "d"}], ",", + RowBox[{"a", " ", "h"}]}], "}"}]}], "\[IndentingNewLine]", "\t", + "]"}]}]}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a_", ",", "b_", ",", "h0_", ",", "d0_", ",", "0"}], "]"}], ":=", + RowBox[{"{", + RowBox[{"h0", ",", "d0"}], "}"}]}]}], "Input", + CellChangeTimes->{{3.514424045707509*^9, 3.514424061967498*^9}, { + 3.5144255050950212`*^9, 3.514425607017445*^9}, {3.514425642488206*^9, + 3.514425669408059*^9}, {3.514425734177042*^9, 3.514425737442438*^9}, { + 3.514426238427285*^9, 3.5144262538256493`*^9}, {3.514426381804556*^9, + 3.514426383523755*^9}, 3.5144264576520653`*^9, {3.5144266314259853`*^9, + 3.5144266539839983`*^9}, {3.514427148128552*^9, 3.5144271570026703`*^9}, { + 3.514432474189856*^9, 3.514432582465474*^9}, {3.514568006098897*^9, + 3.514568067364029*^9}, {3.514680930695098*^9, + 3.514680938603929*^9}},ExpressionUUID->"4376c14f-397e-49be-a5ef-\ +2a30667b650b"], + +Cell["\<\ +Some notes: +\t* Block keeps a set of calculations together, defining local variables in \ +the first {}. The output will be the last entry of the Block. +\t* := sets the left to the right-hand side only after being called and \ +remembers this value. +\t* We have to set a starting point or else the system will end up in an \ +infinite loop going backwards in time.\ +\>", "Text", + CellChangeTimes->{{3.514426408190782*^9, 3.51442655970971*^9}, { + 3.5145648346061983`*^9, + 3.514564835211282*^9}},ExpressionUUID->"5a823be0-002e-49b0-80b3-\ +aaf10e8e6bd4"], + +Cell["\<\ +We can then make a table of population sizes for {haploids, diploids}:\ +\>", "Text", + CellChangeTimes->{{3.514426311595162*^9, 3.514426337581416*^9}, { + 3.5144326128151073`*^9, + 3.514432625364406*^9}},ExpressionUUID->"848b6314-fa5e-411f-b64d-\ +fb7e801a9d84"], + +Cell[BoxData[ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"0.7", ",", "1.5", ",", "10", ",", "10", ",", "t"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5144262691718893`*^9, 3.514426294228351*^9}, { + 3.5144263455531607`*^9, 3.5144263905959597`*^9}, {3.514426567695655*^9, + 3.514426611405775*^9}, {3.51442669599331*^9, 3.514426706329217*^9}, { + 3.514432589298902*^9, + 3.514432602070593*^9}},ExpressionUUID->"bb67a767-5c35-407b-882b-\ +fc54952d877b"], + +Cell["or plotting haploids in red and diploids in blue:", "Text", + CellChangeTimes->{{3.5144263221305637`*^9, 3.514426329021406*^9}, { + 3.514426565192073*^9, 3.5144265653575697`*^9}, {3.514432634174358*^9, + 3.514432637243886*^9}, {3.5144327125256863`*^9, + 3.514432718011566*^9}},ExpressionUUID->"4d483adb-b69d-4591-9965-\ +1c4755d61d49"], + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"0.7", ",", "1.5", ",", "10", ",", "10", ",", "t"}], "]"}], + ",", "1"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}], ",", + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"0.7", ",", "1.5", ",", "10", ",", "10", ",", "t"}], "]"}], + ",", "2"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]}], "}"}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Red", ",", "Blue"}], "}"}]}]}], "]"}]], "Input", + CellChangeTimes->{{3.514432638805904*^9, 3.514432693910797*^9}, { + 3.514564949004417*^9, 3.514564951467107*^9}, {3.514568088301124*^9, + 3.514568089819323*^9}},ExpressionUUID->"0805dd71-581a-4fa0-9d3c-\ +a4b380906361"], + +Cell["\<\ +Notice that in this case the diploids have higher reproductive capacity (1.5 \ +offspring on average), yet it is the haploid population size that grows to a \ +larger size. This is, of course, because diploids beget haploids.\ +\>", "Text", + CellChangeTimes->{{3.514432739753072*^9, + 3.5144328205024443`*^9}},ExpressionUUID->"aa4a36b5-8cd6-4256-afbb-\ +41ac3660e985"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["A case with complex eigenvalues [EXTRA]", "Subsection", + CellChangeTimes->{{3.514165215616572*^9, 3.514165236893621*^9}, { + 3.514430683797038*^9, 3.514430689690156*^9}, {3.514512244518821*^9, + 3.5145122466138*^9}},ExpressionUUID->"33d2b3f2-90ba-4224-960e-e45570482f97"], + +Cell["\<\ +Some systems cycle over time. As an example, let's consider the classic \ +predator-prey model. + +Let H[t] represent the numbers of prey and P[t] represent the numbers of \ +predators. The prey are assumed to grow exponentially, but they are +captured by predators at a rate that depends on both the availability of prey \ +and predators. + +The discrete-time recursions are thus: + +Prey: \t\tH[t+1] = H[t] + r H[t] - b H[t] P[t] +Predator:\tP[t+1] = P[t] + c H[t] P[t] - d P[t] + +which uses the following parameters: +\tthe growth rate of the prey in the absence of the predator (r), +\tthe capture rate at which predators contact and kill prey (b), +\tthe rate at which eaten prey are turned into predator babies (c), +\tand the death rate of predators (d).\ +\>", "Text", + CellChangeTimes->{{3.514427943218479*^9, 3.514427992056077*^9}, { + 3.51443070318458*^9, + 3.5144308123841467`*^9}},ExpressionUUID->"2a7613bd-4dad-4d29-b697-\ +779d3d401a67"], + +Cell[TextData[{ + StyleBox["Question 7: ", + FontWeight->"Bold"], + " What are the equilibria of this model?" +}], "Text", + CellChangeTimes->{{3.514428019317086*^9, 3.514428101517205*^9}, { + 3.5144281484116297`*^9, 3.514428153504444*^9}, {3.514428229695262*^9, + 3.5144282331832857`*^9}, {3.514430772647252*^9, 3.51443080603729*^9}, { + 3.5145438472464542`*^9, + 3.514543899252392*^9}},ExpressionUUID->"2c21241a-b644-4e60-93ed-\ +6638973eecb8"], + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"{", "...", "}"}], ",", + RowBox[{"{", + RowBox[{ + OverscriptBox["H", "^"], ",", + OverscriptBox["P", "^"]}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.514428199117491*^9, 3.5144282532487717`*^9}, { + 3.514428327624214*^9, 3.514428414477846*^9}, {3.514543860228962*^9, + 3.514543864221054*^9}},ExpressionUUID->"58f5a378-3fc3-41fd-ada2-\ +65ce5f9a137c"], + +Cell[TextData[{ + "Here we've asked ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " for all of the sets of solutions for the number of prey and predators ", + Cell[BoxData[ + RowBox[{"{", + FormBox[ + RowBox[{ + RowBox[{ + OverscriptBox["H", "^"], ",", + OverscriptBox["P", "^"]}], "}"}], + TraditionalForm]}]], + CellChangeTimes->{{3.514428199117491*^9, 3.5144282532487717`*^9}}, + ExpressionUUID->"4c20f704-1f22-4e68-9fd2-84de073021be"], + "that cause both of these values to remain constant in the next generation." +}], "Text", + CellChangeTimes->{{3.51442825542505*^9, + 3.514428315406611*^9}},ExpressionUUID->"3d06e8cc-9891-4c64-8fb9-\ +42b67f8fbb91"], + +Cell[TextData[{ + StyleBox["Question 8: ", + FontWeight->"Bold"], + " Under what conditions is the equilibrium with both species present \ +stable?" +}], "Text", + CellChangeTimes->{{3.514429858727319*^9, 3.514429896174037*^9}, { + 3.514431755945674*^9, 3.514431757791016*^9}, {3.514543907832456*^9, + 3.514543935353704*^9}},ExpressionUUID->"7b2cdff2-2182-48cf-ac02-\ +a9494939fef8"], + +Cell[BoxData[{ + RowBox[{ + RowBox[{"eqn1", "=", + RowBox[{ + RowBox[{"H", "[", "t", "]"}], " ", "+", " ", + RowBox[{"r", " ", + RowBox[{"H", "[", "t", "]"}]}], " ", "-", " ", + RowBox[{"b", " ", + RowBox[{"H", "[", "t", "]"}], " ", + RowBox[{"P", "[", "t", "]"}]}]}]}], ";"}], "\n", + RowBox[{ + RowBox[{"eqn2", " ", "=", " ", + RowBox[{ + RowBox[{"P", "[", "t", "]"}], " ", "+", " ", + RowBox[{"c", " ", + RowBox[{"H", "[", "t", "]"}], " ", + RowBox[{"P", "[", "t", "]"}]}], " ", "-", " ", + RowBox[{"d", " ", + RowBox[{"P", "[", "t", "]"}]}]}]}], ";"}]}], "Input", + CellChangeTimes->{{3.514429904547501*^9, + 3.51442992342336*^9}},ExpressionUUID->"1bcd7ff8-9005-464d-9233-\ +a6e89a5cc9bb"], + +Cell[BoxData[ + RowBox[{"matrix", "=", + RowBox[{"{", "...", "}"}]}]], "Input", + CellChangeTimes->{{3.51442993198416*^9, 3.5144299850653954`*^9}, { + 3.5144300475033083`*^9, 3.514430056546912*^9}, {3.514543942210382*^9, + 3.514543942601877*^9}},ExpressionUUID->"a8d57928-cf54-4d9b-a289-\ +e43c89d34f2a"], + +Cell["\<\ +Let's consider the stability of the equilibrium with both prey and predators \ +present:\ +\>", "Text", + CellChangeTimes->{{3.51442999874765*^9, + 3.514430033710093*^9}},ExpressionUUID->"78e6f21a-1272-441d-b6d9-\ +18820710c4dd"], + +Cell[BoxData[ + RowBox[{"matrix", "/.", + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"H", "[", "t", "]"}], "\[Rule]", "..."}], ",", + RowBox[{ + RowBox[{"P", "[", "t", "]"}], "\[Rule]", "..."}]}], "}"}]}]], "Input", + CellChangeTimes->{{3.514430040650399*^9, 3.514430069985098*^9}, { + 3.514543953592757*^9, + 3.514543956220929*^9}},ExpressionUUID->"7460d9a6-b319-466f-9aac-\ +ba1bec99991f"], + +Cell[BoxData[ + RowBox[{"Eigenvalues", "[", "%", "]"}]], "Input", + CellChangeTimes->{{3.514430075822959*^9, + 3.514430078517954*^9}},ExpressionUUID->"32be12a8-9832-413c-b38d-\ +0d0bb7662aa2"], + +Cell[TextData[{ + "The answer will involve a complex number, where ", + Cell[BoxData[ + RowBox[{"\[ImaginaryI]", "=", + SqrtBox[ + RowBox[{"-", "1"}]]}]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "d30996cd-eb5c-4c5f-9445-9740bf32f61c"], + ". The above eigenvalues can be written more simply as {", + Cell[BoxData[ + RowBox[{ + RowBox[{"1", "+", + RowBox[{"\[ImaginaryI]", + SqrtBox[ + RowBox[{"d", " ", "r"}]]}]}], ",", + RowBox[{"1", "-", + RowBox[{"\[ImaginaryI]", + SqrtBox[ + RowBox[{"d", " ", "r"}]]}]}]}]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "52605411-1e3b-4494-b574-75aed266cad1"], + "}. Note that the death rate of predators (d) and the intrinsic growth rate \ +of prey (r) can be assumed to be positive in this model, so these eigenvalues \ +are complex numbers.\n\nThe recipe for discrete-time models remains the same: \ + we find the absolute magnitude of the eigenvalue, |\[Lambda]|, and if it is \ +greater than one then the system is unstable. (The rule is slightly \ +different for continuous-time models. See Chapter 8.)" +}], "Text", + CellChangeTimes->{{3.514431883298354*^9, 3.51443192551478*^9}, { + 3.514431961236163*^9, 3.514432105822605*^9}, {3.514432189176014*^9, + 3.514432192277246*^9}, {3.514543967988736*^9, 3.5145439942440767`*^9}, { + 3.5636676028457127`*^9, + 3.563667605721634*^9}},ExpressionUUID->"4c38ab37-b9d1-4a3b-9032-\ +449d806e9a28"], + +Cell[TextData[{ + StyleBox["DEFINITION: ", + FontWeight->"Bold"], + "The absolute magnitude of a complex number is ", + Cell[BoxData[ + RowBox[{ + RowBox[{"|", "\[Lambda]", "|"}], "=", + SqrtBox[ + RowBox[{ + SuperscriptBox[ + RowBox[{"(", + RowBox[{"real", " ", "part"}], ")"}], "2"], "+", + SuperscriptBox[ + RowBox[{"(", + RowBox[{"complex", " ", "part"}], ")"}], "2"]}]]}]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "182b69e2-3c4c-44cd-8999-079ed3109aa8"], + ". " +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117377492393*^9}, { + 3.514117840393688*^9, 3.5141181925597687`*^9}, {3.514118250452888*^9, + 3.5141182831133347`*^9}, {3.514429521011125*^9, 3.514429568501519*^9}, { + 3.514429683894281*^9, 3.514429707893236*^9}, {3.514429743607738*^9, + 3.514429845831918*^9}, {3.514430368427335*^9, 3.5144303866734123`*^9}, { + 3.514432121433972*^9, 3.514432163272746*^9}, {3.563667618133458*^9, + 3.563667621578416*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"38e6e281-9372-42f3-b1ba-52d6d6897294"], + +Cell[TextData[{ + "Here, the real part is \"1\" and the complex part is the part \"", + Cell[BoxData[ + SqrtBox[ + RowBox[{"d", " ", "r"}]]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "1a76437c-2e6a-4e69-bc6e-86586c916d12"], + "\" multiplying ", + Cell[BoxData[ + RowBox[{"\[ImaginaryI]", "=", + SqrtBox[ + RowBox[{"-", "1"}]]}]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "4eb7b959-9aa6-48b6-91c4-65e1b4ff7d47"], + ". So the magnitude of both eigenvalues is ", + Cell[BoxData[ + SqrtBox[ + RowBox[{ + SuperscriptBox[ + RowBox[{"(", "1", ")"}], "2"], "+", + SuperscriptBox[ + RowBox[{"(", + SqrtBox[ + RowBox[{"d", " ", "r"}]], ")"}], "2"]}]]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "252e3f19-4272-4a1c-92bc-9c5620cda723"], + ", or just ", + Cell[BoxData[ + SqrtBox[ + RowBox[{"1", "+", + RowBox[{"d", " ", "r"}]}]]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "b390cb46-7bc9-4ec7-82be-41a78f516342"], + ", which must be a number greater than one." +}], "Text", + CellChangeTimes->{{3.514432168786694*^9, + 3.5144322771621237`*^9}},ExpressionUUID->"4b2bce83-42db-4917-bf97-\ +995cf24d5f38"], + +Cell[TextData[{ + "\t\[Rule] The predator-prey model will cycle (because \[Lambda] is \ +complex) and expand away \n\tfrom the equilibrium at ", + Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"H", "[", "t", "]"}], "\[Rule]", + FractionBox["d", "c"]}], ",", + RowBox[{ + RowBox[{"P", "[", "t", "]"}], "\[Rule]", + FractionBox["r", "b"]}]}], "}"}]], + CellChangeTimes->{{3.514430040650399*^9, 3.514430069985098*^9}}, + ExpressionUUID->"59058652-1ec8-4615-a1fe-43e8d5943efe"], + " (because ", + "|\[Lambda]| > 1)." +}], "Text", + CellChangeTimes->{{3.5144323346975193`*^9, + 3.5144324054909477`*^9}},ExpressionUUID->"c85c7daf-f387-4346-aec8-\ +290783f4dd40"], + +Cell["\<\ +We can use the same basic code again to track the prey and predator \ +population sizes.\ +\>", "Text", + CellChangeTimes->{{3.5144328332623262`*^9, 3.514432913107875*^9}, { + 3.5144329503095703`*^9, + 3.514432963834735*^9}},ExpressionUUID->"b5370c8e-934b-4f47-b0a6-\ +987bbe311cf6"], + +Cell[BoxData[{ + RowBox[{ + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "r_", ",", "b_", ",", "c_", ",", "d_", ",", "H0_", ",", "P0_", ",", + "t_"}], "]"}], ":=", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "r", ",", "b", ",", "c", ",", "d", ",", "H0", ",", "P0", ",", "t"}], + "]"}], "=", "\[IndentingNewLine]", + RowBox[{"Block", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"H", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "r", ",", "b", ",", "c", ",", "d", ",", "H0", ",", "P0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "1"}], "]"}]}], ",", + RowBox[{"P", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "r", ",", "b", ",", "c", ",", "d", ",", "H0", ",", "P0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "2"}], "]"}]}]}], "}"}], + ",", "\[IndentingNewLine]", "\t", + RowBox[{"{", + RowBox[{ + RowBox[{"H", " ", "+", " ", + RowBox[{"r", " ", "H"}], " ", "-", " ", + RowBox[{"b", " ", "H", " ", "P"}]}], ",", " ", + RowBox[{"P", "+", " ", + RowBox[{"c", " ", "H", " ", "P"}], " ", "-", " ", + RowBox[{"d", " ", "P"}]}]}], "}"}]}], "\[IndentingNewLine]", "\t", + "]"}]}]}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "r_", ",", "b_", ",", "c_", ",", "d_", ",", "H0_", ",", "P0_", ",", "0"}], + "]"}], ":=", + RowBox[{"{", + RowBox[{"H0", ",", "P0"}], "}"}]}]}], "Input", + CellChangeTimes->{{3.514424045707509*^9, 3.514424061967498*^9}, { + 3.5144255050950212`*^9, 3.514425607017445*^9}, {3.514425642488206*^9, + 3.514425669408059*^9}, {3.514425734177042*^9, 3.514425737442438*^9}, { + 3.514426238427285*^9, 3.5144262538256493`*^9}, {3.514426381804556*^9, + 3.514426383523755*^9}, 3.5144264576520653`*^9, {3.5144266314259853`*^9, + 3.5144266539839983`*^9}, {3.514427148128552*^9, 3.5144271570026703`*^9}, { + 3.514432474189856*^9, 3.514432582465474*^9}, {3.514432967303516*^9, + 3.5144330531098347`*^9}, {3.5144331118463917`*^9, + 3.5144331334910192`*^9}},ExpressionUUID->"72104b61-7a28-4e51-8858-\ +4c3084509e61"], + +Cell["\<\ +We can then make a table of population sizes for {prey, predators}:\ +\>", "Text", + CellChangeTimes->{{3.514426311595162*^9, 3.514426337581416*^9}, { + 3.5144326128151073`*^9, 3.514432625364406*^9}, {3.514433379634694*^9, + 3.514433385176149*^9}},ExpressionUUID->"01d86221-a2da-4a01-b318-\ +28481c40170c"], + +Cell[BoxData[ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "0.7", ",", "0.01", ",", "0.0001", ",", "0.1", ",", "900", ",", "70", ",", + "t"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5144262691718893`*^9, 3.514426294228351*^9}, { + 3.5144263455531607`*^9, 3.5144263905959597`*^9}, {3.514426567695655*^9, + 3.514426611405775*^9}, {3.51442669599331*^9, 3.514426706329217*^9}, { + 3.514432589298902*^9, 3.514432602070593*^9}, {3.514433055820443*^9, + 3.514433088432345*^9}, {3.514433167641354*^9, 3.5144331683913803`*^9}, { + 3.5144332023425407`*^9, 3.514433214664681*^9}, {3.514433244887226*^9, + 3.514433263310009*^9}, {3.514433304783252*^9, 3.514433328898786*^9}, + 3.514433370212604*^9, 3.5144334377781887`*^9, {3.514433469033687*^9, + 3.51443349120623*^9}},ExpressionUUID->"dd74ca75-4bee-432d-aa50-\ +a8a0aa97bd72"], + +Cell["or plotting prey in red and predators in blue:", "Text", + CellChangeTimes->{{3.5144263221305637`*^9, 3.514426329021406*^9}, { + 3.514426565192073*^9, 3.5144265653575697`*^9}, {3.514432634174358*^9, + 3.514432637243886*^9}, {3.5144327125256863`*^9, 3.514432718011566*^9}, { + 3.514433391017737*^9, + 3.514433395311802*^9}},ExpressionUUID->"f3fd1d3b-1d76-4b98-b6dd-\ +a9df4eca1559"], + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "0.7", ",", "0.01", ",", "0.0001", ",", "0.1", ",", "900", ",", + "70", ",", "t"}], "]"}], ",", "1"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}], ",", + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "0.7", ",", "0.01", ",", "0.0001", ",", "0.1", ",", "900", ",", + "70", ",", "t"}], "]"}], ",", "2"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]}], "}"}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Red", ",", "Blue"}], "}"}]}], ",", + RowBox[{"PlotRange", "\[Rule]", "All"}]}], "]"}]], "Input", + CellChangeTimes->{{3.514432638805904*^9, 3.514432693910797*^9}, { + 3.514433413578724*^9, 3.5144334239940023`*^9}, {3.514433455050741*^9, + 3.5144335158256702`*^9}},ExpressionUUID->"9c32c182-a1ad-4100-8507-\ +4e8b0001d4ac"], + +Cell["\<\ +I purposely started this near the equilibrium (1000,70), otherwise it cycles \ +out so fast that it crashes and burns very quickly. Even here, the prey go \ +extinct by the end of this 100-generation simulation. + +We can also present this graph as a phase-diagram, where the number of \ +predators (y-axis) is plotted against the number of prey (x-axis):\ +\>", "Text", + CellChangeTimes->{{3.514433545940539*^9, 3.514433606886168*^9}, { + 3.514544019091618*^9, + 3.5145440482866077`*^9}},ExpressionUUID->"6c88fee2-de29-4e39-b06b-\ +ab3bd2634ab4"], + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "0.7", ",", "0.01", ",", "0.0001", ",", "0.1", ",", "900", ",", + "70", ",", "t"}], "]"}], ",", "2"}], "]"}], ",", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "0.7", ",", "0.01", ",", "0.0001", ",", "0.1", ",", "900", ",", + "70", ",", "t"}], "]"}], ",", "1"}], "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Red", ",", "Blue"}], "}"}]}], ",", + RowBox[{"PlotRange", "\[Rule]", "All"}], ",", + RowBox[{"AxesOrigin", "\[Rule]", + RowBox[{"{", + RowBox[{"0", ",", "0"}], "}"}]}]}], "]"}]], "Input", + CellChangeTimes->{{3.514432638805904*^9, 3.514432693910797*^9}, { + 3.514433413578724*^9, 3.5144334239940023`*^9}, {3.514433455050741*^9, + 3.5144335158256702`*^9}, {3.51454405774715*^9, + 3.514544101838194*^9}},ExpressionUUID->"a7c05903-c7c8-4283-8de9-\ +88755fa788b3"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Accounting for randomness [EXTRA]", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.514428463172866*^9, 3.514428464250293*^9}, {3.514432430011691*^9, + 3.514432431921852*^9}, {3.514680913441392*^9, + 3.51468092410325*^9}},ExpressionUUID->"ea4d4e06-3e0f-406f-8bd5-\ +45d53847e4d3"], + +Cell["\<\ +In all of the above models, we've assumed that the state of the system can be \ +precisely predicted in the next time step. Such models are called \ +\"deterministic\". In natural systems, there is always a degree of \ +randomness or stochasticity to life. For example, even if the average number \ +of offspring per parent were 2.3, the actual number will be an integer \ +(0,1,2,3...). + +The offspring number might, for instance, represent a random draw of the \ +Poisson distribution with a certain mean (here 2.3):\ +\>", "Text", + CellChangeTimes->{{3.5144328332623262`*^9, 3.514432913107875*^9}, { + 3.514681088503398*^9, 3.5146811264845057`*^9}, {3.514681215089706*^9, + 3.5146813367371607`*^9}},ExpressionUUID->"c640a1df-cc74-4b4c-8c75-\ +8072b50e7988"], + +Cell[BoxData[ + RowBox[{"RandomInteger", "[", + RowBox[{"PoissonDistribution", "[", "2.3", "]"}], "]"}]], "Input", + CellChangeTimes->{{3.5145680277538223`*^9, 3.514568029616096*^9}, { + 3.5146813385711927`*^9, + 3.514681338705735*^9}},ExpressionUUID->"1885bc31-c81a-4dd8-851a-\ +3f89957a96fb"], + +Cell["\<\ +We can incorporate such randomness (called \"demographic stochasticity\") \ +into the above ecological models by having the number of offspring be drawn \ +from a Poisson:\ +\>", "Text", + CellChangeTimes->{{3.5146813454789953`*^9, + 3.514681419066923*^9}},ExpressionUUID->"7bb81acc-bce0-4590-8098-\ +3f56d9c02c65"], + +Cell[BoxData[{ + RowBox[{"Clear", "[", "hapdip", "]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a_", ",", "b_", ",", "h0_", ",", "d0_", ",", "t_"}], "]"}], ":=", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a", ",", "b", ",", "h0", ",", "d0", ",", "t"}], "]"}], "=", + "\[IndentingNewLine]", + RowBox[{"Block", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"h", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a", ",", "b", ",", "h0", ",", "d0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "1"}], "]"}]}], ",", + RowBox[{"d", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a", ",", "b", ",", "h0", ",", "d0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "2"}], "]"}]}]}], "}"}], + ",", "\[IndentingNewLine]", + RowBox[{ + RowBox[{"numhap", "=", + RowBox[{"If", "[", + RowBox[{ + RowBox[{ + RowBox[{"b", " ", "d"}], ">", "0"}], ",", + RowBox[{"RandomInteger", "[", + RowBox[{"PoissonDistribution", "[", + RowBox[{"b", " ", "d"}], "]"}], "]"}], ",", "0"}], "]"}]}], ";", + "\[IndentingNewLine]", + RowBox[{"numdip", "=", + RowBox[{"If", "[", + RowBox[{ + RowBox[{ + RowBox[{"a", " ", "h"}], " ", ">", "0"}], ",", + RowBox[{"RandomInteger", "[", + RowBox[{"PoissonDistribution", "[", + RowBox[{"a", " ", "h"}], "]"}], "]"}], ",", "0"}], "]"}]}], ";", + "\[IndentingNewLine]", + RowBox[{"{", + RowBox[{"numhap", ",", "numdip"}], "}"}]}]}], "\[IndentingNewLine]", + "\t", "]"}]}]}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a_", ",", "b_", ",", "h0_", ",", "d0_", ",", "0"}], "]"}], ":=", + RowBox[{"{", + RowBox[{"h0", ",", "d0"}], "}"}]}]}], "Input", + CellChangeTimes->{{3.514424045707509*^9, 3.514424061967498*^9}, { + 3.5144255050950212`*^9, 3.514425607017445*^9}, {3.514425642488206*^9, + 3.514425669408059*^9}, {3.514425734177042*^9, 3.514425737442438*^9}, { + 3.514426238427285*^9, 3.5144262538256493`*^9}, {3.514426381804556*^9, + 3.514426383523755*^9}, 3.5144264576520653`*^9, {3.5144266314259853`*^9, + 3.5144266539839983`*^9}, {3.514427148128552*^9, 3.5144271570026703`*^9}, { + 3.514432474189856*^9, 3.514432582465474*^9}, {3.514568006098897*^9, + 3.514568067364029*^9}, {3.514681440031329*^9, 3.5146814782402697`*^9}, { + 3.514681583195634*^9, 3.5146816027804823`*^9}, {3.514681644663149*^9, + 3.51468164542367*^9}, {3.514681685292144*^9, 3.514681695436019*^9}, { + 3.6200398345517263`*^9, 3.62003986436403*^9}, {3.6200399373824778`*^9, + 3.6200400292644787`*^9}, {3.620040496906893*^9, + 3.62004049724343*^9}},ExpressionUUID->"67767389-3ae8-4dd5-a77a-\ +483f5a0838d9"], + +Cell[TextData[{ + "Some notes: \n\t* Block keeps a set of calculations together, defining \ +local variables in the first {}. The output will be the last entry of the \ +Block.\n\t* := sets the left to the right-hand side only after being called \ +and remembers this value.\n\t* We have to set a starting point or else the \ +system will end up in an infinite loop going backwards in time.\n\t* The \ +Poisson distribution can be evaluated by ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " only if the expected number is positive. This will cause problems if the \ +population ever goes extinct (expectation is zero). The If statements says \ +to draw a random number from the Poisson only if the expected number is \ +positive. " +}], "Text", + CellChangeTimes->{{3.514426408190782*^9, 3.51442655970971*^9}, { + 3.5145648346061983`*^9, 3.514564835211282*^9}, {3.514681662192986*^9, + 3.5146818424627533`*^9}, {3.6200400373210783`*^9, + 3.6200401679226847`*^9}},ExpressionUUID->"4214924c-5edf-479c-bb85-\ +d85ed1dff2bb"], + +Cell["\<\ +We can then make a table of population sizes for {haploids, diploids}:\ +\>", "Text", + CellChangeTimes->{{3.514426311595162*^9, 3.514426337581416*^9}, { + 3.5144326128151073`*^9, + 3.514432625364406*^9}},ExpressionUUID->"d16a8b73-c5b3-40ee-88e9-\ +5d42645b7d7b"], + +Cell[BoxData[ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"0.7", ",", "1.5", ",", "10", ",", "10", ",", "t"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5144262691718893`*^9, 3.514426294228351*^9}, { + 3.5144263455531607`*^9, 3.5144263905959597`*^9}, {3.514426567695655*^9, + 3.514426611405775*^9}, {3.51442669599331*^9, 3.514426706329217*^9}, { + 3.514432589298902*^9, + 3.514432602070593*^9}},ExpressionUUID->"7f4547cb-4896-4fee-9982-\ +99aa55b18bf0"], + +Cell["or plotting haploids in red and diploids in blue:", "Text", + CellChangeTimes->{{3.5144263221305637`*^9, 3.514426329021406*^9}, { + 3.514426565192073*^9, 3.5144265653575697`*^9}, {3.514432634174358*^9, + 3.514432637243886*^9}, {3.5144327125256863`*^9, + 3.514432718011566*^9}},ExpressionUUID->"273ad33d-6ad9-40cc-bc6a-\ +9778fb60705e"], + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"0.7", ",", "1.5", ",", "10", ",", "10", ",", "t"}], "]"}], + ",", "1"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}], ",", + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"0.7", ",", "1.5", ",", "10", ",", "10", ",", "t"}], "]"}], + ",", "2"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]}], "}"}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Red", ",", "Blue"}], "}"}]}]}], "]"}]], "Input", + CellChangeTimes->{{3.514432638805904*^9, 3.514432693910797*^9}, { + 3.514564949004417*^9, 3.514564951467107*^9}, {3.514568088301124*^9, + 3.514568089819323*^9}, {3.62004035535583*^9, 3.620040374994598*^9}, { + 3.6200405058091707`*^9, + 3.620040507280802*^9}},ExpressionUUID->"031e6d69-b30e-4968-8c71-\ +3729b5db26fb"], + +Cell["\<\ +Reenter this sub-directory a few times to see how the plots change due to \ +demographic stochasticity. Occassionally, you'll see the whole population go \ +extinct, despite the fact that we expect it to grow with a = 0.7 and b = 1.5. + +To learn more about probability theory and stochastic models (both analytical \ +and simulation-based methods), read Primer 3 and Chapters 13-15.\ +\>", "Text", + CellChangeTimes->{{3.514432739753072*^9, 3.5144328205024443`*^9}, { + 3.514681860480795*^9, 3.514681877814828*^9}, {3.5146819519607058`*^9, + 3.514682015319873*^9}},ExpressionUUID->"3f02efad-548d-4196-b6c7-\ +69642da2020e"] +}, Closed]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Part 6: Another example of building a model from scratch", "Section", + CellChangeTimes->{{3.5144319422285337`*^9, 3.5144319462583027`*^9}, { + 3.514516363953442*^9, + 3.514516370630651*^9}},ExpressionUUID->"a61c7f9b-390b-4cb0-a7f5-\ +0fd05cbd2474"], + +Cell[TextData[{ + StyleBox["Scenario: ", + FontWeight->"Bold"], + "Consider two types of individuals that can help one another to raise a \ +brood (e.g., one type might be better at detecting predators and the other \ +type at collecting food). Assume that neither of the two types would be able \ +to grow on their own, with the number of offspring per parent, 1-r1 and 1-r2, \ +respectively, being less than one. Through cooperation, however, the per \ +capita growth of each type rises linearly with the number of the other type, \ +with slopes \[Rho]1 and \[Rho]2." +}], "Text", + CellChangeTimes->{{3.514512947327882*^9, 3.51451300566192*^9}, { + 3.5145130395300694`*^9, 3.514513149874734*^9}, {3.514513189390361*^9, + 3.514513203812648*^9}, {3.514513251193619*^9, 3.514513366083787*^9}, { + 3.514516385741205*^9, 3.514516386187703*^9}, {3.514565331869029*^9, + 3.514565449264834*^9}, {3.514688780875373*^9, 3.5146887811607933`*^9}, { + 3.5636679304486732`*^9, + 3.563667937136087*^9}},ExpressionUUID->"1aef1eb4-bbf7-4985-820b-\ +bcd2d0b878eb"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell[TextData[{ + "Appendix: Quick reference to ", + StyleBox["Mathematica", + FontSlant->"Italic"] +}], "Section", + Evaluatable->False, + CellChangeTimes->{{3.513949886366438*^9, 3.513949888828957*^9}}, + AspectRatioFixed-> + True,ExpressionUUID->"6ecd5346-96b4-40b0-b023-33a4ea0ae1ff"], + +Cell[CellGroupData[{ + +Cell["Getting started", "Subsection", + Evaluatable->False, + AspectRatioFixed-> + True,ExpressionUUID->"b0e57c80-4368-4d82-a768-047cb9b25fe8"], + +Cell[TextData[{ + "Help -> Documentation Center", + StyleBox[" - Can be used to search for commands of interest\n", + FontFamily->"Times", + FontWeight->"Plain"], + "\n?Command", + StyleBox[" - gives a fairly detailed description of a command, e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + "?Plot", + StyleBox[" tells you all about this command. \n\tYou can use * as a \ +wildcard, for instance ", + FontFamily->"Times", + FontWeight->"Plain"], + "?*Plot", + StyleBox["* gives a list of all commands with Plot in their name. \n\tMore \ +help can be found in the menu under \"Help\", in the Function Navigator or \ +Documentation Center.\n\t\n", + FontFamily->"Times", + FontWeight->"Plain"], + "*", + StyleBox[" - Times command (2*3 gives 6). Spaces can also be used but be \ +careful (e.g, ", + FontFamily->"Times", + FontWeight->"Plain"], + "a=2 3", + StyleBox[" gives six\n\tbut ", + FontFamily->"Times", + FontWeight->"Plain"], + "a=23", + StyleBox[" gives twenty-three)\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "^", + StyleBox[" - Power command (2^3 gives 8)\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "n!", + StyleBox[" - factorial (3! gives 6)\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "{}", + StyleBox[" - denotes a list, e.g., {2,3,4}\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "()", + StyleBox[" - Places variables together, e.g., (1+x)/(1-x) takes 1+x over \ +1-x\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "[]", + StyleBox[" - Generally used to denote that something is a function of \ +something else\n\n%", + FontFamily->"Times", + FontWeight->"Plain"], + "#", + StyleBox[" - grabs previous output number #.\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "%", + StyleBox[" - grabs the previous line of output regardless of the number\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "%%", + StyleBox[" - grabs output two lines back. Note: naming outputs is safer \ +(see next section).\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "f /. object1 -> object2", + StyleBox[" \n - tells Mathematica to make replace object1 with \ +object2 in the function\n e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + "3*x^2 /. x -> 2*y+z", + StyleBox[" gives ", + FontFamily->"Times", + FontWeight->"Plain"], + "3*(2*y + z)^2 \n " +}], "Input", + CellChangeTimes->{{3.513949908602819*^9, 3.513949996977407*^9}, { + 3.5139501531450663`*^9, 3.513950178540937*^9}, {3.513950343469256*^9, + 3.513950345242174*^9}, 3.5140603007363853`*^9, {3.514060332457301*^9, + 3.514060344341905*^9}, {3.563121569604072*^9, 3.563121569929719*^9}, { + 3.618707495180807*^9, 3.618707565305377*^9}, {3.618707601648489*^9, + 3.618707609832266*^9}, {3.6187077244610243`*^9, 3.618707824899582*^9}, { + 3.618708522804984*^9, 3.61870852609206*^9}}, + AspectRatioFixed-> + True,ExpressionUUID->"6856d5ae-91f6-4ff2-9e5e-89c7d58c457c"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell[TextData[{ + "Avoiding conflict with ", + StyleBox["Mathematica", + FontSlant->"Italic"] +}], "Subsection", + CellChangeTimes->{{3.513950368656147*^9, 3.513950374988236*^9}, + 3.513950561334874*^9},ExpressionUUID->"f9a171cc-759c-4ccd-896c-\ +9ce8fff362c6"], + +Cell[TextData[{ + StyleBox["Mathematica", + FontSlant->"Italic"], + " tends to use capital letters for its functions, so its often a good idea \ +to use \nlower case names for your functions and variables.\n\nIf you refer \ +to previous entries using %, it can be difficult to know exactly what your \n\ +previous entry was. It is safer to assign a name to the output and then \ +refer to this name later.\n\nFor example," +}], "Text", + CellChangeTimes->{{3.513950396290183*^9, 3.513950507636909*^9}, { + 3.514081351768971*^9, + 3.514081353894698*^9}},ExpressionUUID->"0e04ef6d-1b69-497c-8440-\ +368a484f4005"], + +Cell[BoxData[ + RowBox[{"myderivative", " ", "=", " ", + RowBox[{"D", "[", + RowBox[{ + RowBox[{"a", " ", + RowBox[{"Sin", "[", + RowBox[{"b", " ", "x"}], "]"}]}], ",", " ", "x"}], "]"}]}]], "Input", + CellChangeTimes->{{3.5139505131262074`*^9, + 3.5139505527349653`*^9}},ExpressionUUID->"3e2e5008-bd35-48e9-8b13-\ +fca9dd5b0c16"], + +Cell[BoxData[ + RowBox[{ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{ + RowBox[{"myderivative", "/.", + RowBox[{"a", "\[Rule]", "1"}]}], "/.", + RowBox[{"b", "\[Rule]", "3"}]}], ",", + RowBox[{"{", + RowBox[{"x", ",", "0", ",", "10"}], "}"}]}], "]"}], + "\[IndentingNewLine]"}]], "Input", + CellChangeTimes->{{3.513950521780437*^9, 3.513950546486189*^9}, { + 3.563121571454344*^9, 3.563121571645876*^9}, {3.618707770838048*^9, + 3.618707771686625*^9}, + 3.618708422888011*^9},ExpressionUUID->"9240e55d-92bd-48eb-ad90-\ +252d36fdf332"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell[TextData[{ + "Functions and constants in ", + StyleBox["Mathematica", + FontSlant->"Italic"], + "\n(A small fraction!)" +}], "Subsection", + Evaluatable->False, + AspectRatioFixed-> + True,ExpressionUUID->"e9198c98-18d8-40a4-96bf-baa7817a18aa"], + +Cell[TextData[{ + StyleBox["Abs[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - Takes the absolute value of x\n\n", + StyleBox["E", + FontFamily->"Courier", + FontWeight->"Bold"], + " - The exponential constant 2.71838. ", + StyleBox["E^(x)", + FontFamily->"Courier", + FontWeight->"Bold"], + " can be invoked using ", + StyleBox["Exp[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + StyleBox["\n", + FontSize->12], + StyleBox["\nI", + FontFamily->"Courier", + FontWeight->"Bold"], + " - The square root of negative 1.\n\n", + StyleBox["Infinity", + FontFamily->"Courier", + FontWeight->"Bold"], + " - Self-explanatory.\n\n", + StyleBox["Log[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " -Takes the natural log of x\n\n", + StyleBox["Log[b,x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " -Takes the log of x in base b\n\n", + StyleBox["Pi", + FontFamily->"Courier", + FontWeight->"Bold"], + " - 3.14159...\n\n", + StyleBox["Sin[x], Cos[x], Tan[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - trigonometric functions", + StyleBox["\n", + FontSize->12], + StyleBox["ArcSin[x], ArcCos[x], ArcTan[x] ", + FontFamily->"Courier", + FontWeight->"Bold"], + "- inverse trigonometric functions\n\n", + StyleBox["Sqrt[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - Square root" +}], "Text", + Evaluatable->False, + CellChangeTimes->{{3.513950323503922*^9, 3.513950333260998*^9}, { + 3.563121524371439*^9, 3.563121524704859*^9}, {3.618707651880374*^9, + 3.618707668239052*^9}, {3.618707766796749*^9, 3.6187077676614428`*^9}, + 3.6187084181609707`*^9, {3.618708461384329*^9, 3.618708464911661*^9}, + 3.62004023217328*^9}, + AspectRatioFixed-> + True,ExpressionUUID->"840b08ef-f6af-43ed-96c8-3b6c7252c6e8"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell[TextData[{ + "Writing equations in ", + StyleBox["Mathematica", + FontSlant->"Italic"] +}], "Subsection", + Evaluatable->False, + AspectRatioFixed-> + True,ExpressionUUID->"4caafba8-e43f-472d-bccf-d04d35438391"], + +Cell[TextData[{ + StyleBox["x=y", "Input", + FontWeight->"Bold"], + StyleBox[" ", "Input", + FontFamily->"Times", + FontWeight->"Bold"], + StyleBox[" - Sets x to y immediately and from then on (use Clear[x] to \ +unassign x), e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["plot1=Plot[x^2,{x,0,10}]", "Input", + FontWeight->"Bold"], + StyleBox["\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["x:=y", "Input", + FontWeight->"Bold"], + StyleBox[" - Does nothing until x is called, at which point x is assigned \ +the value y\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["x==y", "Input", + FontWeight->"Bold"], + StyleBox[" ", "Input", + FontFamily->"Times", + FontWeight->"Bold"], + StyleBox[" - Tests whether x equals y BUT makes no assignment\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["f[x_]:=", "Input", + FontWeight->"Bold"], + " ", + StyleBox["- This is how you define a function (called \"f\") of x, e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["f[x_] := x^2", "Input", + FontWeight->"Bold"], + "\n\n", + StyleBox["f[x]", "Input", + FontWeight->"Bold"], + " ", + StyleBox["- This gives the function evaluated at x, e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["f[3]", "Input", + FontWeight->"Bold"], + StyleBox[" gives ", + FontFamily->"Times", + FontWeight->"Plain"], + "9", + StyleBox[" in the above example", + FontFamily->"Times", + FontWeight->"Plain"], + "\n\n", + StyleBox["f[x_,y_,...]=", "Input", + FontWeight->"Bold"], + " ", + StyleBox["- This is how you define a function of several variables", + FontFamily->"Times", + FontWeight->"Plain"] +}], "Input", + CellChangeTimes->{ + 3.513951162654813*^9, {3.563121328181324*^9, 3.563121345683249*^9}, { + 3.563121529178462*^9, 3.5631215293437777`*^9}, {3.618707875626803*^9, + 3.618707881302347*^9}, {3.620040237579296*^9, 3.620040238380657*^9}}, + AspectRatioFixed-> + True,ExpressionUUID->"2e128d7a-a53e-4e08-8f85-aa48fdd6a6e7"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["A list of helpful commands", "Subsection", + Evaluatable->False, + AspectRatioFixed-> + True,ExpressionUUID->"fd5091b3-6526-4a1c-8193-1feab5f154c4"], + +Cell[TextData[{ + StyleBox["Clear[symbol1,symbol2,...]", "Input"], + " - clears variable or function definitions, \n\te.g., ", + StyleBox["Clear[x, y, pop1]", "Input", + FontWeight->"Bold"], + "\n\n", + StyleBox["Clear[\[OpenCurlyDoubleQuote]Global`*\[CloseCurlyDoubleQuote]] ", + "Input", + FontWeight->"Bold"], + "- clears all variable or function definitions from memory\n\n", + StyleBox["Collect[eqn,{terms},Factor]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - collects parts of an equation involving \[OpenCurlyDoubleQuote]terms\ +\[CloseCurlyDoubleQuote] and \n\tfactors them separately (if only one \ +\[OpenCurlyDoubleQuote]term\[CloseCurlyDoubleQuote], the braces aren\ +\[CloseCurlyQuote]t needed)\n\te.g. Collect[", + Cell[BoxData[ + RowBox[{"a", "-", "b", "+", + RowBox[{"a", " ", "x"}], "-", + RowBox[{"2", " ", "b", " ", "x"}], "+", + RowBox[{ + SuperscriptBox["a", "2"], " ", + SuperscriptBox["x", "2"]}], "+", + RowBox[{"2", " ", "a", " ", "b", " ", + SuperscriptBox["x", "2"]}], "+", + RowBox[{ + SuperscriptBox["b", "2"], " ", + SuperscriptBox["x", "2"]}]}]], + CellChangeTimes->{{3.51395123610637*^9, 3.513951252570932*^9}}, + ExpressionUUID->"51000bef-ef6f-4054-b3cf-5283f70ad459"], + ", x, Factor]\n\n", + StyleBox["D[f,x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - takes the partial derivative of f with respect to x - e.g. D[x^2+y \ +Log[x], x]\n\n", + StyleBox["D[f, {x, n}] ", + FontFamily->"Courier", + FontWeight->"Bold"], + " - takes the nth derivative with respect to x - e.g. D[x^2+y Log[x],{x,2}]\ +\n\n", + StyleBox["DSolve[eqn, y[x],x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - solves differential equation for y as a function of x \n\t\ +(SYMBOLICALLY) e.g. DSolve[{y'[x] == k y[x], y[0]==y0, y[x],x]\n\n", + StyleBox["DSolve[eqns, {y1,y2,y3,..}, x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " same as above but for a system of eqns \n\te.g. pred-prey equations \ +DSolve[{y'[x] == k y-x, z'[x]==x+z}, {y[x],z[x]}, x]\n\n", + StyleBox["NDSolve[eqns, y, {x, xmin,xmax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - same as DSolve but seeks solution\n\tNUMERICALLY - e.g. NDSolve[{y'[x] \ +==4 y[x], y[3]==62}, y[x], {x, 0,20}]\n\n", + StyleBox["Expand[expr]", + FontFamily->"Courier", + FontWeight->"Bold"], + "- expands an expr e.g. Expand[(1+x)^2] gives 1+2x+x^2\n\n", + StyleBox["Evaluate[object]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - evaluates a symbolic object like interpolating functions\n\n", + StyleBox["Factor[polynomial]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - self explanatory - e.g. Factor[x^2 + 2 x + 1]\n\n", + StyleBox["FindRoot[eqn1==eqn2, {x, x0}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - searches for numerical root of eqn1==eqn2\n starting at x0 \ +e.g. FindRoot[Log[x] + x + Arctan[x] == 0, {x, 4}] tries to find \n \ + x that satisfies this very ugly - impossible to solve by hand equation, \ +starting at x=4.\n\n", + StyleBox["For[start,test,increment,body]", "Input", + FontWeight->"Bold"], + " - repeats procedure \[OpenCurlyDoubleQuote]body\[CloseCurlyDoubleQuote], \ +starting from \[OpenCurlyDoubleQuote]start\[CloseCurlyDoubleQuote] \n\tuntil \ +the \[OpenCurlyDoubleQuote]test\[CloseCurlyDoubleQuote] condition is met, \ +adding \[OpenCurlyDoubleQuote]increment\[CloseCurlyDoubleQuote] each time, \n\ +\te.g., ", + StyleBox["For[i=1, i\[LessEqual]10, i=i+1, Print[i]]", "Input", + FontWeight->"Bold"], + " prints out integers 1 through 10.\n\n", + StyleBox["Integrate[f,x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - finds indefinite integral of f with respect to x \n\te.g., \ +Integrate[Log[x], x]\n\n", + StyleBox["Integrate[f, {x, xmin, xmax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - computes definite integral from xmin to xmax\n\te.g., Integrate[Log[x], \ +{x, 1,6}]\n\n", + StyleBox["ListPlot[list] ", "Input", + FontWeight->"Bold"], + "- plots a list of integers, e.g., ", + StyleBox["ListPlot[{2,4,3,5,4}]", "Input", + FontWeight->"Bold"], + "\n\n", + StyleBox["ListPlot[{{x1, y1},{x2, y2},...}] ", "Input"], + "- plots a series of {x, y} values,\n\te.g., ", + StyleBox["ListPlot[{{1,2},{2,1},{5,7}}] ", "Input", + FontWeight->"Bold"], + "To join the points with a line use:", + StyleBox["\n\t ListPlot[{{1,2},{2,1},{5,7}},PlotJoined->True] ", "Input", + FontWeight->"Bold"], + "(in ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " 5)\n", + StyleBox["\t ListPlot[{{1,2},{2,1},{5,7}},Joined->True] ", "Input", + FontWeight->"Bold"], + "(in more recent versions)\n\n", + StyleBox["N[f]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - gives a numerical value for an expression - e.g. N[Pi] gives 3.14159\n\n", + StyleBox["Part[eqn,i]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - grabs the ith part of eqn, e.g., Part[3x^2+x^3,2] gives x^3\n\n", + StyleBox["Plot[f,{x,xmin,xmax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - plots f versus x on the interval [xmin,xmax] \n e.g., \ +Plot[x^2, {x,0,2}] NOTE: Plot has lots of options e.g. AxesLabel,\n \ + Grid, AxesOrigin, etc. See the manual for a complete list and usage \n \ + e.g., Plot[x^2, {x,0,2}, PlotStyle->Dashed] makes a dashed curve.\n\n", + StyleBox["Plot3D[f, {x, xmin, xmax}, {y, ymin, ymax}] ", "Input", + FontWeight->"Bold"], + "- makes a 3D plot of f\n\n", + StyleBox["Show[graphics, options]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - displays graphic objects using options e.g. \n\tShow[popplot1, \ +PlotJoined->True]\n\n", + StyleBox["Simplify[expr]", "Input", + FontWeight->"Bold"], + " - does its best to simplify an expression, expr\n\n", + StyleBox["Solve[eqns, vars]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - tries to solve one or a system equations for the vars specified \n\t\ +(SYMBOLICALLY)- e.g. Solve[{x+y ==1, x-y ==4}, {x,y}]\n\n", + StyleBox["NSolve[eqns, vars]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - does the same thing as Solve, but does it NUMERICALLY\n\t(See also \ +FindRoot)\n\n", + StyleBox["Sum[f, {i, imin, imax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - sums f from i to imax i.e. f[1] + f[2] + f[3] + ... \n (only \ +really interesting if f depends on i) - e.g. Sum[i, {i, 1,4}] gives 10.\n \ + \n", + StyleBox["Reduce[{eqns}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - can be used to determine if a statement is true or false \n\te.g., \ +Reduce[{a + b > 1, a < 0, b < 0}]\n\t\n", + StyleBox["RSolve[eqns, vars]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - solves a discrete-time equation for y as a function of x \n\t\ +(SYMBOLICALLY) e.g. RSolve[{n[t+1] == R n[t], n[0]==n0}, n[t],t]\n\t\n", + StyleBox["Table[f, {i, imin, imax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + "- makes a table in list format of the function f\n\twith i values that run \ +from imin to imax - e.g. Table[i, {i, 1,4}] gives {1,2,3,4}.\n\t" +}], "Text", + Evaluatable->False, + CellChangeTimes->{{3.513950574915991*^9, 3.513950644564106*^9}, { + 3.5139506852524443`*^9, 3.5139507449534903`*^9}, {3.513951058272286*^9, + 3.513951157431922*^9}, {3.513951258750285*^9, 3.513951289125362*^9}, { + 3.513951388122881*^9, 3.5139514539888678`*^9}, {3.563121349636468*^9, + 3.56312137989666*^9}, {3.5631215383007097`*^9, 3.5631215384589367`*^9}, { + 3.5631216133411827`*^9, 3.563121629795897*^9}, {3.618706999372814*^9, + 3.6187070072615623`*^9}, {3.618707059868635*^9, 3.618707088131692*^9}, { + 3.6187079213007107`*^9, 3.6187079237033043`*^9}, {3.618707973985024*^9, + 3.6187079869762917`*^9}, {3.618708025765148*^9, 3.618708066614579*^9}, { + 3.618708105359006*^9, 3.6187081645478563`*^9}, {3.618708214244253*^9, + 3.618708219452034*^9}, 3.61870843421904*^9, {3.6187084805441637`*^9, + 3.618708512996409*^9}, 3.618708553301162*^9, {3.618708665614304*^9, + 3.618708799566545*^9}, {3.618708829907131*^9, 3.618708878628771*^9}, { + 3.618708971988484*^9, 3.6187089725306787`*^9}, {3.618709332845521*^9, + 3.618709368817597*^9}, {3.618709565197136*^9, 3.6187095669896708`*^9}, { + 3.6187096668400307`*^9, 3.6187097296590443`*^9}, {3.618709851524448*^9, + 3.618709893664585*^9}, {3.618709931444655*^9, 3.618709948061162*^9}, { + 3.618710235087677*^9, 3.618710236246958*^9}}, + AspectRatioFixed-> + True,ExpressionUUID->"4ffac4ba-a0cd-4080-b33c-236e4bc57984"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Libraries", "Subsection", + Evaluatable->False, + AspectRatioFixed-> + True,ExpressionUUID->"f64f4fc7-d022-4801-8ec7-cfdb730dfebb"], + +Cell[TextData[{ + StyleBox["Mathematica", + FontFamily->"Times", + FontWeight->"Plain", + FontSlant->"Italic"], + StyleBox[" has some libraries or packages that it does not load \ +automatically.\nThe Documentation Center will tell you if a function needs a \ +library.\nFor example, to plot error bars on a list plot, you will need:", + FontFamily->"Times", + FontWeight->"Plain"] +}], "Text", + CellChangeTimes->{{3.563121394475396*^9, + 3.5631213999837*^9}},ExpressionUUID->"5351ad39-27a1-4e3e-aea9-6d07c59041b7"], + +Cell[BoxData[ + RowBox[{"Needs", "[", "\"\\"", "]"}]], "Input", + CellChangeTimes->{ + 3.563121385155899*^9},ExpressionUUID->"6d520d5e-3b3d-4c8c-9987-\ +a1f4c7d58fd6"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{ + RowBox[{"ErrorListPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"1", ",", "1"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.2", "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"2", ",", "2"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.1", "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"3", ",", "4"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.3", "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"4", ",", "6"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.4", "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"5", ",", "7"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.8", "]"}]}], "}"}]}], "}"}], ",", " ", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"0", ",", "6"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "8"}], "}"}]}], "}"}]}]}], "]"}], " "}]], "Input", + CellChangeTimes->{{3.513950246287406*^9, 3.513950270738648*^9}, + 3.563121389070549*^9},ExpressionUUID->"62ca4b3b-3a6f-4e92-861c-\ +b2ffe4074897"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {Hue[0.67, 0.6, 0.6], + LineBox[{{1., 1.}, {2., 2.}, {3., 4.}, {4., 6.}, {5., + 7.}}], {{LineBox[{{1., 1.2}, {1., 0.8}}], + LineBox[{Offset[{1.5, 0}, {1., 1.2}], Offset[{-1.5, 0}, {1., 1.2}]}], + LineBox[{Offset[{1.5, 0}, {1., 0.8}], Offset[{-1.5, 0}, {1., 0.8}]}]}, { + LineBox[{{2., 2.1}, {2., 1.9}}], + LineBox[{Offset[{1.5, 0}, {2., 2.1}], Offset[{-1.5, 0}, {2., 2.1}]}], + LineBox[{Offset[{1.5, 0}, {2., 1.9}], Offset[{-1.5, 0}, {2., 1.9}]}]}, { + LineBox[{{3., 4.3}, {3., 3.7}}], + LineBox[{Offset[{1.5, 0}, {3., 4.3}], Offset[{-1.5, 0}, {3., 4.3}]}], + LineBox[{Offset[{1.5, 0}, {3., 3.7}], Offset[{-1.5, 0}, {3., 3.7}]}]}, { + LineBox[{{4., 6.4}, {4., 5.6}}], + LineBox[{Offset[{1.5, 0}, {4., 6.4}], Offset[{-1.5, 0}, {4., 6.4}]}], + LineBox[{Offset[{1.5, 0}, {4., 5.6}], Offset[{-1.5, 0}, {4., 5.6}]}]}, { + LineBox[{{5., 7.8}, {5., 6.2}}], + LineBox[{Offset[{1.5, 0}, {5., 7.8}], Offset[{-1.5, 0}, {5., 7.8}]}], + LineBox[{Offset[{1.5, 0}, {5., 6.2}], Offset[{-1.5, 0}, {5., 6.2}]}]}}}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{{0, 6}, {0, 8}}, + PlotRangeClipping->True, + PlotRangePadding->{Automatic, Automatic}]], "Output", + CellChangeTimes->{{3.563121232176646*^9, + 3.563121287867106*^9}},ExpressionUUID->"435fb041-7aa4-426f-90a8-\ +d3b75b2698af"] +}, Open ]] +}, Closed]] +}, Open ]] +}, Open ]] +}, +WindowSize->{1246, 682}, +WindowMargins->{{Automatic, 0}, {Automatic, 0}}, +PrivateNotebookOptions->{"VersionedStylesheet"->{"Default.nb"[8.] -> False}}, +ShowSelection->True, +Magnification:>FEPrivate`If[ + FEPrivate`Equal[FEPrivate`$VersionNumber, 6.], 1.5, 1.5 Inherited], +FrontEndVersion->"12.1 for Mac OS X x86 (64-bit) (June 19, 2020)", +StyleDefinitions->"Default.nb", +ExpressionUUID->"e40d8725-a322-46f9-8e2b-0493c7c85cbe" +] +(* End of Notebook Content *) + +(* Internal cache information *) +(*CellTagsOutline +CellTagsIndex->{} +*) +(*CellTagsIndex +CellTagsIndex->{} +*) +(*NotebookFileOutline +Notebook[{ +Cell[CellGroupData[{ +Cell[567, 22, 508, 12, 158, "Title",ExpressionUUID->"bf3838d1-38f9-4115-ac68-fd6a09d867b9"], +Cell[1078, 36, 642, 17, 260, "Text",ExpressionUUID->"471d3ee9-dbba-4c5e-b100-311cbd91d468"], +Cell[CellGroupData[{ +Cell[1745, 57, 364, 7, 101, "Section",ExpressionUUID->"84d066d3-ebc0-421e-aa4d-b53a2c930db2"], +Cell[CellGroupData[{ +Cell[2134, 68, 166, 3, 76, "Subsection",ExpressionUUID->"745d7dae-e470-43ab-ba1e-0b8f85831fd6"], +Cell[2303, 73, 1805, 42, 382, "Text",ExpressionUUID->"bf485b3e-2c6f-400c-ab53-06b746d14258"] +}, Open ]], +Cell[CellGroupData[{ +Cell[4145, 120, 214, 4, 76, "Subsection",ExpressionUUID->"7e4e226d-5b30-4966-af1c-68299633d063"], +Cell[4362, 126, 1866, 45, 394, "Text",ExpressionUUID->"cff61acc-ee75-4f59-96c5-dae0b0ceb4e0"] +}, Open ]], +Cell[CellGroupData[{ +Cell[6265, 176, 223, 4, 76, "Subsection",ExpressionUUID->"c26cf99e-7540-4a41-a320-0c4f3a6dcf47"], +Cell[6491, 182, 2143, 63, 402, "Text",ExpressionUUID->"3b7b6503-c41a-4e20-9a83-6f25e3cfbe8b"] +}, Open ]], +Cell[CellGroupData[{ +Cell[8671, 250, 228, 7, 76, "Subsection",ExpressionUUID->"95c63cef-fb38-4dcf-9888-321aa7d31904"], +Cell[8902, 259, 249, 7, 63, "Text",ExpressionUUID->"fcedfe7d-5fc9-45a3-8197-a29be16f17da"], +Cell[9154, 268, 385, 7, 102, "Text",ExpressionUUID->"133bf198-51fd-4008-8758-ff51032495c2"], +Cell[9542, 277, 560, 17, 96, "Input",ExpressionUUID->"b5c7ed8d-60c0-4377-a2ad-e75b37ffeb73"], +Cell[10105, 296, 488, 10, 139, "Text",ExpressionUUID->"fdbf74a1-a883-4b86-9148-4e8d40ad0715"], +Cell[10596, 308, 933, 26, 156, "Input",ExpressionUUID->"1ffba96a-cf11-4216-b7a0-a137e9401287"], +Cell[11532, 336, 928, 29, 156, "Input",ExpressionUUID->"3605d36d-880a-4e26-a4a9-10a5fa3fc0c7"], +Cell[12463, 367, 237, 6, 63, "Text",ExpressionUUID->"5670437f-1e21-4a0e-a658-5fff83586f07"], +Cell[12703, 375, 1009, 31, 156, "Input",ExpressionUUID->"d8e9a96d-7418-46d3-99a8-7dc4cb1515de"], +Cell[13715, 408, 572, 12, 178, "Text",ExpressionUUID->"a1d927fc-113b-441f-82b7-e01b7f1d81eb"], +Cell[14290, 422, 439, 14, 96, "Input",ExpressionUUID->"95c08a0f-8e7d-402e-a130-9b84f90c70b1"], +Cell[14732, 438, 289, 7, 60, "Input",ExpressionUUID->"cf7c98ff-8700-4454-97ec-f12cf2371db3"], +Cell[CellGroupData[{ +Cell[15046, 449, 310, 5, 58, "Subsubsection",ExpressionUUID->"1eec161d-e632-4814-9fe6-b8661bb5d925"], +Cell[15359, 456, 1055, 23, 102, "Text",ExpressionUUID->"e0260936-e603-4b32-9684-b635c9d33231"] +}, Open ]], +Cell[CellGroupData[{ +Cell[16451, 484, 397, 6, 58, "Subsubsection",ExpressionUUID->"db38a225-790f-4cf5-a3dc-74ac97c02ad9"], +Cell[16851, 492, 1267, 29, 117, "Text",ExpressionUUID->"fdde2cf5-3d40-4a83-84f1-875a1e64f492"] +}, Open ]] +}, Open ]] +}, Closed]], +Cell[CellGroupData[{ +Cell[18179, 528, 332, 5, 78, "Section",ExpressionUUID->"c18e009c-3dae-4f4a-8cf0-a2572f70c129"], +Cell[CellGroupData[{ +Cell[18536, 537, 160, 3, 51, "Subsection",ExpressionUUID->"b043ff20-0483-4750-827a-153fee482437"], +Cell[18699, 542, 1702, 40, 1539, "Text",ExpressionUUID->"68d497e4-d5c7-4d55-aeee-2a9cd096f91e"], +Cell[20404, 584, 2075, 59, 724, "Text",ExpressionUUID->"8d7d772e-5c56-417f-9450-62a6ae2cc0a9"], +Cell[22482, 645, 697, 25, 445, "Input",ExpressionUUID->"24b4094a-be36-4137-a546-ef831b6e73ac"], +Cell[23182, 672, 426, 14, 243, "Input",ExpressionUUID->"54f620a3-189d-45ae-bc4b-0f82c9186d99"], +Cell[23611, 688, 537, 14, 378, "Text",ExpressionUUID->"1735d295-10d7-4b5e-89bf-5368211fa09d"], +Cell[24151, 704, 899, 25, 297, "Text",ExpressionUUID->"56c603b0-c515-4b59-9f2f-0873f0f987bc"], +Cell[25053, 731, 541, 19, 445, "Input",ExpressionUUID->"b5627452-f3f9-47e3-8db4-d31e757ecbeb"], +Cell[CellGroupData[{ +Cell[25619, 754, 428, 8, 216, "Subsubsection",ExpressionUUID->"f528b24c-43e5-496e-af92-4205e4487846"], +Cell[26050, 764, 2248, 61, 1354, "Text",ExpressionUUID->"66ab879c-0122-4ccd-8248-80befefb0463"] +}, Open ]] +}, Closed]], +Cell[CellGroupData[{ +Cell[28347, 831, 207, 4, 37, "Subsection",ExpressionUUID->"f0dd8c75-3e97-47c8-8eba-3d8ae0aaec88"], +Cell[28557, 837, 936, 15, 42, "Text",ExpressionUUID->"5ae67325-e62f-436a-ab79-cec5bbfa6bf2"], +Cell[29496, 854, 919, 20, 92, "Text",ExpressionUUID->"3e9805f3-ef36-490e-b855-cf728407b7cc"], +Cell[30418, 876, 1353, 27, 144, "Text",ExpressionUUID->"25e1c6a1-e8dc-4834-84b9-ac7e0b040ecb"], +Cell[31774, 905, 835, 24, 540, "Text",ExpressionUUID->"41742680-6e08-4ab6-be2e-53086ccd98eb"], +Cell[32612, 931, 691, 17, 432, "Input",ExpressionUUID->"ca40814b-154f-4bed-830f-cccb4753cfe2"], +Cell[33306, 950, 370, 8, 378, "Text",ExpressionUUID->"eb354cf0-c358-417d-a500-b53500dad939"], +Cell[33679, 960, 460, 12, 387, "Input",ExpressionUUID->"7f8f3a8e-904f-486e-9660-12ea77f934bc"], +Cell[34142, 974, 1030, 27, 819, "Text",ExpressionUUID->"e4e578da-8f49-4cd7-b4aa-a8ac0cd33a78"], +Cell[35175, 1003, 556, 15, 387, "Input",ExpressionUUID->"e12bb329-4c90-44ae-8276-770f12f46899"], +Cell[35734, 1020, 591, 16, 396, "Text",ExpressionUUID->"4348be8d-f55f-4fd7-8215-853b0dc8ff41"], +Cell[36328, 1038, 553, 15, 387, "Input",ExpressionUUID->"433ed097-393b-4a78-82fb-2e9f8e872eba"], +Cell[36884, 1055, 593, 16, 396, "Text",ExpressionUUID->"68e80445-bbfd-4fe0-bcfe-010f2e8d0316"], +Cell[37480, 1073, 555, 15, 387, "Input",ExpressionUUID->"6a30f12f-4807-413c-8a7e-9071f49c1fb8"], +Cell[38038, 1090, 937, 24, 88, "Input",ExpressionUUID->"61e5de36-0817-4c9b-8efb-40f3aff693e8"], +Cell[38978, 1116, 432, 8, 68, "Text",ExpressionUUID->"0afcec9b-a710-45ce-8054-3cc0dad38e69"], +Cell[CellGroupData[{ +Cell[39435, 1128, 499, 15, 48, "Input",ExpressionUUID->"e3459fe3-0a4c-4ca4-84ed-8c02815a121b"], +Cell[39937, 1145, 450, 15, 48, "Output",ExpressionUUID->"60bf7265-f2af-4704-bce7-a963048511e2"] +}, Open ]], +Cell[40402, 1163, 4625, 129, 284, "Text",ExpressionUUID->"ac395172-fae0-4583-be5e-5a25165c801c"], +Cell[45030, 1294, 3845, 113, 239, "Text",ExpressionUUID->"f5493d30-5c32-4668-b537-4ab555b9164f"], +Cell[48878, 1409, 2724, 56, 520, "Text",ExpressionUUID->"4bc80bb2-a72f-4697-a163-8e0568937161"], +Cell[51605, 1467, 540, 13, 68, "Text",ExpressionUUID->"33b669bc-3ddf-478d-ab03-953ddd50fb3b"], +Cell[52148, 1482, 600, 17, 66, "Input",ExpressionUUID->"3eaf7f3d-dcb5-48df-8b66-58a38df7c9c8"], +Cell[52751, 1501, 301, 7, 40, "Input",ExpressionUUID->"555f49fd-4f41-404c-8f7e-0ece6eb96921"], +Cell[53055, 1510, 839, 16, 119, "Text",ExpressionUUID->"82ccea7b-3f80-48f8-8539-2ce7e112201e"], +Cell[53897, 1528, 326, 8, 40, "Input",ExpressionUUID->"c82ab463-4bbc-406e-a40d-7617c120aad3"], +Cell[54226, 1538, 1406, 32, 119, "Text",ExpressionUUID->"86ee511d-1b4d-47be-9475-ef5f0a51568e"], +Cell[CellGroupData[{ +Cell[55657, 1574, 497, 9, 39, "Subsubsection",ExpressionUUID->"330b50ca-3cf0-415a-954e-484180ad73fa"], +Cell[56157, 1585, 837, 18, 42, "Text",ExpressionUUID->"4ea8db2b-1166-4031-ad39-755caeff97e5"], +Cell[56997, 1605, 329, 11, 42, "Text",ExpressionUUID->"5351055e-7f66-4f90-a522-216f6edfc8aa"], +Cell[57329, 1618, 1655, 48, 243, "Text",ExpressionUUID->"8f70b6b3-c98e-43e0-a271-a77ebacaa169"] +}, Open ]] +}, Closed]] +}, Closed]], +Cell[CellGroupData[{ +Cell[59045, 1673, 196, 3, 78, "Section",ExpressionUUID->"0669503b-97b4-42d3-9f43-e5d90bd63cb6"], +Cell[CellGroupData[{ +Cell[59266, 1680, 263, 4, 76, "Subsection",ExpressionUUID->"337c5123-44ce-4d0f-aa70-7a1eef246c34"], +Cell[59532, 1686, 1065, 16, 369, "Text",ExpressionUUID->"e4d5ca47-3b2d-43ae-9d2d-041527f387b4"], +Cell[60600, 1704, 850, 17, 378, "Text",ExpressionUUID->"c95aa361-aabd-4f79-b626-7187ed035d57"], +Cell[61453, 1723, 416, 8, 369, "Text",ExpressionUUID->"e50b458d-661c-4a93-875f-18ce10de9d6c"], +Cell[61872, 1733, 326, 8, 234, "Text",ExpressionUUID->"e1c11abc-3f72-42e1-a159-64edbfe8ab87"], +Cell[62201, 1743, 162, 3, 234, "Text",ExpressionUUID->"3f9285ad-c731-449c-ad3a-79a5039144d9"], +Cell[62366, 1748, 525, 15, 243, "Input",ExpressionUUID->"6ef85025-a1c5-4378-904b-9fb0b330e6d8"], +Cell[62894, 1765, 539, 13, 369, "Text",ExpressionUUID->"25c38607-86ed-4de2-b571-4a4196e7943b"], +Cell[63436, 1780, 769, 24, 418, "Input",ExpressionUUID->"2062c569-f473-44ed-8600-946f8e708cbf"], +Cell[64208, 1806, 214, 4, 234, "Text",ExpressionUUID->"fdbd9a62-d5eb-4673-80fb-043dd1bc94bd"], +Cell[64425, 1812, 657, 17, 243, "Input",ExpressionUUID->"8464d527-ba54-4ca9-acec-a015cab710a5"], +Cell[65085, 1831, 695, 20, 243, "Input",ExpressionUUID->"3539e093-0107-4f13-ad69-0cbffe726d68"], +Cell[65783, 1853, 201, 3, 234, "Text",ExpressionUUID->"619da990-af6e-4153-81f1-df6c4f0887cb"], +Cell[65987, 1858, 1096, 33, 918, "Input",ExpressionUUID->"c56cc435-02c8-4b5b-9ae1-8722f5e39af5"], +Cell[CellGroupData[{ +Cell[67108, 1895, 706, 11, 333, "Subsubsection",ExpressionUUID->"02653e6c-8ad0-4b5c-bd8b-1cbc61076317"], +Cell[67817, 1908, 1779, 45, 1030, "Text",ExpressionUUID->"88247085-1b12-4e56-a22e-8a079f79ea2e"] +}, Open ]] +}, Closed]], +Cell[CellGroupData[{ +Cell[69645, 1959, 209, 4, 55, "Subsection",ExpressionUUID->"2ec15f1f-4de6-4d00-b5da-92d5fd79ac55"], +Cell[69857, 1965, 450, 9, 139, "Text",ExpressionUUID->"c2a98a5f-4c45-4bcd-a087-e95801a9d4dd"], +Cell[70310, 1976, 850, 18, 138, "Text",ExpressionUUID->"9fac8228-d0a5-4ab7-9873-8ea94ab897cd"], +Cell[CellGroupData[{ +Cell[71185, 1998, 1753, 39, 271, "Input",ExpressionUUID->"f4fad38c-20e5-433a-ba4d-f808002eb306"], +Cell[72941, 2039, 323, 5, 60, "Output",ExpressionUUID->"eeaf7619-9c0a-4479-84be-368e230c80fe"] +}, Open ]], +Cell[73279, 2047, 513, 11, 216, "Text",ExpressionUUID->"3f2851a7-99f5-4c23-84f4-f6297e5fda88"], +Cell[73795, 2060, 187, 3, 63, "Text",ExpressionUUID->"8116e108-33b9-40c2-9aaf-3e9c5e03bdaf"], +Cell[73985, 2065, 602, 12, 60, "Input",ExpressionUUID->"13f9e422-7257-49e4-b3f8-490fff188fa3"], +Cell[74590, 2079, 214, 4, 63, "Text",ExpressionUUID->"74a2b478-3314-48df-8eba-aa01af87d1a4"], +Cell[74807, 2085, 1017, 24, 96, "Input",ExpressionUUID->"b2da604a-35ef-4465-a1c4-9616701046c4"], +Cell[75827, 2111, 582, 13, 102, "Text",ExpressionUUID->"dafbb20a-3ff2-4d30-bdda-20bee74c7d51"], +Cell[CellGroupData[{ +Cell[76434, 2128, 428, 6, 58, "Subsubsection",ExpressionUUID->"6421db11-3ab7-4935-a814-d38aa207bd45"], +Cell[76865, 2136, 993, 17, 139, "Text",ExpressionUUID->"fea86190-799e-449f-92dd-2e6254c0a10a"] +}, Open ]] +}, Closed]], +Cell[CellGroupData[{ +Cell[77907, 2159, 263, 4, 55, "Subsection",ExpressionUUID->"550e7194-bb09-44ca-8202-7aa8509b7163"], +Cell[78173, 2165, 457, 10, 102, "Text",ExpressionUUID->"d7813717-471b-4423-af8b-e482c761f031"], +Cell[78633, 2177, 901, 26, 99, "Input",ExpressionUUID->"eab8fe8a-7e93-4137-a706-5c11219140cf"], +Cell[79537, 2205, 226, 5, 60, "Input",ExpressionUUID->"13b67bf0-d454-4601-b2d9-df9392a2fce9"], +Cell[79766, 2212, 674, 14, 292, "Text",ExpressionUUID->"fb65784d-2258-40cf-8a96-3db69f900324"], +Cell[80443, 2228, 217, 5, 63, "Text",ExpressionUUID->"25fffab2-3284-41a2-b331-bf1bc51218cc"], +Cell[80663, 2235, 392, 9, 60, "Input",ExpressionUUID->"f748301f-0f91-46f7-a32d-c8a713c6db14"], +Cell[81058, 2246, 472, 13, 60, "Input",ExpressionUUID->"0e0b1980-60e0-4b1f-8e1d-0ac9a6353b59"] +}, Closed]] +}, Closed]], +Cell[CellGroupData[{ +Cell[81579, 2265, 269, 4, 78, "Section",ExpressionUUID->"dc9ee782-89de-48e5-b2b8-58f448d8238b"], +Cell[81851, 2271, 1166, 19, 216, "Text",ExpressionUUID->"d3fb88cc-95fa-4056-8059-f58a6f713a1f"] +}, Closed]], +Cell[CellGroupData[{ +Cell[83054, 2295, 201, 3, 78, "Section",ExpressionUUID->"84e5f518-7484-462b-ab6b-9d8e8b20e3e7"], +Cell[83258, 2300, 1774, 38, 629, "Text",ExpressionUUID->"3255a60a-d601-40f2-849b-461e1e6b2c7c"], +Cell[CellGroupData[{ +Cell[85057, 2342, 160, 3, 76, "Subsection",ExpressionUUID->"64ce6d46-be26-41b7-8a0a-bf920b092106"], +Cell[85220, 2347, 541, 12, 369, "Text",ExpressionUUID->"05dc1c71-fad7-4ccc-8017-29ff2d1a1ac9"], +Cell[85764, 2361, 233, 4, 234, "Text",ExpressionUUID->"7cf0bd5a-445d-4b52-aea5-e96839897d0d"], +Cell[86000, 2367, 802, 26, 301, "Input",ExpressionUUID->"31ae8fa9-a158-4ab8-b4b6-fe691d67bf99"], +Cell[86805, 2395, 772, 20, 558, "Text",ExpressionUUID->"ae61509c-f98f-41ff-aa52-75c59481b9a4"] +}, Closed]], +Cell[CellGroupData[{ +Cell[87614, 2420, 208, 4, 55, "Subsection",ExpressionUUID->"8b71d86c-41af-4763-a5f3-583f374cf689"], +Cell[87825, 2426, 4397, 134, 3235, "Text",ExpressionUUID->"d0f33504-04b3-45fc-ad86-ae358e00270b"], +Cell[92225, 2562, 1892, 37, 1323, "Text",ExpressionUUID->"1c25a2ce-1726-4903-b230-20b8da935c20"], +Cell[94120, 2601, 274, 6, 234, "Text",ExpressionUUID->"7b1acad4-a948-4b4e-95c7-b7c5e629ab55"], +Cell[94397, 2609, 456, 12, 382, "Input",ExpressionUUID->"d978ddd8-d61c-4ab1-ab85-b50367f0d5a1"], +Cell[94856, 2623, 326, 7, 369, "Text",ExpressionUUID->"edeb5d4e-608b-4db8-b90d-da46955cef3f"], +Cell[95185, 2632, 1215, 33, 382, "Input",ExpressionUUID->"7555bccd-74da-4d28-b19b-a3a0635b49f8"], +Cell[96403, 2667, 219, 4, 234, "Text",ExpressionUUID->"005d101d-ae26-4277-8238-aa501f4ad9b7"], +Cell[96625, 2673, 190, 4, 243, "Input",ExpressionUUID->"ee32c7ed-08cc-4563-a7f6-e0bc88892fdc"], +Cell[96818, 2679, 1166, 24, 972, "Text",ExpressionUUID->"ab55cf22-76ed-4d99-a9e9-1d7d7272b4d9"] +}, Closed]], +Cell[CellGroupData[{ +Cell[98021, 2708, 255, 4, 55, "Subsection",ExpressionUUID->"fbd6ce0c-e917-4d48-9a6d-c5304a73fe3c"], +Cell[98279, 2714, 428, 8, 504, "Text",ExpressionUUID->"9a4f93c5-3101-460b-ad32-a65abf4e1270"], +Cell[98710, 2724, 2012, 46, 1192, "Input",ExpressionUUID->"4376c14f-397e-49be-a5ef-2a30667b650b"], +Cell[100725, 2772, 564, 12, 909, "Text",ExpressionUUID->"5a823be0-002e-49b0-80b3-aaf10e8e6bd4"], +Cell[101292, 2786, 271, 6, 234, "Text",ExpressionUUID->"848b6314-fa5e-411f-b64d-fb7e801a9d84"], +Cell[101566, 2794, 561, 12, 243, "Input",ExpressionUUID->"bb67a767-5c35-407b-882b-fc54952d877b"], +Cell[102130, 2808, 341, 5, 234, "Text",ExpressionUUID->"4d483adb-b69d-4591-9965-1c4755d61d49"], +Cell[102474, 2815, 1122, 30, 517, "Input",ExpressionUUID->"0805dd71-581a-4fa0-9d3c-a4b380906361"], +Cell[103599, 2847, 376, 7, 369, "Text",ExpressionUUID->"aa4a36b5-8cd6-4256-afbb-41ac3660e985"] +}, Closed]], +Cell[CellGroupData[{ +Cell[104012, 2859, 278, 3, 55, "Subsection",ExpressionUUID->"33d2b3f2-90ba-4224-960e-e45570482f97"], +Cell[104293, 2864, 948, 23, 2259, "Text",ExpressionUUID->"2a7613bd-4dad-4d29-b697-779d3d401a67"], +Cell[105244, 2889, 443, 10, 234, "Text",ExpressionUUID->"2c21241a-b644-4e60-93ed-6638973eecb8"], +Cell[105690, 2901, 431, 11, 292, "Input",ExpressionUUID->"58f5a378-3fc3-41fd-ada2-65ce5f9a137c"], +Cell[106124, 2914, 677, 19, 459, "Text",ExpressionUUID->"3d06e8cc-9891-4c64-8fb9-42b67f8fbb91"], +Cell[106804, 2935, 378, 9, 234, "Text",ExpressionUUID->"7b2cdff2-2182-48cf-ac02-a9494939fef8"], +Cell[107185, 2946, 735, 21, 382, "Input",ExpressionUUID->"1bcd7ff8-9005-464d-9233-a6e89a5cc9bb"], +Cell[107923, 2969, 303, 6, 243, "Input",ExpressionUUID->"a8d57928-cf54-4d9b-a289-e43c89d34f2a"], +Cell[108229, 2977, 236, 6, 234, "Text",ExpressionUUID->"78e6f21a-1272-441d-b6d9-18820710c4dd"], +Cell[108468, 2985, 405, 11, 243, "Input",ExpressionUUID->"7460d9a6-b319-466f-9aac-ba1bec99991f"], +Cell[108876, 2998, 190, 4, 243, "Input",ExpressionUUID->"32be12a8-9832-413c-b38d-0d0bb7662aa2"], +Cell[109069, 3004, 1440, 33, 1107, "Text",ExpressionUUID->"4c38ab37-b9d1-4a3b-9032-449d806e9a28"], +Cell[110512, 3039, 1410, 32, 594, "Text",ExpressionUUID->"38e6e281-9372-42f3-b1ba-52d6d6897294"], +Cell[111925, 3073, 1190, 37, 756, "Text",ExpressionUUID->"4b2bce83-42db-4917-bf97-995cf24d5f38"], +Cell[113118, 3112, 686, 19, 432, "Text",ExpressionUUID->"c85c7daf-f387-4346-aec8-290783f4dd40"], +Cell[113807, 3133, 290, 7, 234, "Text",ExpressionUUID->"b5370c8e-934b-4f47-b0a6-987bbe311cf6"], +Cell[114100, 3142, 2320, 56, 1057, "Input",ExpressionUUID->"72104b61-7a28-4e51-8858-4c3084509e61"], +Cell[116423, 3200, 314, 6, 234, "Text",ExpressionUUID->"01d86221-a2da-4a01-b318-28481c40170c"], +Cell[116740, 3208, 948, 18, 243, "Input",ExpressionUUID->"dd74ca75-4bee-432d-aa50-a8a0aa97bd72"], +Cell[117691, 3228, 387, 6, 234, "Text",ExpressionUUID->"f3fd1d3b-1d76-4b98-b6dd-a9df4eca1559"], +Cell[118081, 3236, 1264, 33, 787, "Input",ExpressionUUID->"9c32c182-a1ad-4100-8507-4e8b0001d4ac"], +Cell[119348, 3271, 552, 11, 774, "Text",ExpressionUUID->"6c88fee2-de29-4e39-b06b-ab3bd2634ab4"], +Cell[119903, 3284, 1277, 33, 787, "Input",ExpressionUUID->"a7c05903-c7c8-4283-8de9-88755fa788b3"] +}, Closed]], +Cell[CellGroupData[{ +Cell[121217, 3322, 326, 5, 55, "Subsection",ExpressionUUID->"ea4d4e06-3e0f-406f-8bd5-45d53847e4d3"], +Cell[121546, 3329, 768, 14, 1044, "Text",ExpressionUUID->"c640a1df-cc74-4b4c-8c75-8072b50e7988"], +Cell[122317, 3345, 293, 6, 342, "Input",ExpressionUUID->"1885bc31-c81a-4dd8-851a-3f89957a96fb"], +Cell[122613, 3353, 321, 7, 369, "Text",ExpressionUUID->"7bb81acc-bce0-4590-8098-3f56d9c02c65"], +Cell[122937, 3362, 2977, 67, 1561, "Input",ExpressionUUID->"67767389-3ae8-4dd5-a77a-483f5a0838d9"], +Cell[125917, 3431, 1023, 18, 1314, "Text",ExpressionUUID->"4214924c-5edf-479c-bb85-d85ed1dff2bb"], +Cell[126943, 3451, 271, 6, 234, "Text",ExpressionUUID->"d16a8b73-c5b3-40ee-88e9-5d42645b7d7b"], +Cell[127217, 3459, 561, 12, 342, "Input",ExpressionUUID->"7f4547cb-4896-4fee-9982-99aa55b18bf0"], +Cell[127781, 3473, 341, 5, 234, "Text",ExpressionUUID->"273ad33d-6ad9-40cc-bc6a-9778fb60705e"], +Cell[128125, 3480, 1221, 32, 616, "Input",ExpressionUUID->"031e6d69-b30e-4968-8c71-3729b5db26fb"], +Cell[129349, 3514, 628, 11, 909, "Text",ExpressionUUID->"3f02efad-548d-4196-b6c7-69642da2020e"] +}, Closed]] +}, Closed]], +Cell[CellGroupData[{ +Cell[130026, 3531, 255, 4, 53, "Section",ExpressionUUID->"a61c7f9b-390b-4cb0-a7f5-0fd05cbd2474"], +Cell[130284, 3537, 1044, 18, 178, "Text",ExpressionUUID->"1aef1eb4-bbf7-4985-820b-bcd2d0b878eb"] +}, Closed]], +Cell[CellGroupData[{ +Cell[131365, 3560, 282, 8, 53, "Section",ExpressionUUID->"6ecd5346-96b4-40b0-b023-33a4ea0ae1ff", + Evaluatable->False], +Cell[CellGroupData[{ +Cell[131672, 3572, 141, 3, 51, "Subsection",ExpressionUUID->"b0e57c80-4368-4d82-a768-047cb9b25fe8", + Evaluatable->False], +Cell[131816, 3577, 2928, 87, 1000, "Input",ExpressionUUID->"6856d5ae-91f6-4ff2-9e5e-89c7d58c457c"] +}, Closed]], +Cell[CellGroupData[{ +Cell[134781, 3669, 258, 7, 37, "Subsection",ExpressionUUID->"f9a171cc-759c-4ccd-896c-9ce8fff362c6"], +Cell[135042, 3678, 604, 12, 1044, "Text",ExpressionUUID->"0e04ef6d-1b69-497c-8440-368a484f4005"], +Cell[135649, 3692, 342, 9, 243, "Input",ExpressionUUID->"3e2e5008-bd35-48e9-8b13-fca9dd5b0c16"], +Cell[135994, 3703, 560, 15, 382, "Input",ExpressionUUID->"9240e55d-92bd-48eb-ad90-252d36fdf332"] +}, Closed]], +Cell[CellGroupData[{ +Cell[136591, 3723, 243, 8, 60, "Subsection",ExpressionUUID->"e9198c98-18d8-40a4-96bf-baa7817a18aa", + Evaluatable->False], +Cell[136837, 3733, 1749, 60, 709, "Text",ExpressionUUID->"840b08ef-f6af-43ed-96c8-3b6c7252c6e8", + Evaluatable->False] +}, Closed]], +Cell[CellGroupData[{ +Cell[138623, 3798, 211, 7, 37, "Subsection",ExpressionUUID->"4caafba8-e43f-472d-bccf-d04d35438391", + Evaluatable->False], +Cell[138837, 3807, 1993, 66, 393, "Input",ExpressionUUID->"2e128d7a-a53e-4e08-8f85-aa48fdd6a6e7"] +}, Closed]], +Cell[CellGroupData[{ +Cell[140867, 3878, 152, 3, 37, "Subsection",ExpressionUUID->"fd5091b3-6526-4a1c-8193-1feab5f154c4", + Evaluatable->False], +Cell[141022, 3883, 8386, 194, 11322, "Text",ExpressionUUID->"4ffac4ba-a0cd-4080-b33c-236e4bc57984", + Evaluatable->False] +}, Closed]], +Cell[CellGroupData[{ +Cell[149445, 4082, 135, 3, 37, "Subsection",ExpressionUUID->"f64f4fc7-d022-4801-8ec7-cfdb730dfebb", + Evaluatable->False], +Cell[149583, 4087, 511, 12, 504, "Text",ExpressionUUID->"5351ad39-27a1-4e3e-aea9-6d07c59041b7"], +Cell[150097, 4101, 181, 4, 243, "Input",ExpressionUUID->"6d520d5e-3b3d-4c8c-9987-a1f4c7d58fd6"], +Cell[CellGroupData[{ +Cell[150303, 4109, 1383, 41, 517, "Input",ExpressionUUID->"62ca4b3b-3a6f-4e92-861c-b2ffe4074897"], +Cell[151689, 4152, 1447, 27, 2241, "Output",ExpressionUUID->"435fb041-7aa4-426f-90a8-d3b75b2698af"] +}, Open ]] +}, Closed]] +}, Open ]] +}, Open ]] +} +] +*) + diff --git a/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/BIOS2_WorkshopMathematicaSOLUTIONS.nb b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/BIOS2_WorkshopMathematicaSOLUTIONS.nb new file mode 100644 index 0000000..9417c7d --- /dev/null +++ b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/BIOS2_WorkshopMathematicaSOLUTIONS.nb @@ -0,0 +1,19305 @@ +(* Content-type: application/mathematica *) + +(*** Wolfram Notebook File ***) +(* http://www.wolfram.com/nb *) + +(* CreatedBy='Mathematica 6.0' *) + +(*CacheID: 234*) +(* Internal cache information: +NotebookFileLineBreakTest +NotebookFileLineBreakTest +NotebookDataPosition[ 145, 7] +NotebookDataLength[ 971571, 19297] +NotebookOptionsPosition[ 927035, 18594] +NotebookOutlinePosition[ 928402, 18631] +CellTagsIndexPosition[ 928182, 18623] +WindowFrame->Normal*) + +(* Beginning of Notebook Content *) +Notebook[{ + +Cell[CellGroupData[{ +Cell[TextData[{ + StyleBox["An Introduction to Mathematical Modeling in Ecology and Evolution\n\ +\t\t", + FontSize->24], + StyleBox["Sally Otto (2020)", "Text", + FontSize->24] +}], "Title", + CellChangeTimes->{{3.5139469945181007`*^9, 3.5139470031089993`*^9}, { + 3.5139470749751873`*^9, 3.51394707739872*^9}, 3.514081679254755*^9, + 3.5635847030731*^9, 3.589034444732832*^9, 3.619865854931665*^9, { + 3.787357889985818*^9, + 3.78735789006644*^9}},ExpressionUUID->"8a327de2-529b-4bea-8247-\ +b78719b77d90"], + +Cell[TextData[{ + StyleBox["Sponsors:\n", + FontWeight->"Bold"], + "BIOS2 (NSERC - CREATE Training program)\n", + StyleBox["\nResources:\n* ", + FontWeight->"Bold"], + StyleBox["An Introduction to Mathematical Modeling in Ecology and Evolution", + + FontSlant->"Italic"], + " (2007) by Otto and Day\n* Biomathematical modeling lecture notes \ +(http://www.zoology.ubc.ca/~bio301/Bio301/Lectures.html)\n* ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " labs (http://www.zoology.ubc.ca/biomath/labs.htm)" +}], "Text", + CellChangeTimes->{{3.787357970535242*^9, + 3.787358015823761*^9}},ExpressionUUID->"c1f25a80-b0a0-4723-b2be-\ +418deaae5a8c"], + +Cell[CellGroupData[{ + +Cell["\<\ +Part 1: Classic one-variable models in ecology and evolution\ +\>", "Section", + CellChangeTimes->{{3.513947212490135*^9, 3.513947218035974*^9}, { + 3.5139498791123238`*^9, 3.513949882837112*^9}, {3.5139528239741087`*^9, + 3.513952837318131*^9}, {3.5141651837854567`*^9, + 3.514165197895406*^9}},ExpressionUUID->"73ad134b-a12d-40b7-9758-\ +a39415a42e2a"], + +Cell[CellGroupData[{ + +Cell["Exponential growth", "Subsection", + CellChangeTimes->{{3.513947230674706*^9, + 3.513947234068375*^9}},ExpressionUUID->"487c3942-fe85-40fd-83f5-\ +55cc1164f56d"], + +Cell[TextData[{ + "Assumes that each individual replicates at a constant rate over time:\n\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", " ", + RowBox[{"R", " ", + RowBox[{"n", "[", "t", "]"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"5ee9eb69-3d34-4461-8d52-fbb5c33a75bd"], + "\t\t\t\t\t\tDiscrete-time model (\"", + StyleBox["Recursion equation", + FontColor->RGBColor[1, 0, 0]], + "\")\n\t\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + FractionBox["dn", "dt"], "=", + RowBox[{ + RowBox[{ + SuperscriptBox["n", "\[Prime]", + MultilineFunction->None], "[", "t", "]"}], "=", " ", + RowBox[{"r", " ", + RowBox[{"n", "[", "t", "]"}]}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"ce05a184-fb70-4fbd-b267-c5fe06685121"], + "\t\t\t\t\t\tContinuous-time model (\"", + StyleBox["Differential equation", + FontColor->RGBColor[1, 0, 0]], + "\")\n\t\nn[t]:\tThe population size at time t \nR:\tThe number of offspring \ +per parent in a time unit (from t to t+1).\nr:\tThe growth rate per parent \ +per time unit." +}], "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.513947390108379*^9, 3.5139474220813217`*^9}, {3.513947452990963*^9, + 3.5139475208704576`*^9}, {3.513947727092204*^9, 3.513947731187154*^9}, { + 3.513947812189878*^9, 3.513947902559455*^9}, {3.513947984682602*^9, + 3.513948011709552*^9}, {3.513948963092691*^9, 3.51394897018489*^9}, { + 3.513954053195573*^9, 3.513954074185573*^9}, + 3.514678036939659*^9},ExpressionUUID->"7a137491-f62f-47fa-b492-\ +d360b4529c55"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Logistic growth", "Subsection", + CellChangeTimes->{{3.513947230674706*^9, 3.513947234068375*^9}, { + 3.513947350245451*^9, + 3.5139473511317797`*^9}},ExpressionUUID->"10ac2577-62f8-4f6c-9f58-\ +c0040c166b45"], + +Cell[TextData[{ + "Assumes that each individual replicates at a rate that declines as a linear \ +function of the current population size:\n\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}]}]}], ")"}], + RowBox[{"n", "[", "t", "]"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"1846b184-e262-4698-a645-9985dd28f418"], + "\t\t\t\tDiscrete-time model\n\t\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dn", "dt"], "=", + RowBox[{ + RowBox[{ + SuperscriptBox["n", "\[Prime]", + MultilineFunction->None], "[", "t", "]"}], "=", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}], " ", + RowBox[{"n", "[", "t", "]"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"9cf1fc48-2883-4250-9f54-3ef904166d1b"], + "\t\t\t\t\tContinuous-time model\n\t\nr: \tThe \"intrinsic\" growth rate \ +per parent per unit time, realized when competition is weak (population size \ +small)\nK: \tThe \"carrying capacity\" defined as the population size at \ +which competition causes the population to neither grow nor shrink" +}], "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.5139475325082417`*^9, 3.51394758040838*^9}, {3.5139476417549477`*^9, + 3.513947714905636*^9}, {3.513947913524728*^9, 3.513947982531314*^9}, { + 3.513948017290382*^9, 3.513948113203456*^9}, {3.5139488721875877`*^9, + 3.513948951376718*^9}},ExpressionUUID->"28be2ba4-f799-48b5-b3d7-\ +88ff742ece0d"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Haploid model of selection", "Subsection", + CellChangeTimes->{{3.513947230674706*^9, 3.513947234068375*^9}, { + 3.513947350245451*^9, + 3.513947360443203*^9}},ExpressionUUID->"583ce927-cb7a-4afc-806f-\ +e2ddd8887de0"], + +Cell[TextData[{ + "Assumes that each individual carrying A has a fitness of 1+s relative to \ +individuals carrying a, where p is the frequency of A:\n\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + RowBox[{"p", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"aa6b2380-0c12-4124-b32f-f57ec52cb4d7"], + "\t\t\t\t\tDiscrete-time model\n\t\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dp", "dt"], "=", + RowBox[{ + RowBox[{ + SuperscriptBox["p", "\[Prime]", + MultilineFunction->None], "[", "t", "]"}], "=", + RowBox[{"s", " ", + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"5e46dd53-7c96-4121-a461-419d04bbccda"], + "\t\t\t\t\tContinuous-time model\n\t\np:\tFrequency of allele ", + StyleBox["A", + FontSlant->"Italic"], + " at a locus with two alleles (", + StyleBox["a", + FontSlant->"Italic"], + " and ", + StyleBox["A", + FontSlant->"Italic"], + "). ", + StyleBox["p", + FontSlant->"Italic"], + " must lie between 0 and 1.\ns:\tSelection coefficient favoring allele ", + StyleBox["A", + FontSlant->"Italic"], + " over ", + StyleBox["a.", + FontSlant->"Italic"] +}], "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.5139475325082417`*^9, 3.51394758040838*^9}, {3.5139476417549477`*^9, + 3.513947714905636*^9}, {3.513947913524728*^9, 3.513947982531314*^9}, { + 3.513948017290382*^9, 3.513948113203456*^9}, {3.51394894565186*^9, + 3.513949092099876*^9}, + 3.514678047651116*^9},ExpressionUUID->"1877d1e9-a3c1-4034-a81a-\ +b82bee67d839"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell[TextData[{ + "Getting used to ", + StyleBox["Mathematica", + FontSlant->"Italic"] +}], "Subsection", + CellChangeTimes->{{3.513948127281714*^9, + 3.513948137855798*^9}},ExpressionUUID->"95131596-18ab-4c85-82e9-\ +b54886651daf"], + +Cell[TextData[{ + StyleBox["Mathematica", + FontSlant->"Italic"], + " can be used as a sophisticated calculator." +}], "Text", + CellChangeTimes->{{3.513948198540515*^9, + 3.513948235067747*^9}},ExpressionUUID->"e55751a2-3544-4768-be72-\ +fcb24b219507"], + +Cell["\<\ +For example, if r = 0.3, K = 100, and n = 90 at some time, what population \ +size do we expect in the next generation?\ +\>", "Text", + CellChangeTimes->{{3.513948237712743*^9, 3.513948264443959*^9}, { + 3.513948665451997*^9, + 3.513948670365511*^9}},ExpressionUUID->"ff278b1a-0b0b-42cc-bdab-\ +4ee0e7a67580"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox["n", "K"]}], ")"}]}]}], ")"}], "n"}], "/.", + RowBox[{"n", "\[Rule]", "90"}]}], "/.", + RowBox[{"r", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"K", "\[Rule]", "100"}]}]], "Input", + CellChangeTimes->{{3.513948287127791*^9, 3.513948302422172*^9}, { + 3.513948679036108*^9, + 3.5139486822503233`*^9}},ExpressionUUID->"c3464778-7e0c-4d59-a545-\ +308c9d4c445a"], + +Cell[BoxData["92.7`"], "Output", + CellChangeTimes->{ + 3.5139486890735188`*^9},ExpressionUUID->"0f77a2a6-b30a-4597-b0da-\ +2c19bce19a45"] +}, Open ]], + +Cell[TextData[{ + StyleBox["Mathematica", + FontSlant->"Italic"], + " can also plots functions.\n\nFor example, the per capita number of \ +offspring per parent in the logistic model:" +}], "Text", + CellChangeTimes->{{3.513948237712743*^9, 3.513948264443959*^9}, { + 3.51394832016193*^9, 3.513948337930262*^9}, {3.513948397404797*^9, + 3.513948401530624*^9}, {3.5139484555709047`*^9, + 3.513948474384674*^9}},ExpressionUUID->"5c56e21e-ec31-42b6-a0d2-\ +37d703af7a5a"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox["n", "K"]}], ")"}]}]}], ")"}], "/.", + RowBox[{"r", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"K", "\[Rule]", "100"}]}], ",", + RowBox[{"{", + RowBox[{"n", ",", "0", ",", "250"}], "}"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{"Automatic", ",", + RowBox[{"{", + RowBox[{"0", ",", "1.5"}], "}"}]}], "}"}]}]}], "]"}]], "Input", + CellChangeTimes->{{3.513948425105887*^9, 3.513948439648486*^9}, { + 3.5139486842958097`*^9, + 3.513948685978443*^9}},ExpressionUUID->"72de16af-d707-45d3-a95b-\ +a3bd007f56ef"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {Hue[0.67, 0.6, 0.6], LineBox[CompressedData[" +1:eJwVjnk4lAkcgC0TJlJ0uMrRtJtrsxEr4fdzrB4aTcgkK2QYx+r7SkSNbJuj +UmvHVESrmRFq2y2erESxHukgW0k8U1J9I7lmMEelFNv+8T7vn+9rHUuGxGtq +aGgEfeF/jys/Mf25vV7V07X3urrUkFq139lPXAeC46HF/ffVkKkn55qKb0G2 +xTvOWKcaeC3VGjRxD7D9NszpdKjhc0lO0AfRIOjwb7v43lZDC02pUolUkLT6 +WUVjsxosNthuVIi00IGtdbD6iho297VPTYoWY11d2NpDfDVgUY7eD2mrsJ5W +Y2PNUoOhil1bxFmDj1vFVsZGavC6kRl8cNE6nBNR5dCnAtHelsvPw9ejpXHf +H2GnVfAiYODxjL8XRk5zrrWGqyB+0wF57ENvPEFWB5saq8C76T3tIeGH9+e7 +plb2KUHvOqVhTvnjN4bRJ3PLlGCv2Eh4HA3A9MseviHbleDeaNbqqcnEV3/X +qdKWK6EmIPrrO+RmjHiVYdv5SgHN8xfNGh7bgnfFU3J9kQLMrlf3194KxuAH +mnWVHAWszJnZ02QSig/4Hdp2KxUQ5UQXHEnYihEZAy8pagoMbYMq24VhqNVR +0DhRNQWkJ4tMUbJRWCuzHo2bAr/SIw65a8Jxm9ZIgZvNFLQbZVdo521HHYnj +vPGuScjY/W0FszcCsxS2cx2bJkG8dPEpzYWRaE+xP4b0TECG5JoXg7MDWz/J +jBq2TEC7lN9fJ4rCwol6h9t9cvDrZmjqSqJxv41psFu0HK4TTbsHT8Ugs3BI +kD8gg2Mm2U8POO3EbZ2ve7PjZPBdt+jcxoGdGOgU5BpCjcPUjNDmXW4sRkhZ +4oKYcUgJbPoz0pqD5xPzFuwaGYPmC87Hpzs52GO2qsSOOwadNvc4zKQ49Dj/ +1logGwWF+fqvDtPisW3vzoao9FGQr6DPyP6KR8fdrsna6hGo8lXLFwZysdfH +yyKcNwJOmV6eiWouxnrXTOZODwPv0fm8zJMJaLsstO3H7GEYKBsSJDsmor5z +kbBEexiWpuV/KpIkooTnVnYl9w3Q9/hE79mXhP1lRsWk3ht4nLXDIt86Ge8M +hdXoHR2C+o9bK7I6kvFBpnOPvs4QhP6eYGnP/QkNpL7TDYWv4S7z6bTBohR0 +zWh299J/De+suPcvXUnBEmlSNiEYBEh4GGsTuAuXFdd2aZkPQtTNEna/chfy +0mPc0kql4ObC8/XnE2hi71tVaCWFPp6P3byTBKZxXLpTLaSQ3kY3bD9N4KOz +qz+zl0vhKuvMC++zBObr64dZmkjBIbl+v2c1gUr5E1rtQilYCSdr1t0k8N9a +blz3LAV0etxyxgiBh1wLGEsGKLjIsteSjhHYT2Sxpp9R4F+sHBXJCXS9QPCe +SyjIZfzSYKEiUGYc2lP5hIJZz3MhZrMERnwwz3HpokCZKjlquITEdTcvS9k3 +KOA3CslHy0jkq4UGGxopcNRIYP9mSuKYg8DdsoGClF/fMhZYklhRvk8wfJWC +NxeM/tG1I9HgZ/DJvPSlN/G06q4DiUkNa4nIixQwXMQn8h1JbJ9klGE1BTFt +jhE0FxIPxOgqdSu+/Oi+x1vfk9h35uMKuZCCclbL6sPuJDp1ywK6yynwKM4z +8PYk8QT9ZXr9WQqePWe+nQMSR7y7xaWlFPwHWD5XfQ== + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{{0., 249.9999948979592}, {0, 1.5}}, + PlotRangeClipping->True, + PlotRangePadding->{ + Scaled[0.02], Automatic}]], "Output", + CellChangeTimes->{ + 3.563585356334155*^9},ExpressionUUID->"9480aa9f-a717-45f4-b3c1-\ +addffca0ae58"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Manipulate", "[", + RowBox[{ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox["n", "K"]}], ")"}]}]}], ")"}], ",", + RowBox[{"{", + RowBox[{"n", ",", "0", ",", "250"}], "}"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{"Automatic", ",", + RowBox[{"{", + RowBox[{"0", ",", "1.5"}], "}"}]}], "}"}]}]}], "]"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"r", ",", "0.3"}], "}"}], ",", "0.01", ",", "0.5"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"K", ",", "100"}], "}"}], ",", "10", ",", "200"}], "}"}]}], + "]"}]], "Input", + CellChangeTimes->{{3.563585040878352*^9, + 3.5635850910666943`*^9}},ExpressionUUID->"4b10af3a-a9cc-4fe3-bf00-\ +6896aeeeaa8f"], + +Cell[BoxData[ + TagBox[ + StyleBox[ + DynamicModuleBox[{K$$ = 100, $CellContext`r$$ = 0.3, Typeset`show$$ = True, + Typeset`bookmarkList$$ = {}, Typeset`bookmarkMode$$ = "Menu", + Typeset`animator$$, Typeset`animvar$$ = 1, Typeset`name$$ = + "\"untitled\"", Typeset`specs$$ = {{{ + Hold[$CellContext`r$$], 0.3}, 0.01, 0.5}, {{ + Hold[K$$], 100}, 10, 200}}, Typeset`size$$ = {450., {140., 146.}}, + Typeset`update$$ = 0, Typeset`initDone$$, Typeset`skipInitDone$$ = + True, $CellContext`r$2717$$ = 0, K$2718$$ = 0}, + DynamicBox[Manipulate`ManipulateBoxes[ + 1, StandardForm, "Variables" :> {K$$ = 100, $CellContext`r$$ = 0.3}, + "ControllerVariables" :> { + Hold[$CellContext`r$$, $CellContext`r$2717$$, 0], + Hold[K$$, K$2718$$, 0]}, + "OtherVariables" :> { + Typeset`show$$, Typeset`bookmarkList$$, Typeset`bookmarkMode$$, + Typeset`animator$$, Typeset`animvar$$, Typeset`name$$, + Typeset`specs$$, Typeset`size$$, Typeset`update$$, Typeset`initDone$$, + Typeset`skipInitDone$$}, "Body" :> + Plot[1 + $CellContext`r$$ (1 - $CellContext`n/K$$), {$CellContext`n, 0, + 250}, PlotRange -> {Automatic, {0, 1.5}}], + "Specifications" :> {{{$CellContext`r$$, 0.3}, 0.01, 0.5}, {{K$$, 100}, + 10, 200}}, "Options" :> {}, "DefaultOptions" :> {}], + ImageSizeCache->{505., {210., 217.}}, + SingleEvaluation->True], + Deinitialization:>None, + DynamicModuleValues:>{}, + SynchronousInitialization->True, + UnsavedVariables:>{Typeset`initDone$$}, + UntrackedVariables:>{Typeset`size$$}], "Manipulate", + Deployed->True, + StripOnInput->False], + Manipulate`InterpretManipulate[1]]], "Output", + CellChangeTimes->{ + 3.563585357794471*^9},ExpressionUUID->"d020b703-cd93-4ce8-a656-\ +2dcfa0f3af53"] +}, Open ]], + +Cell["\<\ +Or the number of offspring produced by the entire population in the logistic \ +model:\ +\>", "Text", + CellChangeTimes->{{3.513948485746283*^9, + 3.5139485180034647`*^9}},ExpressionUUID->"876e3ed5-6e8d-47e0-9ca4-\ +743b1adaf708"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Manipulate", "[", + RowBox[{ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox["n", "K"]}], ")"}]}]}], ")"}], "*", "n"}], ",", + RowBox[{"{", + RowBox[{"n", ",", "0", ",", "250"}], "}"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{"Automatic", ",", + RowBox[{"{", + RowBox[{"0", ",", "200"}], "}"}]}], "}"}]}]}], "]"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"r", ",", "0.3"}], "}"}], ",", "0.01", ",", "0.5"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"K", ",", "100"}], "}"}], ",", "10", ",", "200"}], "}"}]}], + "]"}]], "Input", + CellChangeTimes->{{3.563585040878352*^9, 3.563585127124732*^9}, { + 3.563585248119401*^9, + 3.5635852635674353`*^9}},ExpressionUUID->"53e980f9-37f4-443f-9547-\ +0fb69514fecc"], + +Cell[BoxData[ + TagBox[ + StyleBox[ + DynamicModuleBox[{K$$ = 100, $CellContext`r$$ = 0.3, Typeset`show$$ = True, + Typeset`bookmarkList$$ = {}, Typeset`bookmarkMode$$ = "Menu", + Typeset`animator$$, Typeset`animvar$$ = 1, Typeset`name$$ = + "\"untitled\"", Typeset`specs$$ = {{{ + Hold[$CellContext`r$$], 0.3}, 0.01, 0.5}, {{ + Hold[K$$], 100}, 10, 200}}, Typeset`size$$ = {450., {142., 149.}}, + Typeset`update$$ = 0, Typeset`initDone$$, Typeset`skipInitDone$$ = + True, $CellContext`r$2751$$ = 0, K$2752$$ = 0}, + DynamicBox[Manipulate`ManipulateBoxes[ + 1, StandardForm, "Variables" :> {K$$ = 100, $CellContext`r$$ = 0.3}, + "ControllerVariables" :> { + Hold[$CellContext`r$$, $CellContext`r$2751$$, 0], + Hold[K$$, K$2752$$, 0]}, + "OtherVariables" :> { + Typeset`show$$, Typeset`bookmarkList$$, Typeset`bookmarkMode$$, + Typeset`animator$$, Typeset`animvar$$, Typeset`name$$, + Typeset`specs$$, Typeset`size$$, Typeset`update$$, Typeset`initDone$$, + Typeset`skipInitDone$$}, "Body" :> + Plot[(1 + $CellContext`r$$ (1 - $CellContext`n/ + K$$)) $CellContext`n, {$CellContext`n, 0, 250}, + PlotRange -> {Automatic, {0, 200}}], + "Specifications" :> {{{$CellContext`r$$, 0.3}, 0.01, 0.5}, {{K$$, 100}, + 10, 200}}, "Options" :> {}, "DefaultOptions" :> {}], + ImageSizeCache->{503., {212., 219.}}, + SingleEvaluation->True], + Deinitialization:>None, + DynamicModuleValues:>{}, + SynchronousInitialization->True, + UnsavedVariables:>{Typeset`initDone$$}, + UntrackedVariables:>{Typeset`size$$}], "Manipulate", + Deployed->True, + StripOnInput->False], + Manipulate`InterpretManipulate[1]]], "Output", + CellChangeTimes->{ + 3.56358535973024*^9},ExpressionUUID->"3c4c386e-d59c-4551-8218-3d4a996c1d25"] +}, Open ]], + +Cell[TextData[{ + "The real power of ", + StyleBox["Mathematica,", + FontSlant->"Italic"], + " however, is that it can handle commands involving variables and parameters \ +without having to specify their values.\n\nFor example, at what population \ +size do we see the largest total number of offspring produced in the logistic \ +model?" +}], "Text", + CellChangeTimes->{{3.513948159513774*^9, 3.5139481895673933`*^9}, { + 3.513948535766183*^9, 3.5139485481480093`*^9}, {3.513948581393544*^9, + 3.5139486416127234`*^9}},ExpressionUUID->"c10d2856-d7bf-4d90-bcb3-\ +ce0a55ad610f"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"D", "[", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox["n", "K"]}], ")"}]}]}], ")"}], "n"}], ",", "n"}], + "]"}]], "Input", + CellChangeTimes->{{3.513948648902672*^9, 3.513948654246675*^9}, { + 3.5139487005589743`*^9, + 3.513948705274877*^9}},ExpressionUUID->"922e013f-a8d9-42ec-9f0d-\ +9665f8e654c3"], + +Cell[BoxData[ + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", " ", "r"}], "K"], "+", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", + FractionBox["n", "K"]}], ")"}], " ", "r"}]}]], "Output", + CellChangeTimes->{3.513948706186695*^9, 3.513948789877553*^9, + 3.514678092499435*^9},ExpressionUUID->"9e704cf5-9e13-4825-9e03-\ +f24f3bacb049"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"%", "\[Equal]", "0"}], ",", "n"}], "]"}]], "Input", + CellChangeTimes->{{3.513948714912499*^9, 3.513948731598783*^9}, { + 3.5139487802271013`*^9, + 3.513948788486806*^9}},ExpressionUUID->"2cb5418e-d92d-43df-ab99-\ +85fbe81cc54f"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{"n", "\[Rule]", + FractionBox[ + RowBox[{"K", " ", + RowBox[{"(", + RowBox[{"1", "+", "r"}], ")"}]}], + RowBox[{"2", " ", "r"}]]}], "}"}], "}"}]], "Output", + CellChangeTimes->{{3.513948726944105*^9, 3.513948732196899*^9}, + 3.513948791781015*^9, + 3.5146780935709543`*^9},ExpressionUUID->"02e5c93b-0e82-4b7d-a031-\ +2e36790fe261"] +}, Open ]], + +Cell["This checks against the graph above", "Text", + CellChangeTimes->{{3.5146781248331137`*^9, + 3.514678129087179*^9}},ExpressionUUID->"a41ccc35-b5d5-4df5-b8c3-\ +8e5867aef1cf"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{ + RowBox[{"%", "/.", + RowBox[{"r", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"K", "\[Rule]", "100"}]}]], "Input", + CellChangeTimes->{{3.514678094377514*^9, + 3.514678101343503*^9}},ExpressionUUID->"1ff5ba50-aac4-4e63-b58b-\ +075ce8a614f0"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{"n", "\[Rule]", "216.66666666666669`"}], "}"}], "}"}]], "Output", + CellChangeTimes->{ + 3.514678101742447*^9},ExpressionUUID->"7ee70b82-bce6-40b1-8408-\ +656f1529801f"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Question 1: At what speed does an allele rise in frequency?", \ +"Subsubsection", + CellChangeTimes->{{3.51394814025489*^9, 3.513948145584239*^9}, { + 3.513948808098681*^9, 3.5139488496649723`*^9}, {3.5139491033219757`*^9, + 3.513949116352789*^9}},ExpressionUUID->"24309d09-0367-4b0b-ad2c-\ +754d2fef5c0e"], + +Cell[TextData[{ + "Using the continuous-time model, plot the rate of change ", + Cell[BoxData[ + RowBox[{"s", " ", "p", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"d9e45fc4-ccfb-41f1-89fa-dfc15ca6e3d7"], + "as a function of ", + Cell[BoxData["p"], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"1d762284-7bb1-40fd-9791-23074b04baab"], + " (between 0 and 1). Choose whatever numerical value of ", + Cell[BoxData["s"], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"4062ef97-f3cf-4fc0-8ed3-e3a12d5b15dc"], + " you wish." +}], "Text", + CellChangeTimes->{{3.513948852926982*^9, 3.5139488676243277`*^9}, { + 3.513949099585382*^9, 3.5139492404693527`*^9}, 3.513949389000252*^9, { + 3.51395287009256*^9, + 3.513952871211212*^9}},ExpressionUUID->"68fd811c-e53f-4b9b-a3c0-\ +1ad1c408144e"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Question 2: When is evolutionary change fastest?", "Subsubsection", + CellChangeTimes->{{3.51394814025489*^9, 3.513948145584239*^9}, { + 3.513948808098681*^9, 3.5139488496649723`*^9}, {3.5139491033219757`*^9, + 3.513949116352789*^9}, {3.513949233431561*^9, 3.5139492553327103`*^9}, { + 3.513954323615156*^9, + 3.513954325807782*^9}},ExpressionUUID->"57290fed-efd0-44d2-8889-\ +1127cb5522a3"], + +Cell[TextData[{ + "Again, using the continuous-time model, ", + Cell[BoxData[ + RowBox[{ + FractionBox["dp", "dt"], "=", + RowBox[{"s", " ", + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"c9e4581f-cc6f-4c80-aa92-41a68ee4411b"], + ", what value of ", + Cell[BoxData["p"], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"e51a1e25-1d0b-4329-9d4c-9dfee8ff8906"], + " maximizes the rate of allele frequency change? Use D[] to find this \ +result analytically, for any possible value of ", + Cell[BoxData["s"], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"d93f584a-eea4-403e-8000-1d7b94935624"], + ". " +}], "Text", + CellChangeTimes->{{3.513948852926982*^9, 3.5139488676243277`*^9}, { + 3.513949099585382*^9, 3.5139492193176947`*^9}, {3.513949257533883*^9, + 3.5139492748936996`*^9}, {3.513949321630436*^9, 3.513949394617585*^9}, { + 3.5139497524605*^9, 3.5139497575494204`*^9}, {3.514423008423018*^9, + 3.5144230126819553`*^9}},ExpressionUUID->"cff07c96-34d1-4f12-8a7d-\ +36bfa18dd4ca"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"D", "[", + RowBox[{ + RowBox[{"s", " ", "p", " ", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}], ",", "p"}], "]"}]], "Input", + CellChangeTimes->{{3.513948648902672*^9, 3.513948654246675*^9}, { + 3.5139487005589743`*^9, 3.513948705274877*^9}, {3.513949764880245*^9, + 3.513949768830206*^9}},ExpressionUUID->"e1a15929-f7cb-47fd-9710-\ +0566528aef82"], + +Cell[BoxData[ + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}], " ", "s"}], "-", + RowBox[{"p", " ", "s"}]}]], "Output", + CellChangeTimes->{ + 3.513948706186695*^9, 3.513948789877553*^9, {3.513949769288625*^9, + 3.513949775597183*^9}},ExpressionUUID->"89d412fb-4a6d-429c-9f82-\ +04b3ce12492f"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"%", "\[Equal]", "0"}], ",", "p"}], "]"}]], "Input", + CellChangeTimes->{{3.513948714912499*^9, 3.513948731598783*^9}, { + 3.5139487802271013`*^9, 3.513948788486806*^9}, + 3.5139497740316877`*^9},ExpressionUUID->"497361c6-a8e6-4820-b11d-\ +eba88b766705"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{"p", "\[Rule]", + FractionBox["1", "2"]}], "}"}], "}"}]], "Output", + CellChangeTimes->{{3.513948726944105*^9, 3.513948732196899*^9}, + 3.513948791781015*^9, {3.5139497716577682`*^9, + 3.513949776316489*^9}},ExpressionUUID->"ec300727-d5e6-41b2-bc23-\ +5a69ecbb736b"] +}, Open ]] +}, Open ]] +}, Closed]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Part 2: Equilibria and their stability", "Section", + CellChangeTimes->{{3.513947212490135*^9, 3.513947218035974*^9}, { + 3.5139498791123238`*^9, 3.513949882837112*^9}, {3.5139527893987713`*^9, + 3.513952819590952*^9}, {3.514165147827382*^9, + 3.514165180112595*^9}},ExpressionUUID->"e0554370-a9b3-4d8f-baf3-\ +5b8d86b4d15b"], + +Cell[CellGroupData[{ + +Cell["Equilibria", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, + 3.513952890146652*^9}},ExpressionUUID->"e8647bd2-c630-4afa-8af9-\ +25d300729b04"], + +Cell[TextData[{ + StyleBox["DEFINITION: ", + FontWeight->"Bold"], + " An ", + StyleBox["equilibrium", + FontColor->RGBColor[1, 0, 0]], + " is a special value of a variable such that if a system starts at that \ +value, it stays there.\n\n", + StyleBox["RECIPE: ", + FontWeight->"Bold"], + "We find equilibria by:\n\t* Setting the variable at one time and the next \ +(n[t + 1] and n[t]) to the same equilibrium value, ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]],ExpressionUUID-> + "053e8f6b-3e78-4ac3-9211-fecab125dba0"], + ",\t(Discrete-time model)\n\t* Setting the change in a variable (", + Cell[BoxData[ + FractionBox["dn", "dt"]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"9561dc4d-0161-4bd0-97c1-8cab46490ad0"], + ") to zero when started at ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]],ExpressionUUID-> + "ffec4ad6-d778-462b-a415-d0acf9176f09"], + ",\t\t\t\t\t(Continuous-time model)\nand then solving for the value(s) of ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]],ExpressionUUID-> + "629e9abb-fb2b-45fb-a192-acb997cc7a6f"], + " that satisfy the resulting equations." +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117310317294*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"59b3ff5b-28bd-474d-b760-08f76a51d0a4"], + +Cell[TextData[{ + "E.g., in the logistic model, if the population size at time t is ", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "=", + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"491a360a-c376-4652-979e-b772dfb34052"], + ", it will remain at this value only if ", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "=", + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"51d33198-c601-48bd-8e4b-1c506dd4146c"], + ", which gives us an equation that we can solve for ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"6557c9f9-d69e-48d3-bfec-645147beae4c"], + ", by replacing all instances of ", + Cell[BoxData["n"], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"f24c27ab-602f-47ea-a701-cf680537077e"], + " with", + Cell[BoxData[ + RowBox[{" ", + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"89ce920a-af0a-445e-b697-f2f4488e526b"], + " in ", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}]}]}], ")"}], + RowBox[{"n", "[", "t", "]"}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"17d72f4f-39da-489b-91f6-7dba16846bb3"], + "." +}], "Text", + CellChangeTimes->{{3.513953444457696*^9, 3.513953665480241*^9}, { + 3.513953828786998*^9, + 3.513953835425035*^9}},ExpressionUUID->"6dd72596-e66a-41c9-9d67-\ +b158c959ed83"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{ + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm], " ", "==", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm], "K"]}], ")"}]}]}], ")"}], + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}]}], ",", + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}], "]"}]], "Input", + CellChangeTimes->{{3.5139532622009068`*^9, + 3.513953273073205*^9}},ExpressionUUID->"55ea47c1-5afc-41eb-b248-\ +9498217e514d"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + OverscriptBox["n", "^"], "\[Rule]", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + OverscriptBox["n", "^"], "\[Rule]", "K"}], "}"}]}], "}"}]], "Output", + CellChangeTimes->{ + 3.5139532736592903`*^9},ExpressionUUID->"55adb479-7e78-49e9-8a8d-\ +86dfd097cbec"] +}, Open ]], + +Cell[TextData[{ + "NOTE: We use == instead of = here because we don't want to set ", + Cell[BoxData[ + RowBox[{ + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm], " "}]], + CellChangeTimes->{{3.5139532622009068`*^9, 3.513953273073205*^9}}, + ExpressionUUID->"a243bd2e-7c3e-47bb-adb3-c56bb89890d6"], + "equal to the right-hand side, we want TO TEST when the left and right will \ +be equal." +}], "Text", + CellChangeTimes->{{3.513953845501972*^9, + 3.513953878628409*^9}},ExpressionUUID->"ba06d15a-7139-4fa8-bd15-\ +dfc475594e2b"], + +Cell[TextData[{ + "Similarly, in continuous-time, we determine what value of ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"9fadcf11-14e0-48c8-b48c-4aae556affbb"], + " causes ", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + FractionBox["dn", "dt"], "=", " ", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}], " ", + RowBox[{"n", "[", "t", "]"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"e0966e9c-4a10-4919-bb62-bd2c4841de2c"], + " to equal zero:" +}], "Text", + CellChangeTimes->{{3.513953444457696*^9, 3.513953748754612*^9}, { + 3.513953787893159*^9, + 3.5139537887802153`*^9}},ExpressionUUID->"cc7094ca-48e3-4dfe-9a0e-\ +cad216f631f7"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"0", "==", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm], "K"]}], ")"}], + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}]}], ",", + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm]}], "]"}]], "Input", + CellChangeTimes->{{3.513953324623784*^9, + 3.5139533313577223`*^9}},ExpressionUUID->"e547c90a-d03f-48c6-b9a2-\ +d46d1811a9aa"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + OverscriptBox["n", "^"], "\[Rule]", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + OverscriptBox["n", "^"], "\[Rule]", "K"}], "}"}]}], "}"}]], "Output", + CellChangeTimes->{ + 3.513953331787663*^9},ExpressionUUID->"726504dd-f95a-4267-887e-\ +fa79d14c1b56"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["\<\ +Question 3: What are the equilibria for the haploid model of selection?\ +\>", "Subsubsection", + CellChangeTimes->{{3.51394814025489*^9, 3.513948145584239*^9}, { + 3.513948808098681*^9, 3.5139488496649723`*^9}, {3.5139491033219757`*^9, + 3.513949116352789*^9}, {3.5139539142255583`*^9, 3.513953950682358*^9}, { + 3.513954320569996*^9, + 3.513954332097341*^9}},ExpressionUUID->"19fcb08f-cef1-4f0b-851e-\ +204451f81b5f"], + +Cell[TextData[{ + "Find ", + Cell[BoxData[ + FormBox[ + OverscriptBox["p", "^"], TraditionalForm]],ExpressionUUID-> + "7ea80276-b739-4740-a0e6-669d4ba993d5"], + " for both the discrete-time and continuous-time models:\n\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + RowBox[{"p", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"51e5b352-cbd2-4d32-8b09-1c1cddd8033a"], + "\t\t\t\t\tDiscrete-time model\n\t\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dp", "dt"], "=", + RowBox[{ + RowBox[{ + SuperscriptBox["p", "\[Prime]", + MultilineFunction->None], "[", "t", "]"}], "=", + RowBox[{"s", " ", + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"a125e7cf-2873-4fbb-8374-bb936aa88e27"], + "\t\t\t\t\tContinuous-time model\n\t\nFirst, use ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " to solve for ", + Cell[BoxData[ + FormBox[ + OverscriptBox["p", "^"], TraditionalForm]],ExpressionUUID-> + "8168f011-3083-48f2-bd3e-1057c08cc9c6"], + " analytically.\nSecond, carry out the calculations by hand." +}], "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.5139475325082417`*^9, 3.51394758040838*^9}, {3.5139476417549477`*^9, + 3.513947714905636*^9}, {3.513947913524728*^9, 3.513947982531314*^9}, { + 3.513948017290382*^9, 3.513948113203456*^9}, {3.51394894565186*^9, + 3.513949092099876*^9}, {3.513953965380247*^9, 3.513954016760906*^9}, { + 3.513954339220845*^9, 3.513954345520956*^9}, {3.513954414894065*^9, + 3.513954469204207*^9}},ExpressionUUID->"20346cdb-2405-4e8d-b6dc-\ +5218420720b2"], + +Cell["For the recursion equation:", "Text", + CellChangeTimes->{{3.514678389973181*^9, + 3.5146783931705723`*^9}},ExpressionUUID->"f892946f-f291-4fd1-ab51-\ +7c3843c79c47"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{ + OverscriptBox["p", "^"], "==", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + OverscriptBox["p", "^"]}], + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + OverscriptBox["p", "^"]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + OverscriptBox["p", "^"]}], ")"}]}]]}], ",", + OverscriptBox["p", "^"]}], "]"}]], "Input", + CellChangeTimes->{{3.51467815481676*^9, + 3.51467818842894*^9}},ExpressionUUID->"6ac1835c-89b6-405d-a6a5-\ +d408611ffe6b"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + OverscriptBox["p", "^"], "\[Rule]", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + OverscriptBox["p", "^"], "\[Rule]", "1"}], "}"}]}], "}"}]], "Output", + CellChangeTimes->{{3.5146781786748343`*^9, + 3.514678189453238*^9}},ExpressionUUID->"3a121993-a18a-4b8c-869b-\ +d5cd5e1c4544"] +}, Open ]], + +Cell[TextData[{ + "By hand:\n\t", + Cell[BoxData[ + RowBox[{ + OverscriptBox["p", "^"], "==", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + OverscriptBox["p", "^"]}], + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + OverscriptBox["p", "^"]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + OverscriptBox["p", "^"]}], ")"}]}]]}]], + CellChangeTimes->{{3.51467815481676*^9, 3.51467818842894*^9}}, + ExpressionUUID->"b45b761e-196f-4b03-8ef3-e676540c3b59"], + "\t\tDivide both sides by ", + Cell[BoxData[ + OverscriptBox["p", "^"]], + CellChangeTimes->{{3.51467815481676*^9, 3.51467818842894*^9}}, + ExpressionUUID->"00feb9b2-0b54-42f7-a8b7-d88762d26713"], + ", noting when you do that this factor can be set to zero to give an \ +equilibrium at ", + Cell[BoxData[ + OverscriptBox["p", "^"]], + CellChangeTimes->{{3.51467815481676*^9, 3.51467818842894*^9}}, + ExpressionUUID->"f58efabb-b975-418b-888e-12c2b95bde11"], + "=0\n\t", + Cell[BoxData[ + RowBox[{"1", "==", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], "1"}], + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + OverscriptBox["p", "^"]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + OverscriptBox["p", "^"]}], ")"}]}]]}]], + CellChangeTimes->{{3.51467815481676*^9, 3.51467818842894*^9}}, + ExpressionUUID->"658fd100-b449-4917-afcb-c12dfdb80a3f"], + "\t\tMultiply out the denominator\n\t", + Cell[BoxData[ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + OverscriptBox["p", "^"]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + OverscriptBox["p", "^"]}], ")"}]}], "==", + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}]}]], + CellChangeTimes->{{3.51467815481676*^9, 3.51467818842894*^9}}, + ExpressionUUID->"3dd8848f-5264-492a-8334-6eccb18915fe"], + "\t\tExpand and cancel terms\n\t", + Cell[BoxData[ + RowBox[{ + RowBox[{"s", " ", + OverscriptBox["p", "^"]}], "==", "s"}]], + CellChangeTimes->{{3.51467815481676*^9, 3.51467818842894*^9}}, + ExpressionUUID->"88a1ab74-bf81-4a7c-a8b0-7e1220c56484"], + "\t\t\tDivide through by s to find another equilibrium at ", + Cell[BoxData[ + OverscriptBox["p", "^"]], + CellChangeTimes->{{3.51467815481676*^9, 3.51467818842894*^9}}, + ExpressionUUID->"bd84ad6a-0d6a-4747-a2b9-ca1c150e123f"], + "=0" +}], "Text", + CellChangeTimes->{{3.514678196065436*^9, + 3.514678366778347*^9}},ExpressionUUID->"699fd76b-b65c-43a8-9271-\ +f6d9479b7b5e"], + +Cell["For the differential equation:", "Text", + CellChangeTimes->{{3.51467839583323*^9, + 3.514678400290979*^9}},ExpressionUUID->"a9c07be6-763e-4eb9-90a4-\ +daf30288e223"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{ + RowBox[{"s", " ", + OverscriptBox["p", "^"], + RowBox[{"(", + RowBox[{"1", "-", + OverscriptBox["p", "^"]}], ")"}]}], "\[Equal]", "0"}], ",", + OverscriptBox["p", "^"]}], "]"}]], "Input", + CellChangeTimes->{{3.5146783773331547`*^9, + 3.514678386287592*^9}},ExpressionUUID->"e18b4d29-b842-47cf-8b4a-\ +c74a3f3bcaf1"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + OverscriptBox["p", "^"], "\[Rule]", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + OverscriptBox["p", "^"], "\[Rule]", "1"}], "}"}]}], "}"}]], "Output", + CellChangeTimes->{ + 3.514678386918898*^9},ExpressionUUID->"65fabd40-9f07-4d87-ba1d-\ +1c7e58864d68"] +}, Open ]], + +Cell[TextData[{ + "By hand:\n\t", + Cell[BoxData[ + RowBox[{ + RowBox[{"s", " ", + OverscriptBox["p", "^"], + RowBox[{"(", + RowBox[{"1", "-", + OverscriptBox["p", "^"]}], ")"}]}], "\[Equal]", "0"}]], + CellChangeTimes->{{3.5146783773331547`*^9, 3.514678386287592*^9}}, + ExpressionUUID->"0ba3c115-798e-4c6a-a9bc-b1755e807a27"], + "\t\tAs this equation is already factored, there are three ways for it to be \ +solved. \n\t\t\t\t\t(a) s = 0, which is not an equilibrium but a special case \ +of the parameters.\n\t\t\t\t\t(b) ", + Cell[BoxData[ + RowBox[{ + OverscriptBox["p", "^"], "=", "0"}]], + CellChangeTimes->{{3.51467815481676*^9, 3.51467818842894*^9}}, + ExpressionUUID->"b24d9f66-296a-4362-adc4-4d7853107ad2"], + ", an equilibrium\n\t\t\t\t\t(c) ", + Cell[BoxData[ + RowBox[{ + OverscriptBox["p", "^"], "=", "1"}]], + CellChangeTimes->{{3.51467815481676*^9, 3.51467818842894*^9}}, + ExpressionUUID->"afcc7d27-9582-4c7a-bef6-61a9212cd120"], + ", another equilibrium" +}], "Text", + CellChangeTimes->{{3.514678196065436*^9, 3.514678366778347*^9}, { + 3.514678412199419*^9, + 3.514678484004119*^9}},ExpressionUUID->"0658489f-4ac3-4f87-9733-\ +58612ac4f32a"] +}, Open ]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Stability", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.51395448884634*^9, + 3.513954489788062*^9}},ExpressionUUID->"e2a372cb-28a5-4c1c-8dbc-\ +d7b6868d9c8b"], + +Cell["\<\ +A system may or may not move toward a particular equilibrium.\ +\>", "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.513954558138726*^9, + 3.513954567740512*^9}, {3.513954646641127*^9, 3.513954959224346*^9}, { + 3.51395503435863*^9, 3.513955036549271*^9}, {3.513955808112068*^9, + 3.513955827145928*^9}, {3.5139562760990334`*^9, 3.513956403467185*^9}, { + 3.5139565012215347`*^9, 3.513956531165784*^9}, 3.513956573839028*^9, { + 3.513956783731927*^9, 3.5139568012276773`*^9}, {3.514116820097149*^9, + 3.5141168314840097`*^9}, {3.514116935475194*^9, 3.5141169358821573`*^9}, { + 3.5141174296927032`*^9, + 3.514117449201955*^9}},ExpressionUUID->"6d87ee01-7b2a-4c67-9f96-\ +7167fd83e3b6"], + +Cell[TextData[{ + StyleBox["DEFINITION: ", + FontWeight->"Bold"], + " An equilibrium is ", + StyleBox["locally stable", + FontColor->RGBColor[1, 0, 0]], + " if a system near the equilibrium approaches it (attracting). An \ +equilibrium is ", + StyleBox["unstable", + FontColor->RGBColor[1, 0, 0]], + " if a system near the equilibrium moves away from it (repelling). " +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117377492393*^9}, { + 3.5141174250611267`*^9, 3.5141174260424957`*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"85774559-e169-45fc-9e68-278f0e4398ef"], + +Cell[TextData[{ + "A ", + StyleBox["local stability analysis", + FontColor->RGBColor[1, 0, 0]], + " determines whether a system that starts near an equilibrium moves toward \ +(stable) or away from it (unstable).\n\n", + StyleBox["The idea: ", + FontWeight->"Bold"], + " We approximate the dynamics of a model near an equilibrium and then \ +determine how it moves. To do so, we use an incredibly useful approximation \ +tool: the ", + StyleBox["Taylor Series", + FontColor->RGBColor[1, 0, 0]], + "." +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.513954558138726*^9, + 3.513954567740512*^9}, {3.513954646641127*^9, 3.513954959224346*^9}, { + 3.51395503435863*^9, 3.513955036549271*^9}, {3.513955808112068*^9, + 3.513955827145928*^9}, {3.5139562760990334`*^9, 3.513956403467185*^9}, { + 3.5139565012215347`*^9, 3.513956531165784*^9}, 3.513956573839028*^9, { + 3.513956783731927*^9, 3.5139568012276773`*^9}, {3.514116820097149*^9, + 3.5141168314840097`*^9}, {3.514116935475194*^9, 3.5141169358821573`*^9}, { + 3.514117452739401*^9, + 3.514117453475349*^9}},ExpressionUUID->"d1b1de43-3816-4c63-93de-\ +5975d0d80112"], + +Cell[TextData[{ + StyleBox["Taylor series: ", + FontWeight->"Bold"], + " For any nicely behaved function, f, of a variable, x[t], we can write the \ +function around ", + Cell[BoxData[ + FormBox[ + OverscriptBox["x", "^"], TraditionalForm]],ExpressionUUID-> + "5786dc20-a73f-481e-a5cd-7a87907c92a4"], + " as a series of terms, ", + Cell[BoxData[ + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}], "i"]], + CellChangeTimes->{3.513956480106298*^9},ExpressionUUID-> + "5436459b-dede-402d-a344-7b59b1e73334"], + ":" +}], "Text", + CellChangeTimes->{{3.514116887206808*^9, 3.5141168895317717`*^9}, + 3.5141174643724527`*^9}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"c64cdd2a-ad16-461a-9a59-626d15cb90a8"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Series", "[", + RowBox[{ + RowBox[{"f", "[", + RowBox[{"x", "[", "t", "]"}], "]"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], ",", + FormBox[ + OverscriptBox["x", "^"], + TraditionalForm], ",", "4"}], " ", "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5139564742034597`*^9, 3.513956478521184*^9}, + 3.513956539263496*^9, {3.513956806733952*^9, 3.513956817279278*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"a311f301-be2d-45f8-bcb2-e675016090b3"], + +Cell[BoxData[ + InterpretationBox[ + RowBox[{ + RowBox[{"f", "[", + OverscriptBox["x", "^"], "]"}], "+", + RowBox[{ + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["x", "^"], "]"}], " ", + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}]}], "+", + RowBox[{ + FractionBox["1", "2"], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["x", "^"], "]"}], " ", + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}], "2"]}], "+", + RowBox[{ + FractionBox["1", "6"], " ", + RowBox[{ + SuperscriptBox["f", + TagBox[ + RowBox[{"(", "3", ")"}], + Derivative], + MultilineFunction->None], "[", + OverscriptBox["x", "^"], "]"}], " ", + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}], "3"]}], "+", + RowBox[{ + FractionBox["1", "24"], " ", + RowBox[{ + SuperscriptBox["f", + TagBox[ + RowBox[{"(", "4", ")"}], + Derivative], + MultilineFunction->None], "[", + OverscriptBox["x", "^"], "]"}], " ", + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}], "4"]}], "+", + InterpretationBox[ + SuperscriptBox[ + RowBox[{"O", "[", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], "]"}], "5"], + SeriesData[ + $CellContext`x[$CellContext`t], + OverHat[$CellContext`x], {}, 0, 5, 1], + Editable->False]}], + SeriesData[ + $CellContext`x[$CellContext`t], + OverHat[$CellContext`x], { + $CellContext`f[ + OverHat[$CellContext`x]], + Derivative[1][$CellContext`f][ + OverHat[$CellContext`x]], Rational[1, 2] Derivative[2][$CellContext`f][ + OverHat[$CellContext`x]], Rational[1, 6] Derivative[3][$CellContext`f][ + OverHat[$CellContext`x]], Rational[1, 24] + Derivative[4][$CellContext`f][ + OverHat[$CellContext`x]]}, 0, 5, 1], + Editable->False]], "Output", + CellChangeTimes->{ + 3.513956480106298*^9, 3.51395653974072*^9, {3.513956807103202*^9, + 3.513956817500697*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"d6b5dc83-38e5-490e-a8fd-68b50013d7f3"] +}, Open ]], + +Cell["\<\ +For example, Sin[x] can be rewritten as the following function around the \ +point 1/2:\ +\>", "Text", + CellChangeTimes->{{3.513956684327486*^9, 3.513956690461039*^9}, { + 3.513956834878943*^9, 3.513956849921122*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"5bd3f20b-dd2d-4e92-a445-f9c76a5c92ba"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Series", "[", + RowBox[{ + RowBox[{"Sin", "[", "x", "]"}], ",", + RowBox[{"{", + RowBox[{"x", ",", + RowBox[{"1", "/", "2"}], ",", "4"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{ + 3.513956695872752*^9, 3.5139568287948*^9, {3.5141168469483747`*^9, + 3.514116850046146*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"cb1d7f5f-565d-4256-b898-8c51a434c309"], + +Cell[BoxData[ + InterpretationBox[ + RowBox[{ + RowBox[{"Sin", "[", + FractionBox["1", "2"], "]"}], "+", + RowBox[{ + RowBox[{"Cos", "[", + FractionBox["1", "2"], "]"}], " ", + RowBox[{"(", + RowBox[{"x", "-", + FractionBox["1", "2"]}], ")"}]}], "-", + RowBox[{ + FractionBox["1", "2"], " ", + RowBox[{"Sin", "[", + FractionBox["1", "2"], "]"}], " ", + SuperscriptBox[ + RowBox[{"(", + RowBox[{"x", "-", + FractionBox["1", "2"]}], ")"}], "2"]}], "-", + RowBox[{ + FractionBox["1", "6"], " ", + RowBox[{"Cos", "[", + FractionBox["1", "2"], "]"}], " ", + SuperscriptBox[ + RowBox[{"(", + RowBox[{"x", "-", + FractionBox["1", "2"]}], ")"}], "3"]}], "+", + RowBox[{ + FractionBox["1", "24"], " ", + RowBox[{"Sin", "[", + FractionBox["1", "2"], "]"}], " ", + SuperscriptBox[ + RowBox[{"(", + RowBox[{"x", "-", + FractionBox["1", "2"]}], ")"}], "4"]}], "+", + InterpretationBox[ + SuperscriptBox[ + RowBox[{"O", "[", + RowBox[{"x", "-", + FractionBox["1", "2"]}], "]"}], "5"], + SeriesData[$CellContext`x, + Rational[1, 2], {}, 0, 5, 1], + Editable->False]}], + SeriesData[$CellContext`x, + Rational[1, 2], { + Sin[ + Rational[1, 2]], + Cos[ + Rational[1, 2]], Rational[-1, 2] Sin[ + Rational[1, 2]], Rational[-1, 6] Cos[ + Rational[1, 2]], Rational[1, 24] Sin[ + Rational[1, 2]]}, 0, 5, 1], + Editable->False]], "Output", + CellChangeTimes->{{3.513956692740815*^9, 3.51395669604552*^9}, + 3.513956829383613*^9, {3.514116847884625*^9, 3.514116850327593*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"aea1312f-55f3-41f4-a4c2-5d7d6cb0a9c8"] +}, Open ]], + +Cell[TextData[{ + "If we are close enough to the point of interest, then ", + Cell[BoxData[ + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}], "i"]], + CellChangeTimes->{3.513956480106298*^9},ExpressionUUID-> + "540c8cde-9ba6-48da-ad4a-534953bce5b8"], + " will be small, and we can drop terms that we consider to be negligible.\n\n\ +Constant approximation (drops ", + Cell[BoxData[ + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}], "i"]], + CellChangeTimes->{3.513956480106298*^9},ExpressionUUID-> + "4eeabfad-edd0-4334-99f4-edc23813bb86"], + " for i > 0):" +}], "Text", + CellChangeTimes->{{3.5139565789357862`*^9, 3.513956637482334*^9}, { + 3.513956711646802*^9, 3.513956776923006*^9}, {3.513956862553155*^9, + 3.513956940432847*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"a7b26b4f-bb00-4086-ae61-f139786379d6"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"const", "=", + RowBox[{"Normal", "[", + RowBox[{"Series", "[", + RowBox[{ + RowBox[{"Sin", "[", "x", "]"}], ",", + RowBox[{"{", + RowBox[{"x", ",", + RowBox[{"1", "/", "2"}], ",", "0"}], "}"}]}], "]"}], "]"}]}]], "Input",\ + + CellChangeTimes->{ + 3.513956604309889*^9, {3.51395663986055*^9, 3.513956645179866*^9}, { + 3.513956988009224*^9, 3.513956988657848*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"2e1cb6cc-c27f-49c3-ac84-deb74f07e6ee"], + +Cell[BoxData[ + RowBox[{"Sin", "[", + FractionBox["1", "2"], "]"}]], "Output", + CellChangeTimes->{ + 3.513956604781479*^9, {3.513956640323092*^9, 3.5139566482334433`*^9}, + 3.5139569891664333`*^9}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"eb05b389-4adb-412c-a490-2e41352af3c4"] +}, Open ]], + +Cell[TextData[{ + "Linear approximation (drops ", + Cell[BoxData[ + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}], "i"]], + CellChangeTimes->{3.513956480106298*^9},ExpressionUUID-> + "9ff31442-24aa-4644-84a5-fcbd9b46de03"], + " for i > 1):" +}], "Text", + CellChangeTimes->{{3.5139565789357862`*^9, 3.5139566583618107`*^9}, { + 3.51395694691525*^9, 3.513956949849147*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"6b45ad0e-00b1-4d1d-ac77-1a35d800e88a"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"lin", "=", + RowBox[{"Normal", "[", + RowBox[{"Series", "[", + RowBox[{ + RowBox[{"Sin", "[", "x", "]"}], ",", + RowBox[{"{", + RowBox[{"x", ",", + RowBox[{"1", "/", "2"}], ",", "1"}], "}"}]}], "]"}], "]"}]}]], "Input",\ + + CellChangeTimes->{ + 3.513956604309889*^9, {3.51395663986055*^9, 3.513956662387927*^9}, { + 3.51395698248169*^9, 3.513956983793758*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"8e980d3a-5d73-464f-a23b-33e04e2ac57b"], + +Cell[BoxData[ + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"-", + FractionBox["1", "2"]}], "+", "x"}], ")"}], " ", + RowBox[{"Cos", "[", + FractionBox["1", "2"], "]"}]}], "+", + RowBox[{"Sin", "[", + FractionBox["1", "2"], "]"}]}]], "Output", + CellChangeTimes->{ + 3.513956604781479*^9, {3.513956640323092*^9, 3.513956662659687*^9}, + 3.51395695160455*^9, 3.513956984125071*^9}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"0c5f7d4e-28bf-448e-8d57-7edd7272c104"] +}, Open ]], + +Cell[TextData[{ + "Quadratic approximation (drops ", + Cell[BoxData[ + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"x", "[", "t", "]"}], "-", + OverscriptBox["x", "^"]}], ")"}], "i"]], + CellChangeTimes->{3.513956480106298*^9},ExpressionUUID-> + "8cb05689-a2ce-44df-a808-bd7f06139070"], + " for i > 2):" +}], "Text", + CellChangeTimes->{{3.5139565789357862`*^9, 3.5139566583618107`*^9}, { + 3.51395694691525*^9, 3.51395696674475*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"a60afced-54a0-4afe-a512-37eeea8c29ac"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"quad", "=", + RowBox[{"Normal", "[", + RowBox[{"Series", "[", + RowBox[{ + RowBox[{"Sin", "[", "x", "]"}], ",", + RowBox[{"{", + RowBox[{"x", ",", + RowBox[{"1", "/", "2"}], ",", "2"}], "}"}]}], "]"}], "]"}]}]], "Input",\ + + CellChangeTimes->{ + 3.513956604309889*^9, {3.51395663986055*^9, 3.513956662387927*^9}, { + 3.513956967929291*^9, 3.513956980025131*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"4af9e3c0-25a6-42e3-afd2-8615b434d799"], + +Cell[BoxData[ + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"-", + FractionBox["1", "2"]}], "+", "x"}], ")"}], " ", + RowBox[{"Cos", "[", + FractionBox["1", "2"], "]"}]}], "+", + RowBox[{"Sin", "[", + FractionBox["1", "2"], "]"}], "-", + RowBox[{ + FractionBox["1", "2"], " ", + SuperscriptBox[ + RowBox[{"(", + RowBox[{ + RowBox[{"-", + FractionBox["1", "2"]}], "+", "x"}], ")"}], "2"], " ", + RowBox[{"Sin", "[", + FractionBox["1", "2"], "]"}]}]}]], "Output", + CellChangeTimes->{ + 3.513956604781479*^9, {3.513956640323092*^9, 3.513956662659687*^9}, { + 3.51395695160455*^9, 3.513956985992507*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"92b19e0a-ddd9-42ef-9804-6c880b2d88a2"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"Sin", "[", "x", "]"}], ",", "const", ",", "lin", ",", " ", + "quad"}], "}"}], ",", + RowBox[{"{", + RowBox[{"x", ",", "0", ",", "Pi"}], "}"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{"Automatic", ",", + RowBox[{"{", + RowBox[{"0", ",", "1"}], "}"}]}], "}"}]}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Automatic", ",", + RowBox[{"Dashing", "[", "0.1", "]"}], ",", + RowBox[{"Dashing", "[", "0.04", "]"}], ",", + RowBox[{"Dashing", "[", "0.01", "]"}]}], "}"}]}]}], "]"}]], "Input", + CellChangeTimes->{{3.513955887387858*^9, 3.513955998091051*^9}, { + 3.5139569938743477`*^9, 3.5139571060317707`*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"f900e2ca-9f25-46c8-9357-fd0d20e14373"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {Hue[0.67, 0.6, 0.6], LineBox[CompressedData[" +1:eJwt2Hk4lF3cB3BUtlIJRVHSJilbka3v8FSKslVaLKEUUrZCT0qLlBbZkhYU +WSqShPIgRFGSQkkpZI+5LWPmvmcs73nf6/3rd32ua+Y69zn373zPmVns6m3r +JiIkJDRVWEjof+uU15K1f9b5bhD6/7qst8RwYYwVzi+o7FUilf9M4+D36P1Q +/mWt2ERqp6w7nR/tjWuF4005pDZvDi1PjQ7BTcfJjVGkNu6PXpEQfQNtCUNa +FqTaeik0x0cnYdru+WI2UUmIGnbIjYvORjTM4wOvZ8Ow0lzS1L8U3Lxb5ZmH +S+Hzr6VLrk8VeDe+3yo1r8LRl24RIkvqMFxeN1TG/oSGnq0S6a4NGLqylNMs +2YArGlyh/L1NaF2ma+xW8Q2+q6pulqb+xOu4bF+L3B/gHzjytOVYK6xabHdU ++vyGa7GddeShdiS/OHnQ8HAbDgw1lJZe7kDwbAufPSv+4JpmgXdaWBe+j9w6 +PTO/AyKlBXqh//ags/mEntDKLkirWdT+ju8DW30G71pKN7YkmaYMRvdjfJay +1Z/+HsyjajaHFLAxyGYd2aPbhzvvCoWneAxC5OWZfZcc/sJIyWRS+eAQvv18 +oPNwRz9Wtc7uOH18GJxH+okNrAFYdiuXBwQN49HO67IzNg7Ah6153zt4GG32 +ysUmZgN4MWbt4BI6jPUzDB6mbx+AkUJUw8bYYdDTXlU47hvANlvpyukvhrH0 +7Kol/v4D8KqQTrs9Mozb/YPjrIcDyMqY457nNwKj8pJqJyE2Qhtfm0wJHAHT +JmPuMIUNB5GjC2xOjeDSCffE3aJsSDq8q+2/MIIcdZ1ysxlsHJoVvG7pzRHc +nG85KCXPhnJAp0hMwQg69eQLtDTYiP3nZYLP2AgeyumfarRnI/iXY/2qMA4M +RYoqzj9lg2NmnOB2hQPZRHHrnmdseOUoHk6K4CAsaWuBRS4b9qE/+HNucXDW +dUJ+xks2DNT2qvDTOaC0opf6l7HBnNjpW1XNwcm2Zr3mejYCpCxmuUmNYizp +uvZ0HhvsALXvidKjMLPM7F/FkOdtlUhpkhuFB/PitLmADbvcKt1tC0eRKTmw +5NwkG+v2bnbS0RjFwr6W4AYxCpyHJlnCNqMo7PZmychT8DVab5EYOwrVR09l +BnUpCB2LDbkRP4rlGaVRT9ZTiEgazD17bxQ7X95TczOg8FjkkeKBh6PYzjbL +/GJMob1Kgb3ixShsbC70x22ksHOXIDKnfhSPC3O3VthQ0D1W8rViDhd5/npv +czwpVCTNn54/l4uPF74e0fSiYPs5AOnzuTgwvnBl1lEKx9ZqZISrcOH/1arv +vg+FdH7SSUttLtI35IT6BlCQv3ROscmGi1j9xmkF5yjwkza6/o3k4uD4h+Qv +cRQ28IyjtW5ysXbVqJRGPIVzlnrlgbe5kFCn9MJvUxAfX6kyNZkLO6GRd7r3 +KMjtm9WumMtFk0dkY8ADCpqyzS6WjVzE6TlGX3lCwf9IfVTsdy4GPPf+Ls+k +kF9eU9bcwoV42NNeOouCse/rxYe7uPirOF3X6RkF89qHbSE8LtSC1J9I5VFw +u+ztkqPAw4/6a5zJYgoZv92jeEo8JPTMkZJ9TaFf17XMWIWHNxtT2paVUvDr +3Ln4vRoPRV9iS0zLKZw1NWhrN+RByjp5k8tbCnfGprrIOvHwU2JFkFYthTqf +O86ByTwcWLN3VOknBbXI2YLjacTq6yZ/EF/IDrvp95iH1YmpUvEt5H2w/d4f +fc7DHi259ZK/KSQcsVh7sJyHTAuq7GsbBc9DY2I27Tyo36OTZneT93XRL9my +i4d+uc6Bp8RKqT1G2/p4aEx5BYseMv6fBl+zYR5m6nLYp3sp6Llk/TAWodGd +m/bvh78Upjo4Zaup0LhavxRigxScTjVsVV1Og1e75d1F4oI75h3L1GgYza+y +FRki43/XVVisTcO5/JX/KPFnu1kX5pnS8NaJ//lmhMwv4KKS3GYa8Y8rzmhz +KITeFBTMMadxoV96aRLx+obufilbGoHdI4F+oxQSbUrtprrSSN+svFGYR4H2 +0R0SPkRjwZt7E/uJbSMzr0560FjjLVZURDztU3wp35eGmWskfGgKXtt81YbO +0fiH+9X9NUPh7ZHuCvZFGrI71Qxm8iksuuq4vz+cxmItk5n2xF+qt8Z2R9G4 +45lWwibWN1OZaHlAxm+ow4SAwtqU95ffpdI4XeNNGY5RWDPpJ5PziMaK/DN5 +gcQqBW9UQ3NoPNH8FdpLrCjjlXs0j0bkyIqIReMU5nrLbtj9iob9jIasHcTT +V7jtUCujUdS5WTOfWPSC1C+ZShpXysViOoiFfue5j1fReLF60QzpCbL/40TP +1NXRiF5pZnKQmD38VLywgUZBqe34FeIey90xKU005EYef8ombhHNyAhopeEV +tL5ghLjJ1VrHuYPGrCKPmjmTZL4ldPHWHhobgn/zNIhr5j/YotNP4zz/lr4F +8duArfWKg2Q+N6OiDhKXfhlyFOXQ+Fz9fvIUceGaOz0Uj8YOTdPQKOIXV0z9 +vwto/AjhLkwlzu7qGy+fpLHnWtenfOLHpjGXM6cwEDGTvvWW+GGioUycGAOH +khPHG4gT+X8SQqYzWL1Qxr2VON7umqrHLAZXsnt8+4ijn6/NtZVh8L5pNGqY ++NrMFmOjeQxilAyqaOIwz4tVyxYw+LQwT3ac+Nzb1TtmLWKQe+dQ4CRxsMrX +FlqFQaGX5eD/OuDMGff25Qwyr3uFTBD7NC8f+aDGIE6mbKmA2FP30+m8NQxq +tba1jhIfjA4UT9JmMLJ+5nM2sRN7UcxlXQZUnNidTuI95lVKfgYMhr6uj28m +3pHmk2G/gYHfg+TMj8SWIgo6m0wZ6BRt+lZCvMWprHjNZgaQXCL/lNi00GOL +vDmD3quG3neJjebOqRe2ZFDtFPkzjFjXr9Dxrw2DymIVZx9izVrXnoZdDESF +Ocxu4mVhuePpjgy8V+z1WUys3G5/OcqFwa7tg9umEM/fMFXmlBuDiZ81+EP6 +YSZ3p6rlUQZqwk7uCcTituPP9XwZPCqfmxhILPI01XjxCQYdZkp9VsQ8N64t +J5ist75SJZ/053BZYkvLWQbGxQt2fiTuVzJzfxfKYKaOH5NA3Np46/Sdawzu +umlf0ieu3qSfwbrHgHa2y95L9kfQuzNrQu4zuOHjkzuPWHVrxYvih2Q9uS6B +9WS/hW2zKjPIYqBR+WvDRuKNO9ya15Yw+O/zpxpJsj85DY+d/csZdHWurcsn ++zvFbrAr5y0D2a33YpyJRfadGlnziUGB55V9WSQPSp2jZqxsZWAydqt3FckL +n/av0Yc7GHC3lw9UckkeHFRUSOthUNOz5Lkj8ZnD6cuWDDF4G/T4VBjJI6Nj +xRuURPiQ231vTjHJs4JTvT7SS/m4mGC7u4SicGh8Dc9KlY/lxoWua4nnhhw/ +HaHOR9+ptjUZbArHz0+GT19HPn8iTiJ8gIJ2uFzKtM18jIe/rNYgefs0zqSR +OcyH+MUdZ6S7SH/JX7Jf78WH4HjWnQOdFKTu1LQF+PCxsiEwKLeD5FvCbvZI +EB/v794I2vaH5OvDo2LscD46tmheO9BKITXntn77Ez6en2yfsbyZ9LPAXq0p +m4/q4432rt9J/2xauKA2l3z/k2rBvSYKRU3JY6/+40NMd3HM9G8U6iefvI76 +wMdf99y2z/UUhC1LNpn85aNqLK5D6CMFx752m/tqAqwUOtrWQ85HlbWppnFr +BDj0WedrVxHJo9OHda5pCzD+WeF7+39k/tL9skEGAjzTvyDR+IrC1fWj36zM +BThrEDU3mZy3r8LEnCY9BBC8VRv8Rc5ruSXqnk6PBDC7qqDYQc7/yOirdo+y +BNAwUZUMJ/cDSZG/ppwcAXwDJnNW3SJ52fZowZVCAZwXeml4xpJ+TFzxMe+D +AC+rxTs+RJDzcP4STSm2AOLK6hYqF8jzzJnP/U97DEoqMXULyP2GOneyXVRv +DJJ07Kogd7JeQ021NoZjMJrS+M+XQxSc626ld/8zhg6H8MyQAxS2Rcjtldk1 +hqM5i1xfO1BYIild5Bk4hnszfE5+sST5Kix+XqFoDHrvI4y2aJG8zrrtZF06 +Bua/tGA3DQoS+1YZXqoYg1Zle/TZ1RRYzy05nJoxWDduN322kvSD681DdS1j +2GuX/mx0MVmvNyoWlybHsE7+Qa/8HLIfLhrLjpqOY772rrdlg2zkifun1VWP +4/p+1onUdDa6gs8NlHwcxxeJWNUDqWzID91Ym/V5HAGdB0UWpZD77/fM8vDv +42h3kFSLSmRj4+OuX6a94xAqxfb9N9n4YrFvXp74BGrirouknCe/GyJMLt82 +m8DLFjvVanJ/Vpeb7elaOQFtqqIwXpwNKoIrq/N1EgaVqysdDQew5NIlDW9P +IVathvWhz479aN/3o9m0W4g1bTJ/wQGPv9jSWc/kHRNmeVABJi9M+xDk5+Y+ +d0CYVZN3+ri+XC8s8++azw0QYXGEhFManneDPeYZPIUrwrpgdsRov1UXHnw7 +9+KY/xTWrs1WvRtaOsB3N3Y+KZjC0tqv3K6+7g+UxqPsff+dygq9S/e8u9mG +LrOr78WnTmN1WnXlW539jTfLa7Dw6jTWVN1/P5aV/4CneNrUxRKirBavP8FR +K5tQcH+p8ZsoUZb8gs73LqoNqDU0qrSVFmOlFjnGH7erA+15d4dzhBhrX8Oi +Xt6salRZJ+2SmivOiszxV8x4XgpXfaP09Fhx1mdeN/9XWg6Sm057tSlJsN7m +ObkkHnaGehi/fojYIHpZoNByZ+TrBBqKLJRgyUrbKFRW7ceHCB/JJcRPFGuP +bi93AmfjgYyDxKdCqmc75Tlgc86Wjm7ib8syWCF396AvXMaBvUiC5X1pwe6y +w9Y4rhf5ZoJY+OGrv5LVVpjomLFqlrIE63xMvmpMuSVkWKJ8DeKxbM0HKXnb +YMSlb/kSH/2TeK3i7hZEuP6q5xAPxqvaiLqzID/b3nDaYgmWwubM2UpvNiC5 ++FuyHLGoSNiZ1flGKJD/7KtL/OLjtz2W99ajtfbNrCDiG8Vd4pHumvAMZgVe +Jp43ZN3DKlAHZ2Xxr3hiz0f2JS4JqiT38rNeESc1W3ikeCgjWltH7j3xmfvp +wZeT5KHYmh3cTOw1xXr5+yOzkXZdvaOPOCLvUNI8HyFoGT6yEBBraF3/v/8L +/gf03nID + "]]}, + {Hue[0.9060679774997897, 0.6, 0.6], Dashing[0.1], LineBox[CompressedData[" +1:eJxTTMoPSmViYGAwBWIQzbyf69xj00K7D6zeJS/W3bMPypG8NWPSfHsYf+Kn +mM3TJq2H862PenE5FR+A8wuq/BI3F5yA83N3pPYxKV+A86+88ORcnnQFzu/S +/8awLfIGnF+ofWLqgaV34Pxfydnr7uY9gPOT9oYFTEh7BOcnf7xy4EDHEzi/ +x2B7/rK2Z3A+04Ht5i1VL+B8QS3vc/dnvILzPeY7Lf4w6Q2cL/7+jFv99ndw +/qzjuxiZMz/A+Tayjv8VUj7C+doPBJ7UlnyC89euEMrYWvQZzq+5F3tZu+0L +wn82Ft7zpnxF+G++S9LrCd/g/AsFsxLKF32H8y3dlf7dXfgDzj/parnCYc5P +OH/pxpmWj1b/gvNFlXWy4lb+hvMvMXI0Se75A+dv5SheduHkXzhfR1QgK+no +Pzj/fd83EeNr/+F85fZ2/fwsBgcY/1HU7VtOzxF8j6eXf27NY4TzK4pSM8Te +Ivh+22Z7iZUxwfnv/mTVMH9D8Bdeb9ySV8wM5//KsE2o/I3gy/6dGF1YxQLn +P3PvPsXBwgrnH1Y7Yy/XjeBncSxjUeRkg/O3L1CxPTwRwT9nbXM0SJAdzv+R +NTs4oQ/BPxEwP5RXjAPOT7K0Wb58CoK/6EZtzkNZTjj/VadwzDt5BN/QeqX3 +b0UEHwCdjbFM + "]]}, + {Hue[0.1421359549995791, 0.6, 0.6], Dashing[0.04], LineBox[CompressedData[" + +1:eJwBoQFe/iFib1JlAgAAABkAAAACAAAAA78KzuM1cT4QTM1SBc6kPyXpvjse +k08/oGx12dk8pT/6sC9k2ZJfPyiNHWCuq6U/5RRo+LaSbz9Izm1tV4mmP9pG +hMKlkn8/cFAOiKlEqD/VX5InnZKPP+BUT71Nu6s/UmwZ2piSnz/QrugTS1Sx +P5HyXLOWkq8/mLdqfpNBuD87xUoKQnPAP1Rwjts6o8M/cHpOYbNwyD9a03ZY +RqbKP224ZY4CI9A/+uEt0w3D0D/U6EkJp2LUPyjgC9OMfdQ/ii/2ALZZ2D+V +hTEDWfjXP3EryJXApdw/4LBCjLm92z/6Y2uu3W7gP/gi0v1+cd8/Yr1WUJBm +4j8mntTPyHLhP2Px1MDAiOQ/we01TRxS4z+MMLdvpobmP/wQu2KWEeU/AsC3 +N4R66D+cV3/sQsjmPxEqS87fmOo/K2G5ojmk6D9In0Kj8JLsP1s+F/FWYOo/ +F+/MRn+37j963uprvkHsP5rHugEDafA//qH9Wlga7j88HUH/IGTxPyM5NOIY +0+8/EfQDTrZ98T8AAAAAAADwP2gryOY= + "]]}, + {Hue[0.37820393249936934`, 0.6, 0.6], Dashing[0.01], + LineBox[CompressedData[" +1:eJwBcQGO/iFib1JlAgAAABYAAAACAAAA9p+udS7BkT8AAAAAAAAAAFJsGdqY +kp8/HEHHqT2Sjj+R8lyzlpKvP27jMH9E7qg/O8VKCkJzwD9G5+QKhM6+P3B6 +TmGzcMg/oMTIYvy3xz9tuGWOAiPQP3ZW/mCIo88/1OhJCadi1D9hOdCEM/zT +P4ov9gC2Wdg/K64JXT3A1z9xK8iVwKXcP3V++KTysts/+mNrrt1u4D9ZPeHX +xnDfP2K9VlCQZuI/Fd2jibtn4T9j8dTAwIjkP0s+NkqvKuM/jDC3b6aG5j/m +zSNm6r/kPwLAtzeEeug/ofPGpWc+5j8RKkvO35jqP8xfxwvezOc/SJ9Co/CS +7D+ohwcjJDHpPxfvzEZ/t+4/d0mAkGai6j+ax7oBA2nwP9H3vP/G++s/PB1B +/yBk8T8MbWBUlS7tPyvgEOR9dPI/7uLCiqhq7j+tqBJotXLzPxHW1asBgu8/ +Ry5eGTns8z8AAAAAAADwP3NMssU= + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{{0., 3.1415925894756573`}, {0, 1}}, + PlotRangeClipping->True, + PlotRangePadding->{ + Scaled[0.02], Automatic}]], "Output", + CellChangeTimes->{{3.513957020555325*^9, 3.5139571065007277`*^9}}, + Background->RGBColor[ + 0.8597238117036698, 0.8597238117036698, + 0.8597238117036698],ExpressionUUID->"f6907b0f-1937-498e-a1bc-ed2ca8442399"] +}, Open ]], + +Cell["\<\ +In a local stability analysis, we assume that we are near an equilibrium, and \ +use the Taylor series to approximate the recursion or differential equation, \ +f[n], to linear order:\ +\>", "Text", + CellChangeTimes->{{3.5139571281952057`*^9, 3.5139571519990273`*^9}, { + 3.514116962346078*^9, 3.5141170073176403`*^9}, {3.514117051831397*^9, + 3.514117105747826*^9}},ExpressionUUID->"94a62f9b-bf52-4a39-a92f-\ +a9a726c6ccf5"], + +Cell[BoxData[ + RowBox[{"Normal", "[", + RowBox[{"Series", "[", + RowBox[{ + RowBox[{"f", "[", + RowBox[{"n", "[", "t", "]"}], "]"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], ",", + FormBox[ + OverscriptBox["n", "^"], + TraditionalForm], " ", ",", "1"}], "}"}]}], "]"}], "]"}]], "Input", + CellChangeTimes->{ + 3.514117055166052*^9, {3.5141171281161003`*^9, + 3.5141171328914623`*^9}},ExpressionUUID->"f1b0f582-39dc-4bfb-8433-\ +4d00f369bbfb"], + +Cell[TextData[{ + "Describing the recursion equation as a function (f), where ", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "=", + RowBox[{"f", "[", + RowBox[{"n", "[", "t", "]"}], "]"}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"207c7ff8-4958-4de6-8faf-86ee19092c15"], + ", the Taylor series tells us that:\n\n\t", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "\[TildeTilde]", + RowBox[{ + RowBox[{"f", "[", + OverscriptBox["n", "^"], "]"}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"dae5f561-491e-46cc-9293-f7384934046e"], + "\t(note that ", + Cell[BoxData[ + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"907b9bd9-08dc-4da4-a04b-005452ce234a"], + " is the derivative of f with respect to n, evaluated at ", + Cell[BoxData[ + OverscriptBox["n", "^"]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"a182b01a-64e3-4252-bebd-e3a12eb8f258"], + ": ", + Cell[BoxData[ + SubscriptBox[ + RowBox[{"(", + FractionBox["df", "dn"], ")"}], + RowBox[{"n", "=", + OverscriptBox["n", "^"]}]]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"7331d66c-8332-4441-9081-768627df52be"], + ")\n\t", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "\[TildeTilde]", + RowBox[{ + OverscriptBox["n", "^"], " ", "+", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"fa5c6ba3-132a-447c-afcb-d7f7ab3494e6"], + "\t(", + Cell[BoxData[ + RowBox[{ + RowBox[{"f", "[", + OverscriptBox["n", "^"], "]"}], "=", + OverscriptBox["n", "^"]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"7526d36e-b31d-4f28-9f82-5299cd929331"], + " because the recursion started at an equilibrium returns the equilibrium)\n\ +\t", + Cell[BoxData[ + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], "\[TildeTilde]", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"f075292e-0086-4aa8-bbc3-f363ad7d8f2a"], + "\t(moving ", + Cell[BoxData[ + OverscriptBox["n", "^"]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"be2222b9-6afe-4412-ae6b-6ad68fda98b8"], + " to the left)\n\nso the distance to the equilibrium ", + Cell[BoxData[ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"0b3618ea-f623-4747-8f44-117b7a9d9d65"], + " changes by a factor ", + Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"9cebc566-d400-4b4d-9bb9-ead014099b19"], + " each generation." +}], "Text", + CellChangeTimes->{{3.514117113606474*^9, 3.514117142561469*^9}, { + 3.514117477536956*^9, 3.514117590046109*^9}, {3.5141176961194553`*^9, + 3.5141177246657267`*^9}, {3.514117780492716*^9, 3.5141177900252123`*^9}, { + 3.563585746817067*^9, 3.563585775387279*^9}, {3.563585855165455*^9, + 3.563585922937891*^9}, {3.563585993990931*^9, 3.5635860062314653`*^9}, { + 3.5635860429884644`*^9, 3.56358607363433*^9}, {3.563586136139804*^9, + 3.5635861420353737`*^9}, {3.563586277538406*^9, + 3.563586380345704*^9}},ExpressionUUID->"b132e035-227d-4ef4-ad9c-\ +313b44129e1c"], + +Cell[TextData[{ + "Describing the differential equation as a function (f), where ", + Cell[BoxData[ + RowBox[{ + FractionBox["dn", "dt"], "=", + RowBox[{"f", "[", + RowBox[{"n", "[", "t", "]"}], "]"}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"a79da97c-b03b-40a0-bb3e-9d26a1a7f471"], + ", the Taylor series tells us that:\n\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dn", "dt"], "\[TildeTilde]", + RowBox[{ + RowBox[{"f", "[", + OverscriptBox["n", "^"], "]"}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"c365b045-c57d-40a6-a478-08f971baa23f"], + "\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dn", "dt"], "\[TildeTilde]", + RowBox[{"0", " ", "+", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"90e7dc74-4412-4d4d-a9c9-ad264e9b23f0"], + "\t\t(", + Cell[BoxData[ + RowBox[{"f", "[", + OverscriptBox["n", "^"], "]"}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"897c7794-6059-496e-82c6-283e92a61986"], + "=0 because there is no change at an equilibrium)\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox[ + RowBox[{"d", + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}]}], "dt"], "\[TildeTilde]", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"d082a33a-9deb-4589-ad34-1151c86a8025"], + "\t\t(because ", + Cell[BoxData[ + RowBox[{ + FractionBox[ + RowBox[{"d", + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}]}], "dt"], "=", + RowBox[{ + RowBox[{ + FractionBox[ + RowBox[{"d", + RowBox[{"(", + RowBox[{"n", "[", "t", "]"}], ")"}]}], "dt"], "-", + FractionBox[ + RowBox[{"d", + RowBox[{"(", + OverscriptBox["n", "^"], ")"}]}], "dt"]}], "=", " ", + RowBox[{ + FractionBox[ + RowBox[{"d", + RowBox[{"(", + RowBox[{"n", "[", "t", "]"}], ")"}]}], "dt"], "-", "0"}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"87c227af-ba46-4d3e-95f4-7a738ba880e1"], + ")\n\nso the distance to the equilibrium changes at a rate ", + Cell[BoxData[ + RowBox[{"r", "=", + RowBox[{ + SuperscriptBox["f", "\[Prime]", + MultilineFunction->None], "[", + OverscriptBox["n", "^"], "]"}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"a054e02d-2e2b-4e5b-9fe8-2516e78942b3"], + "." +}], "Text", + CellChangeTimes->{{3.514117113606474*^9, 3.514117142561469*^9}, { + 3.514117477536956*^9, 3.5141176140394173`*^9}, {3.514117741485834*^9, + 3.5141177720952053`*^9}, {3.5141178064765463`*^9, + 3.5141178346782017`*^9}, {3.514117971849181*^9, 3.514117974071348*^9}, + 3.563585778522565*^9, {3.5635860769026747`*^9, 3.563586124671801*^9}, { + 3.563586176720563*^9, + 3.563586238144927*^9}},ExpressionUUID->"8939f1a7-008b-4245-8eee-\ +aeff1eb87ef2"], + +Cell[TextData[{ + StyleBox["RECIPE: ", + FontWeight->"Bold"], + "To determine the stability of an equilibrium:\n\t* Take the derivative of \ +the recursion equation with respect to the variable, ", + Cell[BoxData[ + FractionBox["df", "dn"]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"e745cf1b-397c-471e-a45e-01e04509e35d"], + ", and evaluate at an equilibrium ", + Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + SubscriptBox[ + RowBox[{"(", + FractionBox["df", "dn"], ")"}], + RowBox[{"n", "=", + OverscriptBox["n", "^"]}]]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"6ebd6b0e-f2c2-4fb1-88d8-57864ac739d1"], + ".\n\t\t\[Rule] The equilibrium is stable only if -1<\[Lambda]<1\t\t\t\t\t\t\ +(Discrete-time model)\n\t\t\tIf 1<\[Lambda], equilibrium is unstable with \ +exponential growth away from it\n\t\t\tIf 0<\[Lambda]<1, equilibrium is \ +stable with exponential growth toward it\n\t\t\tIf -1<\[Lambda]<0, \ +equilibrium is stable with damped oscillations toward it\n\t\t\tIf \ +\[Lambda]<-1, equilibrium is unstable with growing oscillations away from it\n\ + \t* Take the derivative of the differential equation with respect to the \ +variable, ", + Cell[BoxData[ + FractionBox["df", "dn"]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"3cb56334-727c-4ff0-9c95-4e49bea33c10"], + ", and evaluate at an equilibrium ", + Cell[BoxData[ + RowBox[{ + StyleBox["r", + FontSlant->"Italic"], "=", + SubscriptBox[ + RowBox[{"(", + FractionBox["df", "dn"], ")"}], + RowBox[{"n", "=", + OverscriptBox["n", "^"]}]]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"b12c2471-7f2c-40f3-b1f8-58ae303718d4"], + ".\n\t\t\[Rule] The equilibrium is stable only if ", + StyleBox["r", + FontSlant->"Italic"], + " < 0\t\t\t\t\t\t(Continuous-time model)\n\t\t\tIf 0<", + StyleBox["r", + FontSlant->"Italic"], + ", equilibrium is unstable with exponential growth away from it\n\t\t\tIf ", + StyleBox["r", + FontSlant->"Italic"], + "<0, equilibrium is stable with exponential growth toward it\n\nRepeat for \ +each equilibrium of interest." +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117377492393*^9}, { + 3.514117840393688*^9, 3.5141181925597687`*^9}, {3.514118250452888*^9, + 3.5141182831133347`*^9}, {3.514679013185034*^9, 3.514679183553279*^9}, { + 3.5635864193461323`*^9, 3.563586461062994*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"824cfa99-bacf-454a-b7b3-128689879943"], + +Cell[TextData[{ + "For example, consider the logistic model in discrete time. When will the \ +system approach ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"d0c4cae0-21e6-4883-a88e-45c5a09f0e1d"], + " = 0, causing the system to go extinct?" +}], "Text", + CellChangeTimes->{{3.514118260182096*^9, 3.51411834422397*^9}, { + 3.514164209875112*^9, + 3.514164212833427*^9}},ExpressionUUID->"ba31bde4-919b-47b7-b6fe-\ +ca97ffc76124"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"derivative", "=", + RowBox[{"D", "[", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}]}]}], ")"}], + RowBox[{"n", "[", "t", "]"}]}], ",", + RowBox[{"n", "[", "t", "]"}]}], "]"}]}]], "Input", + CellChangeTimes->{{3.514118347956435*^9, 3.5141183994468813`*^9}, { + 3.514118454362989*^9, + 3.514118457111812*^9}},ExpressionUUID->"0362fd92-1034-4a7e-a6d8-\ +22d1d67c7a1d"], + +Cell[BoxData[ + RowBox[{"1", "-", + FractionBox[ + RowBox[{"r", " ", + RowBox[{"n", "[", "t", "]"}]}], "K"], "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}]}]}]], "Output", + CellChangeTimes->{{3.514118386149518*^9, 3.514118407945298*^9}, + 3.514118459061335*^9, + 3.514514866715094*^9},ExpressionUUID->"f68a7e6c-7d63-4a40-8383-\ +806791bdee61"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{"derivative", "/.", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", "0"}]}]}]], "Input", + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9},ExpressionUUID->"c7db40b4-64d5-4093-9d65-\ +09298453b3a8"], + +Cell[BoxData[ + RowBox[{"1", "+", "r"}]], "Output", + CellChangeTimes->{3.5141184099144697`*^9, 3.5141184643525333`*^9, + 3.514514868367621*^9},ExpressionUUID->"a1d91ce9-381d-4ab5-b1af-\ +6bcacb93281a"] +}, Open ]], + +Cell[TextData[{ + "For \[Lambda] to lie between -1 and +1, r must lie between -2 and 0. \ +[Technically, because 1+r measures the number of offspring per parent when \ +comeptition is weak, r cannot fall below -1 or it becomes biologically \ +meaningless.]\n\nWhen will the system approach ", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"0305b764-447c-45fa-83d9-0da05a420ded"], + " = K, causing the system to remain stably at carrying capacity?" +}], "Text", + CellChangeTimes->{{3.514118260182096*^9, 3.51411834422397*^9}, { + 3.5141184400986767`*^9, 3.5141184515365677`*^9}, {3.514164168341901*^9, + 3.514164312407412*^9}},ExpressionUUID->"8924f4b3-4dcd-4779-92e0-\ +c2f8d3c1008b"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{"derivative", "/.", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", "K"}]}]}]], "Input", + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, { + 3.514118467115301*^9, + 3.51411847142483*^9}},ExpressionUUID->"f35b923a-df30-454c-9325-\ +f96da2902d9b"], + +Cell[BoxData[ + RowBox[{"1", "-", "r"}]], "Output", + CellChangeTimes->{3.5141184099144697`*^9, + 3.5141184720825567`*^9},ExpressionUUID->"288a4c0a-3bbc-40cb-b9b5-\ +3f32847806bd"] +}, Open ]], + +Cell[TextData[{ + "\[Lambda] will be greater than one if:\tr<0\t\t", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"539b96e5-fe76-47a3-9dc8-2b43d771cdcf"], + "=K is an unstable equilibrium\n\[Lambda] will be between 0 and 1 if:\t0{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"225aa9b7-3435-46ec-837d-4497df78626f"], + "=K is a stable equilibrium\n\[Lambda] will be between -1 and 0 if:\t1{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"1fe1def9-90ac-40a9-a369-66b1537e46f2"], + "=K is a stable equilibrium with damped oscillations\n\[Lambda] will be less \ +than -1 if:\tr>2\t\t", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"d91d8f9d-64c6-45af-9432-29b7c2db856e"], + "=K is an unstable equilibrium with growing oscillations" +}], "Text", + CellChangeTimes->{{3.51455433531047*^9, 3.514554502230818*^9}, { + 3.514678601815401*^9, 3.514678606006456*^9}, {3.514678722858058*^9, + 3.514678737334487*^9}, {3.788179338906081*^9, + 3.788179339662862*^9}},ExpressionUUID->"da894a18-5657-4bd6-98ca-\ +45d240c75eba"], + +Cell[CellGroupData[{ + +Cell["\<\ +Question 4: What determines stability of the equilibria for the haploid model \ +of selection?\ +\>", "Subsubsection", + CellChangeTimes->{{3.51394814025489*^9, 3.513948145584239*^9}, { + 3.513948808098681*^9, 3.5139488496649723`*^9}, {3.5139491033219757`*^9, + 3.513949116352789*^9}, {3.5139539142255583`*^9, 3.513953950682358*^9}, { + 3.513954320569996*^9, 3.513954332097341*^9}, {3.51416490831287*^9, + 3.5141649260473633`*^9}},ExpressionUUID->"b453616a-bd0d-42e6-9227-\ +e7fc2cd8cf89"], + +Cell[TextData[{ + "Under what conditions is ", + Cell[BoxData[ + FormBox[ + RowBox[{ + OverscriptBox["p", "^"], "=", "0"}], TraditionalForm]],ExpressionUUID-> + "3dda8df8-aac7-44bd-a620-93643df493f7"], + " stable? \n\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + RowBox[{"p", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"ee3578c1-4c01-4a0c-90cf-a8a9f2b02eca"], + "\t\t\t\t\tDiscrete-time model\n\t\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dp", "dt"], "=", + RowBox[{ + RowBox[{ + SuperscriptBox["p", "\[Prime]", + MultilineFunction->None], "[", "t", "]"}], "=", + RowBox[{"s", " ", + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"ac7bdcc2-5c71-4192-9d86-91c94e1bec22"], + "\t\t\t\t\tContinuous-time model\n\t" +}], "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.5139475325082417`*^9, 3.51394758040838*^9}, {3.5139476417549477`*^9, + 3.513947714905636*^9}, {3.513947913524728*^9, 3.513947982531314*^9}, { + 3.513948017290382*^9, 3.513948113203456*^9}, {3.51394894565186*^9, + 3.513949092099876*^9}, {3.513953965380247*^9, 3.513954016760906*^9}, { + 3.513954339220845*^9, 3.513954345520956*^9}, {3.513954414894065*^9, + 3.513954469204207*^9}, {3.514164930898707*^9, + 3.5141650047514763`*^9}},ExpressionUUID->"d9ec45aa-1b0f-43f2-9bb5-\ +0362c2e60df7"], + +Cell[TextData[{ + "Under what conditions is ", + Cell[BoxData[ + FormBox[ + RowBox[{ + OverscriptBox["p", "^"], "=", "1"}], TraditionalForm]],ExpressionUUID-> + "9bb7a178-f427-4bc5-85f5-8c6848316065"], + " stable? " +}], "Text", + CellChangeTimes->{ + 3.514165000145801*^9},ExpressionUUID->"3c1e5d40-a65c-4cf9-bc45-\ +c643cdd6c4d9"], + +Cell[TextData[{ + "You can use either the discrete-time or the continuous-time model:\n\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + RowBox[{"p", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"ceb7a302-242d-4681-9880-487280334d12"], + "\t\t\t\t\tDiscrete-time model\n\t\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dp", "dt"], "=", + RowBox[{ + RowBox[{ + SuperscriptBox["p", "\[Prime]", + MultilineFunction->None], "[", "t", "]"}], "=", + RowBox[{"s", " ", + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"1362dd7f-da60-4191-b9d8-c94b34684118"], + "\t\t\t\t\tContinuous-time model\n\nNote that, in the discrete-time model, \ +the fitness of ", + StyleBox["A", + FontSlant->"Italic"], + " individuals is 1+s times greater than the fitness of ", + StyleBox["a", + FontSlant->"Italic"], + " individuals, where 1+s must be positive (fitness can't be negative)." +}], "Text", + CellChangeTimes->{{3.5141650094602737`*^9, + 3.514165129390822*^9}},ExpressionUUID->"64723ab7-8df1-4d2b-8afc-\ +785ce7c57645"], + +Cell["Discrete-time model:", "Text", + CellChangeTimes->{{3.514678647430603*^9, + 3.514678655991353*^9}},ExpressionUUID->"77561f68-7936-4f90-89b6-\ +d71709974977"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"derivative", "=", + RowBox[{"D", "[", + RowBox[{ + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]], ",", + RowBox[{"p", "[", "t", "]"}]}], "]"}]}]], "Input", + CellChangeTimes->{{3.514118347956435*^9, 3.5141183994468813`*^9}, { + 3.514118454362989*^9, 3.514118457111812*^9}, {3.514678661162228*^9, + 3.514678662993318*^9}},ExpressionUUID->"a776d04c-6096-410d-911b-\ +3b000d6ba455"], + +Cell[BoxData[ + RowBox[{ + RowBox[{"-", + FractionBox[ + RowBox[{"s", " ", + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], " ", + RowBox[{"p", "[", "t", "]"}]}], + SuperscriptBox[ + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], " ", + RowBox[{"p", "[", "t", "]"}]}]}], ")"}], "2"]]}], "+", + FractionBox[ + RowBox[{"1", "+", "s"}], + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], " ", + RowBox[{"p", "[", "t", "]"}]}]}]]}]], "Output", + CellChangeTimes->{{3.514118386149518*^9, 3.514118407945298*^9}, + 3.514118459061335*^9, 3.514514866715094*^9, + 3.5146786638248577`*^9},ExpressionUUID->"76b1f466-857b-4e74-b696-\ +aa5cb22f57d5"] +}, Open ]], + +Cell["(You could use the quotient rule to rederive the above.)", "Text", + CellChangeTimes->{{3.5146786688671083`*^9, + 3.514678681031719*^9}},ExpressionUUID->"b06c4621-0993-4cd2-a21c-\ +429a0ce15561"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{"derivative", "/.", + RowBox[{ + RowBox[{"p", "[", "t", "]"}], "\[Rule]", "0"}]}]}]], "Input", + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9, + 3.51467868436069*^9},ExpressionUUID->"33d00c46-6105-427c-978d-\ +44cd120941e5"], + +Cell[BoxData[ + RowBox[{"1", "+", "s"}]], "Output", + CellChangeTimes->{3.5141184099144697`*^9, 3.5141184643525333`*^9, + 3.514514868367621*^9, + 3.514678684802614*^9},ExpressionUUID->"d33da08e-160d-41df-b6f8-\ +5978952454fc"] +}, Open ]], + +Cell[TextData[{ + "As 1+s must be positive (its a fitness), \n\t\[Lambda] will be greater than \ +one if:\ts>0\t\t", + Cell[BoxData[ + FormBox[ + OverscriptBox["p", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"33112bad-644e-4685-ab2b-b534c3d9b4f8"], + "=0 is an unstable equilibrium (because A is favored)\n\t\[Lambda] will be \ +between 0 and 1 if:\t-1{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"0ab3131f-1645-48da-b13a-b776035280bb"], + "=0 is a stable equilibrium (because A is selected against)\n" +}], "Text", + CellChangeTimes->{{3.514678690500552*^9, + 3.514678796865803*^9}},ExpressionUUID->"c86419b4-f324-4669-bf14-\ +72d95e3c7ceb"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{"derivative", "/.", + RowBox[{ + RowBox[{"p", "[", "t", "]"}], "\[Rule]", "1"}]}]}]], "Input", + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9, 3.51467868436069*^9, + 3.514678804299721*^9},ExpressionUUID->"3ef9792e-37f1-4e33-b3a8-\ +6f9dc2097834"], + +Cell[BoxData[ + RowBox[{"1", "-", + FractionBox["s", + RowBox[{"1", "+", "s"}]]}]], "Output", + CellChangeTimes->{3.5141184099144697`*^9, 3.5141184643525333`*^9, + 3.514514868367621*^9, 3.514678684802614*^9, + 3.514678804629672*^9},ExpressionUUID->"cd3965e1-b09b-411c-a648-\ +0b0e629815da"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Factor", "[", "%", "]"}]], "Input", + CellChangeTimes->{{3.514678806330117*^9, + 3.514678807378543*^9}},ExpressionUUID->"e0aca7e7-144d-434a-a01b-\ +8ee771b2653a"], + +Cell[BoxData[ + FractionBox["1", + RowBox[{"1", "+", "s"}]]], "Output", + CellChangeTimes->{ + 3.5146788077351017`*^9},ExpressionUUID->"3258bdac-e990-480b-b516-\ +f9b5f70b562a"] +}, Open ]], + +Cell[TextData[{ + "As 1+s must be positive (its a fitness), \n\t\[Lambda] will be between 0 \ +and 1 if:\ts>0\t\t", + Cell[BoxData[ + FormBox[ + OverscriptBox["p", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"6c664843-5290-4a42-85ef-7eacc3eb9c9f"], + "=1 is a stable equilibrium (because A is favored)\n\t\[Lambda] will be \ +greater than one if:\t-1{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"5c6ac532-4a07-4017-9668-b5005a6c1afc"], + "=1 is an unstable equilibrium (because A is selected against)\n" +}], "Text", + CellChangeTimes->{{3.514678690500552*^9, + 3.51467890713196*^9}},ExpressionUUID->"29aa8fb3-7deb-469f-93af-\ +a9d84cff95f0"], + +Cell["Continuous-time model:", "Text", + CellChangeTimes->{{3.514678647430603*^9, 3.514678655991353*^9}, { + 3.514678915765066*^9, + 3.514678917372171*^9}},ExpressionUUID->"e6a6cfb3-593b-4a6b-a754-\ +7baf21d438bf"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"derivative", "=", + RowBox[{"D", "[", + RowBox[{ + RowBox[{"s", " ", + RowBox[{"p", "[", "t", "]"}], + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}], ",", + RowBox[{"p", "[", "t", "]"}]}], "]"}]}]], "Input", + CellChangeTimes->{{3.514118347956435*^9, 3.5141183994468813`*^9}, { + 3.514118454362989*^9, 3.514118457111812*^9}, {3.514678661162228*^9, + 3.514678662993318*^9}, {3.514678922732115*^9, + 3.51467892945287*^9}},ExpressionUUID->"8714f100-ee34-4738-87ef-\ +ede441db7f31"], + +Cell[BoxData[ + RowBox[{ + RowBox[{"s", " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}], "-", + RowBox[{"s", " ", + RowBox[{"p", "[", "t", "]"}]}]}]], "Output", + CellChangeTimes->{{3.514118386149518*^9, 3.514118407945298*^9}, + 3.514118459061335*^9, 3.514514866715094*^9, 3.5146786638248577`*^9, + 3.5146789301270943`*^9},ExpressionUUID->"d9d92a76-9288-446a-8f82-\ +ec22a1b44396"] +}, Open ]], + +Cell["(You could use the quotient rule to rederive the above.)", "Text", + CellChangeTimes->{{3.5146786688671083`*^9, + 3.514678681031719*^9}},ExpressionUUID->"a1c73d06-0283-4f6f-909f-\ +2fe5fd08c848"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{"derivative", "/.", + RowBox[{ + RowBox[{"p", "[", "t", "]"}], "\[Rule]", "0"}]}]}]], "Input", + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9, + 3.51467868436069*^9},ExpressionUUID->"75ba2372-4bc7-4df4-9a61-\ +eb50dfdc070f"], + +Cell[BoxData["s"], "Output", + CellChangeTimes->{3.5141184099144697`*^9, 3.5141184643525333`*^9, + 3.514514868367621*^9, 3.514678684802614*^9, + 3.514678933515183*^9},ExpressionUUID->"310b81b8-6869-47ec-8053-\ +d2b08e9715be"] +}, Open ]], + +Cell[TextData[{ + "\t\[Lambda] will be positive if:\ts>0\t\t", + Cell[BoxData[ + FormBox[ + OverscriptBox["p", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"e83c9375-47d9-4868-b3a6-d433c1ff9966"], + "=0 is an unstable equilibrium (because A is favored)\n\t\[Lambda] will be \ +negative if:\ts<0\t\t", + Cell[BoxData[ + FormBox[ + OverscriptBox["p", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"05bb53ea-10a8-4b58-b221-57e12481c9d4"], + "=0 is a stable equilibrium (because A is selected against)\n" +}], "Text", + CellChangeTimes->{{3.514678690500552*^9, 3.514678796865803*^9}, { + 3.514678937638277*^9, + 3.514678950452757*^9}},ExpressionUUID->"3ed079b4-159e-46d6-b9d2-\ +bb511858a350"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{"derivative", "/.", + RowBox[{ + RowBox[{"p", "[", "t", "]"}], "\[Rule]", "1"}]}]}]], "Input", + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9, 3.51467868436069*^9, + 3.514678804299721*^9},ExpressionUUID->"12664078-cfad-427d-816b-\ +4be9ab8b8a14"], + +Cell[BoxData[ + RowBox[{"-", "s"}]], "Output", + CellChangeTimes->{3.5141184099144697`*^9, 3.5141184643525333`*^9, + 3.514514868367621*^9, 3.514678684802614*^9, 3.514678804629672*^9, + 3.514678955185184*^9},ExpressionUUID->"f04c5f90-f355-4673-b974-\ +8ab43c10a512"] +}, Open ]], + +Cell[TextData[{ + "\t\[Lambda] will be negative if:\ts>0\t\t", + Cell[BoxData[ + FormBox[ + OverscriptBox["p", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"8891aab1-3092-4c25-b9a6-61e18e76f2bb"], + "=1 is a stable equilibrium (because A is favored)\n\t\[Lambda] will be \ +positive if:\ts<0\t\t", + Cell[BoxData[ + FormBox[ + OverscriptBox["p", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"94da8fcf-0d87-40ef-999f-3582b340c66f"], + "=1 is an unstable equilibrium (because A is selected against)" +}], "Text", + CellChangeTimes->{{3.514678690500552*^9, 3.51467890713196*^9}, { + 3.514678960254184*^9, + 3.5146789857359447`*^9}},ExpressionUUID->"bccce608-5988-4c97-a855-\ +bd2be51ad106"] +}, Open ]] +}, Open ]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Part 3: Beyond equilibria", "Section", + CellChangeTimes->{{3.5141651627789507`*^9, 3.514165208361671*^9}, + 3.514421631908485*^9},ExpressionUUID->"a2a07b40-06dd-4555-bb97-\ +3abb2cd9f7a3"], + +Cell[CellGroupData[{ + +Cell["General solutions", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.51395448884634*^9, 3.513954489788062*^9}, {3.514421636657851*^9, + 3.5144216396486893`*^9}},ExpressionUUID->"6ac5e1bb-5542-4ad0-8408-\ +90ac15e3ca11"], + +Cell["\<\ +Some models can be solved generally, allowing us to predict the future state \ +at any time in the future and how this depends on the parameters.\ +\>", "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.513954558138726*^9, + 3.513954567740512*^9}, {3.513954646641127*^9, 3.513954959224346*^9}, { + 3.51395503435863*^9, 3.513955036549271*^9}, {3.513955808112068*^9, + 3.513955827145928*^9}, {3.5139562760990334`*^9, 3.513956403467185*^9}, { + 3.5139565012215347`*^9, 3.513956531165784*^9}, 3.513956573839028*^9, { + 3.513956783731927*^9, 3.5139568012276773`*^9}, {3.514116820097149*^9, + 3.5141168314840097`*^9}, {3.514116935475194*^9, 3.5141169358821573`*^9}, { + 3.5141174296927032`*^9, 3.514117449201955*^9}, {3.514421641290387*^9, + 3.514421687132519*^9}},ExpressionUUID->"1e3b067d-f60c-4ff3-afd8-\ +3c290427ca0c"], + +Cell[TextData[{ + StyleBox["DEFINITION: ", + FontWeight->"Bold"], + " A ", + StyleBox["general solution", + FontColor->RGBColor[1, 0, 0]], + " describes the state of a system at any future point in time." +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117377492393*^9}, { + 3.5141174250611267`*^9, 3.5141174260424957`*^9}, {3.514421694846284*^9, + 3.514421705133667*^9}, {3.514422248108547*^9, 3.51442226455268*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"143bea1c-40de-42d9-a476-959ea71a3968"], + +Cell["\<\ +There are many methods for finding general solutions (see Chapters 6 & 9), \ +including iterating recursions to deduce a general rule and using recipes to \ +solve differential equations (e.g., separation of variables).\ +\>", "Text", + CellChangeTimes->{{3.514422868946821*^9, 3.514422878860903*^9}, { + 3.514423189942401*^9, + 3.514423305497418*^9}},ExpressionUUID->"573123a8-1ff3-4dcf-a945-\ +2c80810ecd23"], + +Cell[TextData[{ + StyleBox["Mathematica", + FontSlant->"Italic"], + " makes it easy to find general solutions for many of the simpler models." +}], "Text", + CellChangeTimes->{{3.514422268916256*^9, 3.514422287097013*^9}, { + 3.51442332643711*^9, + 3.514423377884426*^9}},ExpressionUUID->"b4bea33a-7b4c-44d8-8979-\ +ca1c28adafe8"], + +Cell["Recursion equations:", "Text", + CellChangeTimes->{{3.514422302039283*^9, + 3.514422305265853*^9}},ExpressionUUID->"c452e00a-c18a-4525-87e2-\ +2cf6520edd5d"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"RSolve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "\[Equal]", " ", + RowBox[{"R", "*", + RowBox[{"n", "[", "t", "]"}]}]}], ",", + RowBox[{ + RowBox[{"n", "[", "0", "]"}], "\[Equal]", "n0"}]}], "}"}], ",", + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}]], "Input", + CellChangeTimes->{{3.514422306626211*^9, + 3.514422346637411*^9}},ExpressionUUID->"fb65b155-6016-496b-a313-\ +28530b16e3c3"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", + RowBox[{"n0", " ", + SuperscriptBox["R", "t"]}]}], "}"}], "}"}]], "Output", + CellChangeTimes->{ + 3.514679662398361*^9},ExpressionUUID->"2268ea6d-296f-483b-ba4c-\ +42a5f342a946"] +}, Open ]], + +Cell[TextData[{ + "NOTE: Again, we use == instead of = here because we don't want to set ", + Cell[BoxData[ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], " "}]], + CellChangeTimes->{{3.5139532622009068`*^9, 3.513953273073205*^9}}, + ExpressionUUID->"3762cbfc-0dd4-4a70-b0b2-b63440a08c42"], + "equal to the right-hand side, we want TO TEST when the left and right will \ +be equal." +}], "Text", + CellChangeTimes->{{3.514423032910853*^9, + 3.514423041749639*^9}},ExpressionUUID->"fcc3e77c-e2fd-4788-9c92-\ +f8726dbba130"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"RSolve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"p", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "==", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], + RowBox[{"p", "[", "t", "]"}]}], "+", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]]}], ",", + RowBox[{ + RowBox[{"p", "[", "0", "]"}], "\[Equal]", "p0"}]}], "}"}], ",", + RowBox[{"p", "[", "t", "]"}], ",", "t"}], "]"}]], "Input", + CellChangeTimes->{{3.514422306626211*^9, + 3.5144223727675056`*^9}},ExpressionUUID->"4304aa7d-e533-4dab-a3dd-\ +2cf7f1de261d"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{ + RowBox[{"p", "[", "t", "]"}], "\[Rule]", + FractionBox[ + RowBox[{"p0", " ", + SuperscriptBox[ + RowBox[{"(", + FractionBox["1", + RowBox[{"1", "+", "s"}]], ")"}], + RowBox[{"-", "t"}]]}], + RowBox[{"1", "-", "p0", "+", + RowBox[{"p0", " ", + SuperscriptBox[ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], "t"]}]}]]}], "}"}], "}"}]], "Output",\ + + CellChangeTimes->{ + 3.514679460654866*^9},ExpressionUUID->"2c42cbf4-017a-4ba5-88e0-\ +f0bda16abc98"] +}, Open ]], + +Cell[TextData[{ + "Note that ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " doesn't simplify the fraction on top unless you specify that the \ +denominator is positive:" +}], "Text", + CellChangeTimes->{{3.5146795136634207`*^9, 3.5146795323996353`*^9}, { + 3.514679575931913*^9, + 3.514679588923149*^9}},ExpressionUUID->"05de0edb-fb88-48f5-bea8-\ +d6e1faebcb5e"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Simplify", "[", + RowBox[{ + SuperscriptBox[ + RowBox[{"(", + FractionBox["1", + RowBox[{"1", "+", "s"}]], ")"}], + RowBox[{"-", "t"}]], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"1", "+", "s"}], ">", "0"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.514679479254745*^9, 3.514679493854981*^9}, { + 3.514679534666851*^9, 3.514679534715317*^9}, {3.5146795687087917`*^9, + 3.5146795721882067`*^9}},ExpressionUUID->"c2a1b75e-df8d-4ad1-bf2d-\ +2c572a613662"], + +Cell[BoxData[ + SuperscriptBox[ + RowBox[{"(", + RowBox[{"1", "+", "s"}], ")"}], "t"]], "Output", + CellChangeTimes->{3.514679488076874*^9, 3.5146795351991243`*^9, + 3.514679572633718*^9},ExpressionUUID->"bdd7674e-ec2c-4665-a907-\ +e255e575bbb1"] +}, Open ]], + +Cell["Differential equations:", "Text", + CellChangeTimes->{{3.514422453198406*^9, 3.514422456164042*^9}, { + 3.514422577047386*^9, + 3.514422579516485*^9}},ExpressionUUID->"b15044b7-afe3-42fb-8ad3-\ +49848a1fbe95"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"DSolve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"D", "[", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}], " ", "\[Equal]", " ", + RowBox[{"R", "*", + RowBox[{"n", "[", "t", "]"}]}]}], ",", + RowBox[{ + RowBox[{"n", "[", "0", "]"}], "\[Equal]", "n0"}]}], "}"}], ",", + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}]], "Input", + CellChangeTimes->{{3.514422306626211*^9, 3.514422346637411*^9}, { + 3.51442258600113*^9, 3.514422593641465*^9}, {3.5144228115485783`*^9, + 3.5144228119806643`*^9}},ExpressionUUID->"bd2a3e68-c2cc-4462-bcd1-\ +23d7697253d3"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", + RowBox[{ + SuperscriptBox["\[ExponentialE]", + RowBox[{"R", " ", "t"}]], " ", "n0"}]}], "}"}], "}"}]], "Output", + CellChangeTimes->{ + 3.514679668852212*^9},ExpressionUUID->"fe6dc093-d105-4763-bcf2-\ +ae97ff6c3eb3"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"DSolve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"D", "[", + RowBox[{ + RowBox[{"p", "[", "t", "]"}], ",", "t"}], "]"}], " ", "==", + RowBox[{"s", " ", + RowBox[{"p", "[", "t", "]"}], + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]}], ",", + RowBox[{ + RowBox[{"p", "[", "0", "]"}], "\[Equal]", "p0"}]}], "}"}], ",", + RowBox[{"p", "[", "t", "]"}], ",", "t"}], "]"}]], "Input", + CellChangeTimes->{{3.514422306626211*^9, 3.5144223727675056`*^9}, { + 3.514422818087641*^9, + 3.51442283933525*^9}},ExpressionUUID->"60879615-4a14-4b9b-8e33-\ +8dff4ed852a4"], + +Cell[BoxData[ + RowBox[{ + RowBox[{"Solve", "::", "\<\"ifun\"\>"}], ":", + " ", "\<\"Inverse functions are being used by \\!\\(Solve\\), so some \ +solutions may not be found; use Reduce for complete solution information. \\!\ +\\(\\*ButtonBox[\\\"\[RightSkeleton]\\\", ButtonStyle->\\\"Link\\\", \ +ButtonFrame->None, ButtonData:>\\\"paclet:ref/message/Solve/ifun\\\", \ +ButtonNote -> \\\"Solve::ifun\\\"]\\)\"\>"}]], "Message", "MSG", + CellChangeTimes->{3.514422839923977*^9, 3.514423053816245*^9, + 3.5146796709973087`*^9},ExpressionUUID->"c56da930-1131-40f7-9927-\ +0b6203956ac9"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{ + RowBox[{"p", "[", "t", "]"}], "\[Rule]", + FractionBox[ + RowBox[{ + SuperscriptBox["\[ExponentialE]", + RowBox[{"s", " ", "t"}]], " ", "p0"}], + RowBox[{"1", "-", "p0", "+", + RowBox[{ + SuperscriptBox["\[ExponentialE]", + RowBox[{"s", " ", "t"}]], " ", "p0"}]}]]}], "}"}], "}"}]], "Output", + CellChangeTimes->{ + 3.514679671008894*^9},ExpressionUUID->"fb0de74f-42f8-4ab5-b5cc-\ +bf3a7e6be932"] +}, Open ]], + +Cell["These can then be used to predict where the system will be:", "Text", + CellChangeTimes->{{3.514423057756749*^9, + 3.514423067565619*^9}},ExpressionUUID->"34e02973-9e3f-4546-8c9b-\ +5328b3e1f700"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Manipulate", "[", + RowBox[{ + RowBox[{"Plot", "[", + RowBox[{ + FractionBox[ + RowBox[{ + SuperscriptBox["\[ExponentialE]", + RowBox[{"s", " ", "t"}]], " ", "p0"}], + RowBox[{"1", "-", "p0", "+", + RowBox[{ + SuperscriptBox["\[ExponentialE]", + RowBox[{"s", " ", "t"}]], " ", "p0"}]}]], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{"Automatic", ",", + RowBox[{"{", + RowBox[{"0", ",", "1"}], "}"}]}], "}"}]}]}], "]"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"s", ",", "0.1"}], "}"}], ",", + RowBox[{"-", "0.2"}], ",", "0.2"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"p0", ",", "0.05"}], "}"}], ",", "0.01", ",", "0.99"}], "}"}]}], + "]"}]], "Input", + CellChangeTimes->{{3.514423073379549*^9, 3.5144230885136223`*^9}, { + 3.563586610276767*^9, + 3.563586716031848*^9}},ExpressionUUID->"22795aeb-d61b-4e3b-9220-\ +d1a5337a9e40"], + +Cell[BoxData[ + TagBox[ + StyleBox[ + DynamicModuleBox[{$CellContext`p0$$ = 0.05, $CellContext`s$$ = 0.1, + Typeset`show$$ = True, Typeset`bookmarkList$$ = {}, + Typeset`bookmarkMode$$ = "Menu", Typeset`animator$$, Typeset`animvar$$ = + 1, Typeset`name$$ = "\"untitled\"", Typeset`specs$$ = {{{ + Hold[$CellContext`s$$], 0.1}, -0.2, 0.2}, {{ + Hold[$CellContext`p0$$], 0.05}, 0.01, 0.99}}, Typeset`size$$ = { + 450., {143., 150.}}, Typeset`update$$ = 0, Typeset`initDone$$, + Typeset`skipInitDone$$ = True, $CellContext`s$3222$$ = + 0, $CellContext`p0$3223$$ = 0}, + DynamicBox[Manipulate`ManipulateBoxes[ + 1, StandardForm, + "Variables" :> {$CellContext`p0$$ = 0.05, $CellContext`s$$ = 0.1}, + "ControllerVariables" :> { + Hold[$CellContext`s$$, $CellContext`s$3222$$, 0], + Hold[$CellContext`p0$$, $CellContext`p0$3223$$, 0]}, + "OtherVariables" :> { + Typeset`show$$, Typeset`bookmarkList$$, Typeset`bookmarkMode$$, + Typeset`animator$$, Typeset`animvar$$, Typeset`name$$, + Typeset`specs$$, Typeset`size$$, Typeset`update$$, Typeset`initDone$$, + Typeset`skipInitDone$$}, "Body" :> + Plot[E^($CellContext`s$$ $CellContext`t) ($CellContext`p0$$/( + 1 - $CellContext`p0$$ + + E^($CellContext`s$$ $CellContext`t) $CellContext`p0$$)), \ +{$CellContext`t, 0, 100}, PlotRange -> {Automatic, {0, 1}}], + "Specifications" :> {{{$CellContext`s$$, 0.1}, -0.2, + 0.2}, {{$CellContext`p0$$, 0.05}, 0.01, 0.99}}, "Options" :> {}, + "DefaultOptions" :> {}], + ImageSizeCache->{503., {213., 220.}}, + SingleEvaluation->True], + Deinitialization:>None, + DynamicModuleValues:>{}, + SynchronousInitialization->True, + UnsavedVariables:>{Typeset`initDone$$}, + UntrackedVariables:>{Typeset`size$$}], "Manipulate", + Deployed->True, + StripOnInput->False], + Manipulate`InterpretManipulate[1]]], "Output", + CellChangeTimes->{{3.5635866923495827`*^9, + 3.5635867240843277`*^9}},ExpressionUUID->"e7ec6cc7-1552-4ce3-bfc0-\ +65151baade76"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["\<\ +Question 5: Show that the logistic model in discrete time does not have a \ +solution, but the model in continuous time does and and then plot this \ +solution.\ +\>", "Subsubsection", + CellChangeTimes->{{3.51394814025489*^9, 3.513948145584239*^9}, { + 3.513948808098681*^9, 3.5139488496649723`*^9}, {3.5139491033219757`*^9, + 3.513949116352789*^9}, {3.5139539142255583`*^9, 3.513953950682358*^9}, { + 3.513954320569996*^9, 3.513954332097341*^9}, {3.51416490831287*^9, + 3.5141649260473633`*^9}, {3.5144228942244473`*^9, 3.514422927032115*^9}, { + 3.514423175354671*^9, 3.5144231788669167`*^9}, {3.563586762704207*^9, + 3.563586764944023*^9}},ExpressionUUID->"e478712e-1285-4223-af1a-\ +9cd518503832"], + +Cell[TextData[{ + "Use: \n\n\t", + Cell[BoxData[ + RowBox[{" ", + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], " ", "=", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}]}]}], ")"}], + RowBox[{"n", "[", "t", "]"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"7c84d796-87ce-44a1-8fa4-53220722a77b"], + "\t\t\t\tDiscrete-time model\n\t\n\t", + Cell[BoxData[ + RowBox[{ + FractionBox["dn", "dt"], "=", + RowBox[{ + RowBox[{ + SuperscriptBox["n", "\[Prime]", + MultilineFunction->None], "[", "t", "]"}], "=", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}], " ", + RowBox[{"n", "[", "t", "]"}]}]}]}]], + CellChangeTimes->{{3.513947684629984*^9, 3.5139476954205637`*^9}}, + ExpressionUUID->"99ea77b2-45d1-4549-bb2e-387f1eb0b1ed"], + "\t\t\t\t\tContinuous-time model\t" +}], "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.5139475325082417`*^9, 3.51394758040838*^9}, {3.5139476417549477`*^9, + 3.513947714905636*^9}, {3.513947913524728*^9, 3.513947982531314*^9}, { + 3.513948017290382*^9, 3.513948113203456*^9}, {3.51394894565186*^9, + 3.513949092099876*^9}, {3.513953965380247*^9, 3.513954016760906*^9}, { + 3.513954339220845*^9, 3.513954345520956*^9}, {3.513954414894065*^9, + 3.513954469204207*^9}, {3.514164930898707*^9, 3.5141650047514763`*^9}, { + 3.5144229374662333`*^9, 3.514422939223877*^9}, {3.514423130160406*^9, + 3.514423131507475*^9}},ExpressionUUID->"f7931284-0a87-4d28-9326-\ +5ab53f843f2a"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"DSolve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"D", "[", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}], " ", "==", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}], " ", + RowBox[{"n", "[", "t", "]"}]}]}], ",", + RowBox[{ + RowBox[{"n", "[", "0", "]"}], "\[Equal]", "n0"}]}], "}"}], ",", + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}]], "Input", + CellChangeTimes->{{3.514679689803866*^9, + 3.514679697603372*^9}},ExpressionUUID->"790c2919-a15e-46db-8846-\ +d47e76c50a14"], + +Cell[BoxData[ + RowBox[{ + RowBox[{"Solve", "::", "\<\"ifun\"\>"}], ":", + " ", "\<\"Inverse functions are being used by \\!\\(Solve\\), so some \ +solutions may not be found; use Reduce for complete solution information. \\!\ +\\(\\*ButtonBox[\\\"\[RightSkeleton]\\\", ButtonStyle->\\\"Link\\\", \ +ButtonFrame->None, ButtonData:>\\\"paclet:ref/message/Solve/ifun\\\", \ +ButtonNote -> \\\"Solve::ifun\\\"]\\)\"\>"}]], "Message", "MSG", + CellChangeTimes->{ + 3.514679698028041*^9},ExpressionUUID->"6c658f82-9b03-4796-9ab0-\ +1082f3dc8fed"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", + FractionBox[ + RowBox[{ + SuperscriptBox["\[ExponentialE]", + RowBox[{"r", " ", "t"}]], " ", "K", " ", "n0"}], + RowBox[{"K", "-", "n0", "+", + RowBox[{ + SuperscriptBox["\[ExponentialE]", + RowBox[{"r", " ", "t"}]], " ", "n0"}]}]]}], "}"}], "}"}]], "Output", + CellChangeTimes->{ + 3.514679698030118*^9},ExpressionUUID->"e1e9ac0d-24c9-4b40-a6ff-\ +8d7f171b25ce"] +}, Open ]], + +Cell[TextData[{ + "Note that this has the same form as the solution for the haploid model, ", + Cell[BoxData[ + FractionBox[ + RowBox[{ + SuperscriptBox["\[ExponentialE]", + RowBox[{"s", " ", "t"}]], " ", "p0"}], + RowBox[{"1", "-", "p0", "+", + RowBox[{ + SuperscriptBox["\[ExponentialE]", + RowBox[{"s", " ", "t"}]], " ", "p0"}]}]]], + CellChangeTimes->{{3.514423073379549*^9, 3.5144230885136223`*^9}}, + ExpressionUUID->"1a59dd8e-31cb-4f21-9dc7-f28c8d6fc61a"], + ", if we let K=1, n0=p0, and r=s. This is only true for the continuous-time \ +models, however, and the discrete-time models behave much differently." +}], "Text", + CellChangeTimes->{{3.514679708881302*^9, + 3.514679781778755*^9}},ExpressionUUID->"1040be7d-568e-44eb-b39d-\ +67c0ed2002ea"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{ + RowBox[{ + FractionBox[ + RowBox[{ + SuperscriptBox["\[ExponentialE]", + RowBox[{"r", " ", "t"}]], " ", "K", " ", "n0"}], + RowBox[{"K", "-", "n0", "+", + RowBox[{ + SuperscriptBox["\[ExponentialE]", + RowBox[{"r", " ", "t"}]], " ", "n0"}]}]], "/.", + RowBox[{"s", "\[Rule]", "0.1"}]}], "/.", + RowBox[{"p0", "\[Rule]", "0.01"}]}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.514423073379549*^9, 3.5144230885136223`*^9}, + 3.514679706672103*^9},ExpressionUUID->"8d2d7efc-166b-4baf-9e31-\ +4f3235f70007"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {Hue[0.67, 0.6, 0.6], LineBox[CompressedData[" +1:eJwV1nk0llsXAHBT0e0qpPKiEr4MGV5D6or2VpF5eOeKQsk8lTmizMqQCgkR +KipzKYWkKEUSDVRcSYT3IZlCvuf+cdZev3X2XuusffZZ62x29KY58fHw8Hwg +139RNnkxP2djw66iZkrivyFRUC2ktMnT5So8ZRtOdCREQUNQSYGiSynMtdnl +tGdGQRPV13m5Sz04ivvMjtdEwfNzHcZTzq+B55NZedN8FLzQjXww6twLp8Wz +/dvCo6HlfI/vkDMBPem8pannY8C0VtBy0HkJLI80MGW+xIHGkuPUuvElED3R +uyQ6GQfnZA63yenxoPmXtrVrheLBz7HGn/GUBzl6xbVWmvGwd9Dn6d1OXqzb +4XU2IzYe+sc+OwRN8eO1NKIyalsCyCxWZy3qCGHLcwEFtatnoVVYZ4WAnQiK +U1vuyd5Jgg4zsYy2UBF0bbrLT32WBB/iuVsuZ4ng/T0+/Vafk2Bg2Y29ap9E +sPnCwLlm4WRYWFwfwTkoivmZI9IZ3smgzJ2bvr1fDMtDDAycpFIgrq12gMkS +x87k35dHh1Ngd7Lh4xtWErg9z2rFZGEqRJhWFXV4SaA2b16QXlUq1C2Tu7CY +KIHBC1WFKU9SQTeU5xj9lQQaO+hw9vemgpbrw5VLxhSUGf9nzoNyAeT3aLBZ +uyVRvk1ctCD5AiyfkeYKbJPGx/oRH+OjLoKT+m9hDWEZNGgQPC6YmgbmPbGF +Ehtl8H5K16bqgjTQjl2rz6Mug3oyMOpfnQYCvVSP19YyGPgtbvXmz2lwLcm5 +xfOiDI77U5+rKaVD71hnTLHUZlQ2lj6k+TQd9t8uXZJTlsWPNo231JZfBgsl +p4l1++Qx62BHxcNHV+D3Wf+Hn1nyOBe+YatwxxW4yY2OLjgmj5O+7ile36+A +QNV1imaMPEaqdVs6iGVBza4hA4tn8miwVuidoGsWbGG4p0bu+R8K5igvOFKy +gSfcV2sctuBf2b5R12JyoKIzzP/FDkUsUd2l9LMlF25GH3XsN1FE/VOXtnV/ +yIUcHTOr+QOKSIvwc2gdzIWEDAkl1TBF/Jr2YkcXXx4csa38lNKgiOo/hlvd +d+aB+MDQHo6pEtLpR74+LMmDgEm62PeDyhiT/sBaLuca7BRTLhUIV8HDcUOl +C3kF0MZ74EVrsgpujC6LzKsoAPuJ+K9puSp45xBNi95YAFHtw+uVnqjgW76d +pp8HyPykogiLZaq4t5LGSFQsBPuVSrS0s6o40Cv+/mhFIUQJKE4pZKjh66xP +EZrt18F5PjW7kENFLPQ5d1inCC5ajjYG21OxfuiNmbJJETzOM/xh4UJFvS3i +ND7bIpAwntWZDqSibaIro/t0ETy/aNdulE5Fz9P2lK1tRaCkpsg/1EXFojrO +LMu1GEbsa12U6Rro1LPOYU3xLfBu+q5VaqGJO3oudQmwS+Ax3nZXYWlihsT2 +amPvEhB56JNfdEgTg/tWN+XElkBZ6ZxYgbcmmi3yZp6+XwI/M1b+zDivia9y +hB3lpEohwF297EyXJjrcbH3w79dSCBUJVGHZaWFrZqh5W0MZJBxY/r9FD21c +neevxQmvgCPNJ49puOjgKm5uwLTmPWgQpNi479+BQSeCgswCa0BDNCJt2E8X +D+QvGN4YrAf7SX0VSw891GrQOZXx/Qnk5TyTnknchddyT2tYZjZBZZJuTwcN +8fbDivthjS3gV6NvnW1ugAqqdh59Mq+hvqXwZ/zB3RgVbu35gNoBrvv+qXXl +7MFG2TgznS+dkHVT46672150udhcljr/Hs5P1p72CTREY8qfLRLbemCw2D/A +5bgRmu7fsM/c6gs8NUrNOHNmHz5SZTEzu/uA16q7PznCGJvY2dSTHv3AY3CP +NzfYBKcKOcf+/PgKcetnLDpiTXF4eb7cff9v4HPgyJOZSDPcXcIMOdM6CP+e +1j4Kl8yxP8zp6KjsEIhfuNwdn2eBjc3DhkLWw3BdRDm4+Yolfjle4ddk8gMa +jm8yVLhlhT++CVrYbR+BHJlcaX2GNYZSBfMTZkagNvQ3j0u7NdJEKVEmmaOw +2UxwQY5tg+Vbe/YNUseg6rXS2Y+dNjiSpLih7sYYpMg1FP5+Z4Mybnx66UVj +4B7IeSz10QabcpHf+9YYyG6KnbL7bINr4tYnSZaOQbLXwOH+bzZYe8PxlsO9 +MXATvqo9Mm2D6bYud8uejoGMmfiXBQkaJts6RbH7xuBc0x+qjB0NhY790J9c +wwX0HdTYcJiGit2/zjuu5cIvqTZNSQca/tWi+a19HRdsfbO1xZ1o2Lem9Gwx +hQuq0no7hDxpaO7vPGyziQttvsEwHkpDwTYJT19lLohs+GXxOIuGCTs4VTPA +hQsnht3sP9Fwj9qhCAMXLkgahfjSv9Cwk0ANb1cuXJNYGWTUR0PhfxNWZblx +oaJWJVplgBygJXvrSQ8utAv6XJ0doeHV645L6b5cWJU1/TZlnoYZe51Da0K4 +EPeUX79Bko7+L/X9nM9xIXTtxtWy++lopm5fEnqHC63lKw7AQTpeHt9Sm1TC +hY2WUwW2dnR0CUiauVrKhfqYV7rpDnTssLw4UV/OBb7ZkGN/u9FxSvPBX9N3 +uRDb/b52OoSOq6/b0HbWcSH16nmPl1lkvV2JqlobF4qUlrX49dGxYry9+e0I +FzqkDeY9++kYGbJq8/VRLiysDlNxHqBj/+f83sAxLlhO/0raP0RH7kJIEoUg ++/1kgL5rnI6GLKs65k/yPmyffhbkYWC+akBD+SwXPiRFTmRuYuDPmTmZeQEC +lv/ipTQcYuCetxv6h6QImC3LSBqwZyDlwMTu69IEjHiqCwgdYWBBDe/KIxsI +aP9uS1g6MzBk5kZH90YCMnuqn33yZqCo2zXzxs0EqDV6Hp+NYGDfEYpVkAIB +rNSPL9XzGfiDI5/tr0nADWr5qZzvDLS9afm904gAr7UTc9XDDGRscLnpsY8A +7d9U/zcjDFwT+ofgNybgcWOZu8A4A99qiItrmBDwgVXGcZtl4Dq7qQfRZgQI +hZVq6qxg4otn1q8krAlweXFnsFWZiZufdYYOcQhQciy2XPRkIt/2ux3oSsDz +bN2yn95MlBW2uVBF+tjHFtEhXyYKaFcuKLgRUGA90tnhz8TDK5tbhN0JkAGV +gzfDmKjeu/JglwcB66RLnOmJTBTuCD7D8CGA7115RNFtJp7SXEgXDyT/QSYP +KpgjTJQM2Fp5M5KA3VYFHP8xJjqoiCWKRBFQzEj+c5Fg4lHeFNEg0iGHnUw7 +J5l4acJeyiiaAEl/0X7aAhMnzR798yWGAE6uq6i1MAt1Zt73/Ikn4N00xcdU +nYXiGBnOn0JAR36IKpxgofsrnhmFKwSI8dx7oOvPwlWnyrsCSNNtJwx1Aln4 +sSQg8BnpTnGXQ6onWZjdOyXgmEXA+2hmslQkC20vN5pnZBPwyZk6MZPKwvRt +a6rnrhLwbetgVVkFC3enlW89X0DOR6WNnuxPFt6qWP5R6g4Bf+/QaVvzi4Xf +2sPOHiQt80jSftk0C2Nunxa+Qtr46dfIoTkWin6pj6CUEHC50/9lCS8bH9ny +KYqXEqA7dfnATlE2Ov97J4OnnIBQnf4gBpWN2DU6da+KgKX7x+/GeLHRknjz +I/cheb7lFWev+bCx2f82fzfpGsaEQ91xNvKd2jUm9ogAv3HvVdMBbAweldWK +Ij2k4OnsFM5G43SppKO1ZL/SnCl7U9i47c2nPOl6Agr9bMN4K9hYErJpj/sT +AsyoRoahU2y0q6iUS3hOAE9XF6/fDBvbh7W87pK+F+xU5z7Hxq188ul9pGUb +o7YfXGTjabeaKJ0XBPxmNirpLuNgMH/Cmz7SxSdx1aw4Bz+/eLZP/SUBK5p1 +35/Q5iBFw4te1UpAs526q/sJDhYU3RI72kGA0SuKW6I/B6MLlioTSD/TFXAv +DeTgAqVFu5x04/qPHpMnOej6RK1rkXT9mzM+J6M4WHxA8eKltwRUG74LPHuJ +g9C0Sba+k3xvqmExt6o5KPf+ndb8OwJiF1vyR+Y5+CE9M0O6hwDGRcrUPGna +mX1xG0jLbHUx+nuBgxmHuIEbSddwlg2rkN44psSWIT1aCWpepNnHOGvlSVu7 +Vd0fJ+02kpqylbTk++zWqUUOOlmFn9ElPeg5unH5Hw4y69x8d5KuFNjps470 +iJy1vR5pc80PYttJp70V2rWLdHiiGCeItNYLjTkD0gN7Yvt/k3ZUd/QyIV3W +3aW1comDuZJjtqakw3zlo6VIj/3xNTMjve5qg4Ie6X2VrooWpE1+z3uEkTZ4 +LdJv/d/+edO6RNJyse7tNqT7FS6vziFt8s/jOhrpUKZORR3pX+fYVxikjUej ++F+TblHLjGeSXhv5ltFLOvjlu0DWf/UU2esEabUjwsfYpEvKfGaWSP89rc/g +kP4/zQt6zA== + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{{0, 100}, {0., 0.9955255170204409}}, + PlotRangeClipping->True, + PlotRangePadding->{ + Scaled[0.02], + Scaled[0.02]}]], "Output", + CellChangeTimes->{ + 3.514679674834813*^9},ExpressionUUID->"dae5cb29-070e-44bd-ae19-\ +9172e325277d"] +}, Open ]] +}, Open ]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Simulations", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.514421605669952*^9, + 3.51442160694818*^9}},ExpressionUUID->"58ceb75c-09a2-4a8b-bfb4-\ +92009e759cd2"], + +Cell["\<\ +Some models, however, are too complicated to solve. Some cannot be solved \ +(e.g., the logistic in discrete time), while others may not be worth the time \ +needed to obtain a general solution when all that is needed are solutions to \ +specific cases.\ +\>", "Text", + CellChangeTimes->{{3.5144216199985*^9, 3.514421620816608*^9}, { + 3.5144233861823177`*^9, + 3.514423486185019*^9}},ExpressionUUID->"00483b84-7fd6-44fc-91da-\ +732d218c2f7d"], + +Cell[TextData[{ + StyleBox["DEFINITION: ", + FontWeight->"Bold"], + " A ", + StyleBox["simulation", + FontColor->RGBColor[1, 0, 0]], + " explores a model using specific parameter values and initial states by \ +applying the model's equations repeatedly." +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117310317294*^9}, { + 3.514423493433316*^9, 3.514423525555004*^9}, {3.514423974786891*^9, + 3.514423997472085*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"bf49b3d6-91da-4bfe-a8dc-6faeaf5cb3d0"], + +Cell[BoxData[{ + RowBox[{"Clear", "[", "logistic", "]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"r_", ",", "K_", ",", "n0_", ",", "t_"}], "]"}], ":=", + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"r", ",", "K", ",", "n0", ",", "t"}], "]"}], "=", + "\[IndentingNewLine]", + RowBox[{"Block", "[", + RowBox[{ + RowBox[{"{", + RowBox[{"n", "=", + RowBox[{"logistic", "[", + RowBox[{"r", ",", "K", ",", "n0", ",", + RowBox[{"t", "-", "1"}]}], "]"}]}], "}"}], ",", + "\[IndentingNewLine]", "\t", + RowBox[{"n", "+", + RowBox[{"r", " ", "n", " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"n", "/", "K"}]}], ")"}]}]}]}], "\[IndentingNewLine]", "\t", + "]"}]}]}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"r_", ",", "K_", ",", "n0_", ",", "0"}], "]"}], ":=", + "n0"}]}], "Input", + CellChangeTimes->{{3.514424045707509*^9, 3.514424061967498*^9}, { + 3.5144255050950212`*^9, 3.514425607017445*^9}, {3.514425642488206*^9, + 3.514425669408059*^9}, {3.514425734177042*^9, 3.514425737442438*^9}, { + 3.514426238427285*^9, 3.5144262538256493`*^9}, {3.514426381804556*^9, + 3.514426383523755*^9}, 3.5144264576520653`*^9, {3.5144266314259853`*^9, + 3.5144266539839983`*^9}, {3.514427148128552*^9, 3.5144271570026703`*^9}, { + 3.514679879462606*^9, + 3.514679893609824*^9}},ExpressionUUID->"dc948b39-aaa6-44f1-8bbb-\ +394906603b25"], + +Cell["\<\ +Some notes: +\t* Block keeps a set of calculations together, defining local variables in \ +the first {}. The output will be the last entry of the Block. +\t* := sets the left to the right-hand side only after being called and \ +remembers this value. +\t* We have to set a starting point or else the system will end up in an \ +infinite loop going backwards in time.\ +\>", "Text", + CellChangeTimes->{{3.514426408190782*^9, + 3.51442655970971*^9}},ExpressionUUID->"ce8154fb-dd94-44e3-9b8c-\ +17424baf8b4b"], + +Cell["We can then make a table of population sizes:", "Text", + CellChangeTimes->{{3.514426311595162*^9, + 3.514426337581416*^9}},ExpressionUUID->"2838ef50-526a-48f1-b5ba-\ +959a98e5a849"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"1.9", ",", "100", ",", "10", ",", "t"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5144262691718893`*^9, 3.514426294228351*^9}, { + 3.5144263455531607`*^9, 3.5144263905959597`*^9}, {3.514426567695655*^9, + 3.514426611405775*^9}, {3.51442669599331*^9, 3.514426706329217*^9}, + 3.514679974478546*^9},ExpressionUUID->"c10177da-49e8-4bc0-b2d7-\ +f35760d0cf96"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + "10", ",", "27.1`", ",", "64.63621`", ",", "108.0660557798821`", ",", + "91.50438593706687`", ",", "106.27471894881998`", ",", + "93.60468308621506`", ",", "104.97868373227931`", ",", + "95.04822609853345`", ",", "103.99071528066624`", ",", + "96.10576588682487`", ",", "103.21667457462149`", ",", + "96.90839997177935`", ",", "102.6008382014432`", ",", "97.5307227910495`", + ",", "102.10650021929725`", ",", "98.01984028232837`", ",", + "101.70764412826216`", ",", "98.40771536365708`", ",", + "101.38488413580909`", ",", "98.71716410044912`", ",", + "101.12328461863743`", ",", "98.96507024487144`", ",", + "100.91108626725274`", ",", "99.1642508739314`", ",", + "100.73890315802899`", ",", "99.32461357811196`", ",", + "100.5991809901407`", ",", "99.4539157695534`", ",", "100.48580985565383`", + ",", "99.55828691681039`", ",", "100.3938346763613`", ",", + "99.64260178198104`", ",", "100.31923145997844`", ",", + "99.71075542024366`", ",", "100.25873053566926`", ",", + "99.76587062958602`", ",", "100.20967491869287`", ",", + "99.81045726531734`", ",", "100.16990585869723`", ",", + "99.84653623515693`", ",", "100.13766991694348`", ",", + "99.87573696763627`", ",", "100.11154334440431`", ",", + "99.89937459360019`", ",", "100.09037048178398`", ",", + "99.91851139673885`", ",", "100.07321357547826`", ",", "99.9340059377445`", + ",", "100.05931190692112`", ",", "99.94655244362724`", ",", + "100.0480485245511`", ",", "99.95671246335047`", ",", + "100.03892318057882`", ",", "99.9649403522133`", ",", + "100.03153032860887`", ",", "99.97160381518118`", ",", "100.025541245814`", + ",", "99.97700048401788`", ",", "100.02068951380693`", ",", + "99.98137130451009`", ",", "100.0167592324033`", ",", "99.98491135427149`", + ",", "100.01357545547829`", ",", "99.9877785885027`", ",", + "100.01099643245249`", ",", "99.99010091328377`", ",", + "100.00890731619816`", ",", "99.9919819079563`", ",", + "100.00721506133311`", ",", "99.9935054557151`", ",", + "100.00584428845342`", ",", "99.99473949143346`", ",", + "100.00473393192381`", ",", "99.99573903547643`", ",", + "100.00383452311064`", ",", "99.99654864983265`", ",", + "100.00310598882606`", ",", "99.99720442676036`", ",", + "100.0025158674263`", ",", "99.99773559905414`", ",", + "100.00203786342855`", ",", "99.99816584400943`", ",", + "100.00165067647308`", ",", "99.9985143394043`", ",", + "100.00133705259957`", ",", "99.9987966186939`", ",", + "100.00108301566107`", ",", "99.99902526361952`", ",", + "100.00087724469033`", ",", "99.99921046515709`", ",", + "100.00071056951467`", ",", "99.99936047784351`", ",", + "100.00057556217006`", ",", "99.99948198775279`", ",", + "100.00046620592408`", ",", "99.99958041053871`", ",", + "100.00037762717011`", ",", "99.99966013283745`", ",", + "100.00030587825161`", ",", "99.99972470779586`"}], "}"}]], "Output", + CellChangeTimes->{{3.514679861996146*^9, 3.5146798959469347`*^9}, + 3.514679974972332*^9, + 3.563586854591041*^9},ExpressionUUID->"ee3bd96d-26c4-4148-b336-\ +e9873c0bbe72"] +}, Open ]], + +Cell["and plot this list:", "Text", + CellChangeTimes->{{3.5144263221305637`*^9, 3.514426329021406*^9}, { + 3.514426565192073*^9, + 3.5144265653575697`*^9}},ExpressionUUID->"a96c73bf-9ca4-41d0-a489-\ +1dbb5cbc5d8b"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"1.9", ",", "100", ",", "10", ",", "t"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"0", ",", "100"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "140"}], "}"}]}], "}"}]}], ",", + RowBox[{"Joined", "\[Rule]", "True"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5144263013250847`*^9, 3.514426303622571*^9}, { + 3.5146799460149117`*^9, 3.5146799717030067`*^9}, {3.563586859377133*^9, + 3.5635868638610163`*^9}},ExpressionUUID->"ca8208d5-8dee-40f6-ab5d-\ +597aaae23723"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {Hue[0.67, 0.6, 0.6], LineBox[CompressedData[" +1:eJw9y3lQ1GUcx/EVlkOg2rgNSEBDQVi5wmUl+HCswHL92GV3f0AOY2JFTGhp +5lQIHkB/6DAWCyN/qKCD2kzRgA3HdIAggh2Ypjk5UoSRlMll4nJG4+/7fWae +eebzvObt98pO3Q4rmUy2Y/n+/z45E3FP3rWQPlB/fPms2ixte9y69cInbesF +aStw5GObBLU8X9queKB4eDv5N6O0PbE/bGCx5lietL0RM97s2/qqSdq+cP3R +o7sxltwf07K//d17yNfCUqkYfm0pV9oBKItJGeq1FaW9HhMz9kt3vicPQsuJ +xug1avJgXBCd/fc0kSsR1Nrx8sw28lAc6EgbvVpJHob68WCF5gB5OP6yOe6g +fZM8Ao9jlVae9eSRWGftPNkgkr+IG7p4+ein5FF4O3XDHyPJ5JsQLl/4oucr +chVuF/fFZKnJozE/4+l+6Aq5Grrz+0K1G8k3w+Ydu319P5HH4GBC9JwYQP4S +2kydD53ukMfibqXqoMdq8jg8U+Bk6RwhBwK78msjV0leDuwsjd7uO0Yej6M+ +V1JLXMnj8Vluhrz0H/IEJKVVOFQryBNQejHWVj5JnojpM7lC8VPkiVgwBHw4 +NE2eBNWpa1/+6kCehDBVdlPII3INajrfNw/ak2sgWhQuTo/Jt6DQpaVyjR35 +FpTU7cmrtpAnI2NK09BvQ56MgTLbu/2z5CnIc1msapaTp+A91c9dfXPkqTCu +3tD7rTV5KuZzWoWaeXIt8gufV7uwayF/a6xPvUCeBu+xprZSK/I0RNwMMXez +pyPxaH+dnD0dg2293cpF8gx4Dn3zbuMK8gx4X1wZUsWeiQmt96yOPROnK2sH +fmDPgtUlwezMnoUq68YB+yVyAc362uIhmeQQ0KFv7tlEXi6gcNe2oAvkXQIG +PlJd3cp9NhwmF8aPcZ8NMbq54QPus9HuExi1l/tsFAXfqzNzr8PZyfauAu51 +uDR+ffA89zrcaDlSncG9DhFKVWgn93r031x3PZZ7PYYs87svc69HudfekXDu +9VB6HA6/xn0OtK6CKpD7HFQsFY3+wn0OhsOKt/txn4NM2eLUMPcGPNq6y9GL +ewNs3T4/9yf3Bjimr7jnxr0B+sCzKfe5N+K5qLKvn+XeiLHL5+wmuDciXygp +eJp7I+6/sVsxzb0JDyLFM47cm6AUmir+5d6Ek8FuJSu5N6HNnH5ohnsRJ757 +/bQd9yK84nx8LdyL8HX/faMt9yLai/aXzHKfC7NmysqG+1z4xZlK55b9P3Wy +qpc= + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{{0, 100}, {0, 140}}, + PlotRangeClipping->True, + PlotRangePadding->{Automatic, Automatic}]], "Output", + CellChangeTimes->{{3.514679942021348*^9, 3.514679972191387*^9}, { + 3.563586856008102*^9, + 3.5635868655932903`*^9}},ExpressionUUID->"480264ba-2562-4dc7-bcb9-\ +4c65467e27fc"] +}, Open ]], + +Cell[TextData[{ + "For r values between 0 and 2, we see a stable equilibrium, as we would \ +expect from the local stability analysis of ", + Cell[BoxData[ + FormBox[ + RowBox[{ + OverscriptBox["n", "^"], "=", "k"}], TraditionalForm]],ExpressionUUID-> + "b5a06d83-0ca3-43b9-9f07-181146e464d6"], + ". For 2{{3.514426786255549*^9, 3.5144268854843693`*^9}, + 3.514426993070139*^9},ExpressionUUID->"c8e6fc21-a714-4130-8bbf-\ +e21840bc1edd"], + +Cell["\<\ +Notice, though, that the oscillations get so large when 3", "Text", + CellChangeTimes->{{3.5146800211208067`*^9, + 3.514680060853672*^9}},ExpressionUUID->"c2f894fe-029c-42f0-9944-\ +db874a4a86f0"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"3.01", ",", "100", ",", "10", ",", "t"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{ + 3.5635869581883383`*^9},ExpressionUUID->"528b6743-9092-419f-a27c-\ +3f4fd0938e0e"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + "10", ",", "37.09`", ",", "107.32329019000001`", ",", "83.66590628397074`", + ",", "124.80076958174558`", ",", "31.636600168101538`", ",", + "96.73644512117787`", ",", "106.23915651397525`", ",", + "86.28759047933279`", ",", "121.90223487318028`", ",", "41.537300342465`", + ",", "114.63162004910633`", ",", "64.1465061129278`", ",", + "133.37278469331437`", ",", + RowBox[{"-", "0.602954254970058`"}], ",", + RowBox[{"-", "2.428789532820886`"}], ",", + RowBox[{"-", "9.917006486313436`"}], ",", + RowBox[{"-", "42.72744124136932`"}], ",", + RowBox[{"-", "226.28862985243444`"}], ",", + RowBox[{"-", "2448.7343801230736`"}], ",", + RowBox[{"-", "190308.05680263517`"}], ",", + RowBox[{"-", "1.0908995454760284`*^9"}], ",", + RowBox[{"-", "3.582086510593332`*^16"}], ",", + RowBox[{"-", "3.8622344745818025`*^31"}], ",", + RowBox[{"-", "4.489973396131099`*^61"}], ",", + RowBox[{"-", "6.068118190487475`*^121"}], ",", + RowBox[{"-", "1.108343957049122`*^242"}], ",", + RowBox[{ + "-", "3.697563244653191264540045141396927959214`15.954589770191005*^482"}], + ",", + RowBox[{ + "-", "4.11526415841128061168999232670582466147`15.653559774527023*^963"}], + ",", + RowBox[{ + "-", "5.0975551271448558500363916016640931663`15.477468515471298*^1925"}], + ",", + RowBox[{ + "-", "7.8215055505585225009096995224669183`15.352529778863042*^3849"}], + ",", + RowBox[{ + "-", "1.8413960672302749326630496664932664816822689668773`15.\ +255619765855103*^7698"}], ",", + RowBox[{ + "-", "1.0206125823997480108383284296086597930932`15.17643851980841*^15395"}\ +], ",", + RowBox[{ + "-", "3.135366630491573871616175534600249123445`15.10949173017689*^30788"}]\ +, ",", + RowBox[{ + "-", "2.958987696187625533996161653934552368813`15.051499783199061*^61575"}\ +], ",", + RowBox[{ + "-", "2.6354380640431150778127257611014152151068`15.0003472607494*^123149"}\ +], ",", + RowBox[{ + "-", "2.0906056706116038733979896900083673711137`14.95458977020536*^\ +246297"}], ",", + RowBox[{ + "-", "1.3155602530680114862098850546113952904967`14.913197085088537*^\ +492593"}], ",", + RowBox[{ + "-", "5.2094033261516346103744872929097582875103`14.875408524282419*^\ +985184"}], ",", + RowBox[{ + "-", "8.16850278737043332446433577529808064908283`14.840646417760492*^\ +1970367"}], ",", + RowBox[{ + "-", "2.00840557739708387130506968940859837127270662`14.808461734688132*^\ +3940734"}], ",", + RowBox[{ + "-", "1.214141581959233783615966398666684879417514369348`14.\ +778498510657915*^7881467"}], ",", + RowBox[{ + "-", "4.43716074093783681512816584251589729726`14.75046978753508*^\ +15762932"}], ",", + RowBox[{ + "-", "5.9262070277169234915425781237566112124`14.724140848447247*^\ +31525863"}], ",", + RowBox[{ + "-", "1.05710988503437965430647820822390146`14.699317264244346*^63051726"}]\ +, ",", + RowBox[{ + "-", "3.363618740202571864957860575605944951882399019991`14.\ +675836159286854*^126103450"}], ",", + RowBox[{ + "-", "3.40549323986202268818514997141345296052`14.653559795778348*^\ +252206899"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}], ",", + RowBox[{"Overflow", "[", "]"}]}], "}"}]], "Output", + CellChangeTimes->{3.514680019105529*^9, + 3.563586959255204*^9},ExpressionUUID->"d89c91cc-12a2-441b-994e-\ +f8c28ee9dfcb"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Question 6: Simulating extinction", "Subsubsection", + CellChangeTimes->{{3.51394814025489*^9, 3.513948145584239*^9}, { + 3.513948808098681*^9, 3.5139488496649723`*^9}, {3.5139491033219757`*^9, + 3.513949116352789*^9}, {3.5139539142255583`*^9, 3.513953950682358*^9}, { + 3.513954320569996*^9, 3.513954332097341*^9}, {3.514426735708166*^9, + 3.514426752358864*^9}},ExpressionUUID->"9553666f-de5a-407a-aeb9-\ +b5956a9e001b"], + +Cell["\<\ +Add an If[ ] statement to the above simulation to return zero if ever the \ +population size is predicted to be negative. + +Use this simulation to explore what happens with r = 3.01 (generate a table \ +as above, and ListPlot it).\ +\>", "Text", + CellChangeTimes->{{3.513947236964213*^9, 3.51394733823662*^9}, { + 3.5139475325082417`*^9, 3.51394758040838*^9}, {3.5139476417549477`*^9, + 3.513947714905636*^9}, {3.513947913524728*^9, 3.513947982531314*^9}, { + 3.513948017290382*^9, 3.513948113203456*^9}, {3.51394894565186*^9, + 3.513949092099876*^9}, {3.513953965380247*^9, 3.513954016760906*^9}, { + 3.513954339220845*^9, 3.513954345520956*^9}, {3.513954414894065*^9, + 3.513954469204207*^9}, {3.5144267563054047`*^9, 3.514426782297421*^9}, { + 3.5144269059322367`*^9, 3.514426945753895*^9}, {3.5144269968666162`*^9, + 3.514426997273953*^9}, 3.514516234152482*^9, {3.5635869214025097`*^9, + 3.563586945192173*^9}},ExpressionUUID->"bc9ffdcd-39e2-446e-92e6-\ +bc228d896b78"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"?", "If"}]], "Input", + CellChangeTimes->{{3.514679855133791*^9, + 3.514679855810052*^9}},ExpressionUUID->"b946961a-bc28-4972-bfb8-\ +e6f5e36fc209"], + +Cell[BoxData[ + RowBox[{ + StyleBox["\<\"\\!\\(\\*RowBox[{\\\"If\\\", \\\"[\\\", \ +RowBox[{StyleBox[\\\"condition\\\", \\\"TI\\\"], \\\",\\\", \ +StyleBox[\\\"t\\\", \\\"TI\\\"], \\\",\\\", StyleBox[\\\"f\\\", \ +\\\"TI\\\"]}], \\\"]\\\"}]\\) gives \\!\\(\\*StyleBox[\\\"t\\\", \ +\\\"TI\\\"]\\) if \\!\\(\\*StyleBox[\\\"condition\\\", \\\"TI\\\"]\\) \ +evaluates to True, and \\!\\(\\*StyleBox[\\\"f\\\", \\\"TI\\\"]\\) if it \ +evaluates to False. \\n\\!\\(\\*RowBox[{\\\"If\\\", \\\"[\\\", \ +RowBox[{StyleBox[\\\"condition\\\", \\\"TI\\\"], \\\",\\\", \ +StyleBox[\\\"t\\\", \\\"TI\\\"], \\\",\\\", StyleBox[\\\"f\\\", \\\"TI\\\"], \ +\\\",\\\", StyleBox[\\\"u\\\", \\\"TI\\\"]}], \\\"]\\\"}]\\) gives \ +\\!\\(\\*StyleBox[\\\"u\\\", \\\"TI\\\"]\\) if \ +\\!\\(\\*StyleBox[\\\"condition\\\", \\\"TI\\\"]\\) evaluates to neither True \ +nor False. \"\>", "MSG"], " ", + ButtonBox[ + StyleBox["\[RightSkeleton]", "SR"], + Active->True, + BaseStyle->"Link", + ButtonData->"paclet:ref/If"]}]], "Print", "PrintUsage", + CellChangeTimes->{3.5146798565246696`*^9}, + CellTags-> + "Info3514654656-5782146",ExpressionUUID->"353a083e-0028-4907-af1c-\ +6a1b1a33e6bc"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[{ + RowBox[{ + RowBox[{"Clear", "[", "logistic", "]"}], + "\[IndentingNewLine]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"r_", ",", "K_", ",", "n0_", ",", "t_"}], "]"}], ":=", + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"r", ",", "K", ",", "n0", ",", "t"}], "]"}], "=", + "\[IndentingNewLine]", + RowBox[{"Block", "[", + RowBox[{ + RowBox[{"{", + RowBox[{"n", "=", + RowBox[{"logistic", "[", + RowBox[{"r", ",", "K", ",", "n0", ",", + RowBox[{"t", "-", "1"}]}], "]"}]}], "}"}], ",", + "\[IndentingNewLine]", "\t", + RowBox[{"If", "[", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"newn", "=", + RowBox[{"n", "+", + RowBox[{"r", " ", "n", " ", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"n", "/", "K"}]}], ")"}]}]}]}], ")"}], ">", "0"}], ",", + "newn", ",", "0"}], "]"}]}], "\[IndentingNewLine]", "\t", "]"}]}]}], + "\[IndentingNewLine]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"r_", ",", "K_", ",", "n0_", ",", "0"}], "]"}], "=", + "n0"}]}], "Input", + CellChangeTimes->{{3.514424045707509*^9, 3.514424061967498*^9}, { + 3.5144255050950212`*^9, 3.514425607017445*^9}, {3.514425642488206*^9, + 3.514425669408059*^9}, {3.514425734177042*^9, 3.514425737442438*^9}, { + 3.514426238427285*^9, 3.5144262538256493`*^9}, {3.514426381804556*^9, + 3.514426383523755*^9}, 3.5144264576520653`*^9, {3.5144266314259853`*^9, + 3.5144266539839983`*^9}, {3.514427148128552*^9, 3.5144271570026703`*^9}, + 3.51455764587731*^9, {3.5145577020626297`*^9, 3.5145577196429243`*^9}, { + 3.514557809731855*^9, 3.5145578387179317`*^9}, {3.514557911737157*^9, + 3.514557912918582*^9}, {3.514558160949648*^9, 3.514558190734005*^9}, { + 3.5146815174664097`*^9, + 3.5146815247700777`*^9}},ExpressionUUID->"a743e79f-784f-46b2-8a37-\ +11af33266c90"], + +Cell[BoxData["n0"], "Output", + CellChangeTimes->{{3.51455764780307*^9, 3.514557665850696*^9}, { + 3.514557706400259*^9, 3.514557720460586*^9}, {3.514557841048443*^9, + 3.5145578490297413`*^9}, 3.514557916292965*^9, 3.514558191558956*^9, + 3.514679988385291*^9, + 3.514681525365872*^9},ExpressionUUID->"4e89080b-ade0-498d-acac-\ +484062e82c6d"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"logistic", "[", + RowBox[{"3.01", ",", "100", ",", "10", ",", "t"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"0", ",", "100"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "140"}], "}"}]}], "}"}]}], ",", + RowBox[{"Joined", "\[Rule]", "True"}]}], "]"}]], "Input", + CellChangeTimes->{{3.514679990422339*^9, + 3.5146799942618647`*^9}},ExpressionUUID->"c93ca56a-8631-450c-8711-\ +eebe63283128"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {Hue[0.67, 0.6, 0.6], LineBox[CompressedData[" +1:eJxdz8srRGEYx/EnK1YsLCzkMkmS3Bn3edwGg3GbGdcQYaPslJV3Q0lS/gAj +K0WxMyu9CykrGwuxsrAhpZRkhbyTzvet0+lzvv1O5+TPrQwvpIjIws/1e/87 +b4G/e4G6B/oylMjZ2G5zTtVEKHZ9djvhnKGXH/M1+88R50yNh9NvAlUzzlna +dLDZ8HkYcM7WxNn5c37ZmHOe+rZyR8O7yff59Ovu6XFpL6rJ79hZjPkv1qad +C/Vk67316rLDuUif4uury0dTzsV6+lAyOZs26FyioWDx/evxrHNp8r/cKYcr +4Eq4Cq6Ga+Ba2A/XwfVwA9wIN8HNcAscgNVrA0srOixt6LC0o8PSgQ5LJzos +QXRYutBh6UaHpQcdlhA6LL3osPShw9KPDksYHZYBdFgGvVbYwBaWIexhA1tY +hrGHDWxhGcEeNrCFJeK1wga2sES9VtjAFpYY9rCBLSyj2MMGtrCMea2wgS0s +49j/+xsM4H5E + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{{0, 100}, {0, 140}}, + PlotRangeClipping->True, + PlotRangePadding->{Automatic, Automatic}]], "Output", + CellChangeTimes->{{3.514679990940617*^9, 3.5146799947143707`*^9}, + 3.514681526880694*^9},ExpressionUUID->"3a56179d-ab8a-4830-9057-\ +a6b9f6854dc5"] +}, Open ]] +}, Open ]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Numerical solutions", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.514421605669952*^9, 3.51442160694818*^9}, {3.514427010309041*^9, + 3.514427012729041*^9}},ExpressionUUID->"58f64af0-0781-4aa2-9f1b-\ +9b347d3e61c6"], + +Cell[TextData[{ + "Differential equations can also be solved numerically using ", + StyleBox["Mathematica", + FontSlant->"Italic"], + "'s NDSolve routines, which can work even for models that cannot be solved \ +analytically." +}], "Text", + CellChangeTimes->{{3.5144216199985*^9, 3.514421620816608*^9}, { + 3.5144233861823177`*^9, 3.514423486185019*^9}, {3.5144270172409153`*^9, + 3.514427088047944*^9}},ExpressionUUID->"cd058551-75ba-4eb3-92b3-\ +0d5086978cd0"], + +Cell[BoxData[ + RowBox[{ + RowBox[{"logisticD", "[", + RowBox[{"r_", ",", "K_", ",", "n0_"}], "]"}], ":=", + RowBox[{"NDSolve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"D", "[", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}], "==", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}], " ", + RowBox[{"n", "[", "t", "]"}]}]}], ",", + RowBox[{ + RowBox[{"n", "[", "0", "]"}], "\[Equal]", "n0"}]}], "}"}], ",", + RowBox[{"n", "[", "t", "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]}]], "Input", + CellChangeTimes->{{3.51442706851635*^9, 3.51442712755998*^9}, { + 3.514427174650832*^9, 3.5144272211635733`*^9}, {3.563595943220928*^9, + 3.563595944102522*^9}},ExpressionUUID->"a9619a38-4615-45df-b3e5-\ +6c602325f296"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"logisticD", "[", + RowBox[{"0.5", ",", "100", ",", "10"}], "]"}]], "Input", + CellChangeTimes->{{3.514427227417859*^9, + 3.514427235453794*^9}},ExpressionUUID->"1f6d2dc1-7850-4998-91fd-\ +b519cf2402a1"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", + RowBox[{ + TagBox[ + RowBox[{"InterpolatingFunction", "[", + RowBox[{ + RowBox[{"{", + RowBox[{"{", + RowBox[{"0.`", ",", "100.`"}], "}"}], "}"}], ",", "\<\"<>\"\>"}], + "]"}], + False, + Editable->False], "[", "t", "]"}]}], "}"}], "}"}]], "Output", + CellChangeTimes->{3.514427237057322*^9, 3.563587020810622*^9, + 3.563595946820834*^9, + 3.563596060444139*^9},ExpressionUUID->"65dd93eb-fbdd-4bcb-9abc-\ +fe28e19a63fb"] +}, Open ]], + +Cell[TextData[{ + "Some notes: \n\t* We must use := here because we don't want the routine to \ +start calculating until we call it with specific values of the parameters.\n\t\ +* The code is very similar to DSolve, except that we must specify the time \ +frame over which we want a solution (here 0-100)\n\t* When we do call the \ +function, ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " tells us that it has represented the solution as a function, which we can \ +interrogate." +}], "Text", + CellChangeTimes->{{3.5144272409234343`*^9, + 3.514427375818904*^9}},ExpressionUUID->"17fe90c5-4054-4cf2-b34a-\ +604602898420"], + +Cell["\<\ +We can then evaluate this function at specific values or in a plot:\ +\>", "Text", + CellChangeTimes->{{3.514427526380866*^9, + 3.514427546611237*^9}},ExpressionUUID->"22dbf043-9638-4932-b9a9-\ +b678355f1c16"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{ + RowBox[{"logisticD", "[", + RowBox[{"0.1", ",", "100", ",", "10"}], "]"}], "/.", + RowBox[{"t", "\[Rule]", "20"}]}]], "Input",ExpressionUUID->"74f8c6a0-9134-\ +4d49-ab17-bc0960733b52"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{ + RowBox[{"n", "[", "20", "]"}], "\[Rule]", "45.08530884285847`"}], "}"}], + "}"}]], "Output", + CellChangeTimes->{3.563595951414206*^9, + 3.563596034115473*^9},ExpressionUUID->"23cdf5a0-e55d-4e76-aa15-\ +0c4584ea8e54"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{"Evaluate", "[", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "/.", + RowBox[{"logisticD", "[", + RowBox[{"0.1", ",", "100", ",", "10"}], "]"}]}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5144273849703627`*^9, 3.514427432709642*^9}, { + 3.563595959264803*^9, 3.5635959865084267`*^9}, {3.563596038646062*^9, + 3.563596041539015*^9}},ExpressionUUID->"a9699b78-7502-413f-9a1c-\ +0cd324b3563f"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {Hue[0.67, 0.6, 0.6], LineBox[CompressedData[" +1:eJwV1nk0FUwfB3Da7ErRIiJEilJJUtxvlOzufkcUkq61JBJRQtqRNpFQKEWh +vScJhZREaNGGbGkRsi/vvH/MmfM5Z86cOTPzW+Zv3cl2nyAiIvKZjv/ParGj +Vy7NKzJJ3ZlmLCKigfvi2iq+HikMpdCyTE1ZDRTtvZm+0OMWQ78ruounpIFS +vV3CKR6FjBHO2LoqQw2Un6ix+CesYpw5sNJS118DL4wiH/4UfmXcUm70SmzV +QMWphl3twj+MsrjET9z6BbAqELNrFY4zWlavMNas0UKljIHEpM3TsH+hi4FI +lg5MYzc8vWo/G6EhP06v7taD+9IhmWUyqmDb6V768nkFbLXd/87cqIGcBdsM +hnatQn5tWOALw4W4d6DKs3PRGqyZvujWpAM6aK5oqg5LYEA4HJ+cQfQQts5l +1YMFpthZ2rbilu1yBA0pSQ7vWY9jm6YsGPXRRw4/f2zO9I1wK9u3fZmHATKO +OhXNOW6JIrE5LG8HQ1iGZYrO/meNZXLh5zoCjCAfO2LkH2kHlx5jHTuftcjP +eVD7zJ2JtEvPlfpPmuD1g9eLsmJYuB1j1FDDBu4ma7psSmQj4JExM9lmHU5f +ufIoK5SDwoqM7qOOpjhlISP/WMCF58bVBZ7EDMF3kjWypHi4eG3ZXW+v9RBI +rFeQucvDqZ6Cg35BGzAo+FEoMOOj9XrgHg9/c8Rqpfqn3+HjmXl8QkTERpQz +HzSmKgkgav+xKTbcAgEhm94s2SFA+ROeekCUBTIlyo5wdgoQt6TajRyxgCVn +fkiQnwCqsuXfVeMs8Dxrm0SBvwCovNual2KBNztOtpoECRBuferH2ycWGM1P +GVMOF0DEwqJ71qgFFLqPFtqcol53TzQ12BLHI7+3RuUJsGl9W8X7MEtcZZ5d +HJcvwJ2Ns8/IRVjC04eZmXhbAA+7EM3IY5bItBhj5NwVoNrRxHp7kiVC01qm +v3gowOU9pWd0CiwxE9bZDUUCrM+u13ooYoW05QN8v2oBjszqt605bIUI3yTD +3b8FOFNe3lx83Ao+wnOm6/4IkBKcGHw71gotZ9Y+kO0S4F6DccaZ81aIPjOz +/epfAVpSokb4V60Q41O37W2vAKYLp99oKLVCXYaK9tRhAUYMdcVbJlsD3WL+ +SmIEfpvcivsjrbEw2zUiTZlANuXHt7VHrPHmU0W+4zyC7OZd4wdPWENL/ZG9 +ggpBm0/4Wumz1lj6+febaFWCLQeS76lmWsP06+TRreoENunvrluWW+NgbLNA +RJtg4W/r00nSNnDOfVhfvYKg8aD+NsZZGxh9iG5s2UigOVM2xu+CDZRLquL2 +WRB4XW+7n5ZsA/+TUhXTLAl6axKlJmXaYL98VsNqKwJxDdHb5fdsEK9+ISra +hmBJaaUo+70NdERXGUiyCEIkhSnb5trC/Nx95wIHAvnTFz4eTbPF7uKkpu+e +BJJ1M6r9M2zhbd7iIPAiEJkVU+aYZQvp4V/7XlD/Soy4o5tni9mi2kXZ3gSl +l71jqp/aQuzVQ/5OX4K9+camc77ZIutRe+N3P4LP1Y1Z1+bZYXNrjMLpIILM +aYuCy5LswFZ0CBePoudrdRiYlGoH+3dbduykvv/f0SDTdDs4uB4Wr6cu394R +WJBth7YJ5qaXDxH8eHzN/3aBHWyOJNcYHCbQ9dTySflqh+GxuhTmMYI7RRrO +Qer2mKYjf9cijqDIX2WD1g17hBrmTCFJBEP//sQp3bKH3OBifia1fvDTT3K3 +7eF8Ntuzl/raAdeAkUf2cC/y+hx7kSDuxJUr1RX2mHr0y0hJMoFLptaE0B/2 +MGh9ajY/lWD853nndnkmUt2DF+alE1xSTVUy5jJx2ax5cEkO/S/HlpXr8pm4 +UmvE2kF9oKd49zzCRI/Wg7051C6lLRXjjkwwAu8ZLr5JoOazOLjYjYmvFsXh +Grfofd2/V7dxNxMPSueyZPMIbtpVxrDjmdB99baz8A5BQeiQiMcbJg5LSTSn +/UfQd6u1K6KGiUvFHYUfqfWaa74l1zKxd3qP74zHBOmWN56+fc+EzaCiSRT1 +sZlO4YxGJtbbitx2KyDg5xaMz+ym53PSkFMsJPjTHD72fAYL0SoG192LCeZb +i42oC1jI+ipz7UA5vb86sxpFBxZeN9lWX6c2dw6/JufIgrQ040MdtdfuQe74 +FhYuuCcfWvyCvk9SZ87H7SxsMdfk1FGb/6xyPrWHhZuWlu/VXtL1JxNKxs6y +oKK53ySzkq6v0j7+oZaFXmVJIaeGvod6UcZQPQthLhv7gqm9g8jTuR9Y+JKg +5Z5KraZy+N/mzyzsaTNp+kkdu+O7c1MLC7ObKpyi3tL9ZVL0O/tYGA4TeufU +Eqhay38Zmc2G/NQj2e31BCdKx/RUN7MRsj2wR7yBALtalyk7s6F20VJNk7p3 +7uvliq5s9GktNTKjdtqVrC/vzoa4yN4FYdS6SmsNxX3ZMG6e9PMP9etdwYyu +UDbGRXQtqz8RTFPutX16kY0Cfb/iyC8Ep3d3eLl8YqMnfKHWjUYCRfOQXZwv +bKj/TbpaTH15ttRe829sfA7oUPhInV+gc0jnOxvPq6wfizcRvBHzSxnoZEN4 +sGCZO7Xsxb63ccNsVJnVvFRsJjjybKJxkSIHP2p/qAR/JwhVmDdVzYED9qWM +iZPbCCrzJDYxHDlQe202RZF6nt2/dKfNHDSXoH8JdWH0K6PzrhzUlcenE+oJ +AyHbpb04aMhZveQG9eGP7wr6Quh+sZmStu0E8SmnfF5e5MBgvRozqoMgS3ty +RcA3DhiGwr8lnQQ1SuuGfZs4SN4r+e4t9cjUMB3hdw4CP6zMbaa26+uNcWjn +oOiVjfHEn/S+i79zTLo4mLg4vmQdNZyefRYT4eKXvd7Rx9TvYyL/Jqpw8UmH +a5L1i2BKr+icoi1cBJ0aZrj+IRjITYj57sLFos1qHjupO32XThJ3oz5oFBVG +/abN6Y+dkAsdN2HCBerEhvvPP+3kQvlw1bJq6iUlvv4D4VzkyTxcZtJF4yP+ +w8ulV7g4JPMne+pfgqt6efsvtXEx19k1P76bYIfC38H7HVx0X0z+nUytP6QX +WN3JRWNawPws6qclud6TurhwnyjnXUj9np9LvAa4CF9ZF9NJLR52a7mBBA9d +H+aqmPYQeLzIaa1cxMMaM83z7dTaW6/bjfry4PxhwmGlfzQ/Jhvldu/kwfZu +j9gC6u0fKuTad/HwYsqGCF3qdGZnbU0gD2pTldxMqFUZOo7XwnhYWK9a70w9 +U+mmkHOSB6/1Nw+lUU+ozwvPyubh3HtVHdU+ggbLh/m8Th745zJTpfoJTO3T +SeAvHnbw362cQX2dGzt25g8P3g3pzxSpQ5zdrWp7eHjpv6RKm1oxUK6JPcLD +canzCRupSaqnHFOGj81tjSIR1PV9c/yslvJx+UuQRTd1zZUQXcZuPrJToh4X +DRBMF7n30CiQj7HPHXvKqDlOfzcYBPGReLFcp5K6Vt5ji+4+PhrHRY+/p353 +iBc7N5IPZfU3cn+oPwn1/vbH8/FkfJXN3EGClsWtd3Lz+Yh/PvukH/XAbdZa +tW4+tnoVdsgOEUgbGrye0cvHDUm3QzOoVR8rukzu44MI/ZVnU1s8a45sH+Sj +I+Or6XzqC7WBL2+KCqDlYea2gtro34VNa+QEUIvMGuFThxo07eXqCZCn/jgj +iXr8gf/daNqXTavcu23uMD3flPzjl2kfpnwgIUKF+hH3r+sT2oetXI5kdeqA +rp2yfXsE2Pdlefli6nYtX6H7AQGMNHp711DXnBPOWR8nwJjk5mxH6owApzBR +2nflBYdlJlBb65lvCP0nwLOb/9wkRmg9r6sTDegXQG9HW7g09b1g9yfegwJo +pgiTplKrlUStchwVoOyI4gsF6iFeibbRZIKwb6FiatTX90F2QJ7mydelckbU +EmVG73brE/RISXh6UJdtXurpvZvGrbTU4SfU0908/ksOJFDeWuJaRL3FI03m +De0DDqmPrn5G3ec/I18/lIDxaaTpBbXGkf6hUVr3TxRsm1VHHZ5feCLuHO1T +RE9LdVIbiTFz7z4k8E2wX6owShAtfXRCO61z2eayT2ZRV8sVcxWf0Lz346SV +IrWHkv7gflq3zCa9d1KhPr9stqkFrTP9s6q2a1P3On57+5Hm5daDk6cbU8N1 +jqbMVwKFyqIwBvXx7ey9DJp3T9VsaVtHrbbrmVJ6C0HCqOkdc2pW9DV33980 +jnw69ZnUF4833k+heeLd/JZYNnV7nKJkDY3rtQFV7Vzq8KQTNw3oP5/7LeyM +A/Wr1OcinvQf6nRvaHOknpU5xk6i7yYdP8VwC/XWG6syKuk85XFRtAudb+b6 +9Y+PE2zzCX67lfp/ZXdnMA== + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{{0, 100}, {0., 99.95915686471704}}, + PlotRangeClipping->True, + PlotRangePadding->{ + Scaled[0.02], + Scaled[0.02]}]], "Output", + CellChangeTimes->{{3.5144273941075277`*^9, 3.514427433213737*^9}, + 3.5144275737468023`*^9, 3.563587020871086*^9, {3.5635959651869307`*^9, + 3.563595986989359*^9}, + 3.563596050730527*^9},ExpressionUUID->"57d7f0df-c484-49ec-99c6-\ +f0290561e912"] +}, Open ]] +}, Closed]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Part 4: Example of building a model from scratch", "Section", + CellChangeTimes->{{3.513954497848974*^9, 3.513954512594667*^9}, + 3.514165209759124*^9, {3.5145122512870913`*^9, 3.514512262071327*^9}, + 3.620056533466091*^9},ExpressionUUID->"f9d39d79-2a68-422a-a40f-\ +655b104ca3d5"], + +Cell[TextData[{ + StyleBox["Scenario: ", + FontWeight->"Bold"], + " Let's model the number of species on a large landmass over long periods of \ +evolutionary time, where the number of species is primarily influenced by \ +speciation and extinction events within the landmass. If extinction risk, d, \ +is constant per species but speciation rate declines from an initial value, \ +b, exponentially with the number of species already present (because of \ +competition for overlapping resources/niches), then develop a model that \ +might describe the number of species, n, on the landmass." +}], "Text", + CellChangeTimes->{{3.514512133202097*^9, 3.514512218390479*^9}, { + 3.5145122751264963`*^9, 3.514512297988493*^9}, {3.514514376589346*^9, + 3.514514458902255*^9}, {3.514514572866433*^9, 3.5145145941994133`*^9}, { + 3.514514631370022*^9, 3.514514661182852*^9}, {3.5145150056463737`*^9, + 3.514515014249876*^9}, {3.563587074926766*^9, 3.563587075110824*^9}, { + 3.563595436071618*^9, 3.563595441232374*^9}, + 3.620056533466344*^9},ExpressionUUID->"5001d2bb-dd3f-4e30-a192-\ +73e2954ad9b7"], + +Cell[CellGroupData[{ + +Cell["Discrete-time approach", "Subsection", + CellChangeTimes->{{3.563595464831003*^9, 3.5635954688845663`*^9}, + 3.6200565334667587`*^9},ExpressionUUID->"7e12f097-d403-4e1e-8056-\ +efda95e775ee"], + +Cell["\tn[t + 1] = n[t] - d n[t] + b n[t] Exp[-a n[t]]", "Text", + CellChangeTimes->{{3.563595437816786*^9, 3.563595471789021*^9}, + 3.620056533466886*^9},ExpressionUUID->"79f8d706-301d-446b-85c0-\ +dde780c58e76"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"nhat", "==", + RowBox[{"nhat", "-", + RowBox[{"d", " ", "nhat"}], " ", "+", " ", + RowBox[{"b", " ", + RowBox[{"Exp", "[", + RowBox[{ + RowBox[{"-", "a"}], " ", "nhat"}], "]"}], " ", "nhat"}]}]}], ",", + "nhat"}], "]"}]], "Input", + CellChangeTimes->{{3.5145620885906353`*^9, 3.5145620954550447`*^9}, { + 3.514562234647851*^9, 3.514562271064756*^9}, {3.514680167209667*^9, + 3.514680173982081*^9}, + 3.620056533467078*^9},ExpressionUUID->"dacf77d1-44f5-4b43-bc29-\ +0fa0d5ac36d1"], + +Cell[BoxData[ + RowBox[{ + RowBox[{"Solve", "::", "\<\"ifun\"\>"}], ":", + " ", "\<\"Inverse functions are being used by \\!\\(Solve\\), so some \ +solutions may not be found; use Reduce for complete solution information. \\!\ +\\(\\*ButtonBox[\\\"\[RightSkeleton]\\\", ButtonStyle->\\\"Link\\\", \ +ButtonFrame->None, ButtonData:>\\\"paclet:ref/message/Solve/ifun\\\", \ +ButtonNote -> \\\"Solve::ifun\\\"]\\)\"\>"}]], "Message", "MSG", + GeneratedCell->False, + CellAutoOverwrite->False, + CellChangeTimes->{3.5145622716008863`*^9, 3.514680170721435*^9, + 3.620056533467277*^9},ExpressionUUID->"2e40cf07-d7ef-4af0-b00c-\ +a6a586d9abd1"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"nhat", "\[Rule]", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"nhat", "\[Rule]", + FractionBox[ + RowBox[{"Log", "[", + FractionBox["b", "d"], "]"}], "a"]}], "}"}]}], "}"}]], "Output", + GeneratedCell->False, + CellAutoOverwrite->False, + CellChangeTimes->{3.514562271602889*^9, 3.5146801707235937`*^9, + 3.620056533467616*^9},ExpressionUUID->"c4963338-8faa-49cc-b25d-\ +914e2345320b"] +}, Open ]], + +Cell["\<\ +Here, I've used nhat to stand for the equilibrium. The first equilibrium to \ +consider is the no-species case. The second equilibrium is biologically \ +valid only if it is not negative, which requires that b>d. + +The first equilibrium (no-species case) will be unstable if \[Lambda]>1, \ +which the following shows requires that b>d, that is, if speciation is more \ +common than extinction when there are few species present:\ +\>", "Text", + CellChangeTimes->{{3.51468019478463*^9, 3.5146802491594763`*^9}, + 3.563595606869961*^9, {3.619865943392826*^9, 3.619866008462476*^9}, + 3.620056533467946*^9},ExpressionUUID->"757b6524-1bbf-4879-9643-\ +9ab3ba6b6485"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{ + RowBox[{"D", "[", + RowBox[{ + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + RowBox[{"d", " ", + RowBox[{"n", "[", "t", "]"}]}], "+", + RowBox[{"b", " ", + RowBox[{"n", "[", "t", "]"}], " ", + RowBox[{"Exp", "[", + RowBox[{ + RowBox[{"-", "a"}], " ", + RowBox[{"n", "[", "t", "]"}]}], "]"}]}]}], ",", + RowBox[{"n", "[", "t", "]"}]}], "]"}], "/.", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", "0"}]}]}]], "Input", + CellChangeTimes->{{3.514118347956435*^9, 3.5141183994468813`*^9}, { + 3.514118454362989*^9, 3.514118457111812*^9}, 3.514514816409915*^9, { + 3.514514936011118*^9, 3.5145149387008944`*^9}, {3.514514977671487*^9, + 3.514514978516873*^9}, {3.514515030612793*^9, 3.514515032579115*^9}, + 3.514680145041581*^9, 3.5146801883101683`*^9, + 3.620056533468133*^9},ExpressionUUID->"70d54709-16b4-4d50-a40c-\ +1deef37762f8"], + +Cell[BoxData[ + RowBox[{"1", "+", "b", "-", "d"}]], "Output", + GeneratedCell->False, + CellAutoOverwrite->False, + CellChangeTimes->{{3.514118386149518*^9, 3.514118407945298*^9}, + 3.514118459061335*^9, {3.514514817823138*^9, 3.514514852099307*^9}, { + 3.51451488720148*^9, 3.514514904294133*^9}, {3.514514936618411*^9, + 3.514514944362132*^9}, 3.5145149819696913`*^9, 3.514515034074918*^9, + 3.514680151955868*^9, + 3.6200565334682713`*^9},ExpressionUUID->"2e775eb2-64a7-4bb7-929c-\ +d14d1bd552fa"] +}, Open ]], + +Cell["Now considering the second equilibrium:", "Text", + CellChangeTimes->{{3.514680256839128*^9, 3.514680314061429*^9}, { + 3.563595612997179*^9, 3.563595620432363*^9}, 3.619865941376807*^9, + 3.620056533468383*^9},ExpressionUUID->"32c6ad4a-b22f-4b98-909d-\ +6a336cd16ac2"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{ + RowBox[{"D", "[", + RowBox[{ + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + RowBox[{"d", " ", + RowBox[{"n", "[", "t", "]"}]}], "+", + RowBox[{"b", " ", + RowBox[{"n", "[", "t", "]"}], " ", + RowBox[{"Exp", "[", + RowBox[{ + RowBox[{"-", "a"}], " ", + RowBox[{"n", "[", "t", "]"}]}], "]"}]}]}], ",", + RowBox[{"n", "[", "t", "]"}]}], "]"}], "/.", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", + FractionBox[ + RowBox[{"Log", "[", + FractionBox["b", "d"], "]"}], "a"]}]}]}]], "Input", + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9, 3.51451505271852*^9, 3.514515317606764*^9, { + 3.514680321148003*^9, 3.5146803269805403`*^9}, + 3.6200565334685907`*^9},ExpressionUUID->"6897de05-9760-40e5-bd0e-\ +d19d142f71ec"], + +Cell[BoxData[ + RowBox[{"1", "-", + RowBox[{"d", " ", + RowBox[{"Log", "[", + FractionBox["b", "d"], "]"}]}]}]], "Output", + GeneratedCell->False, + CellAutoOverwrite->False, + CellChangeTimes->{ + 3.5141184099144697`*^9, 3.5141184643525333`*^9, {3.514514825051873*^9, + 3.514514854280603*^9}, {3.514514890991288*^9, 3.514514907147491*^9}, + 3.514514946481635*^9, {3.514515036962925*^9, 3.514515053139289*^9}, + 3.514680327392661*^9, + 3.6200565334687243`*^9},ExpressionUUID->"7260dc89-b4fe-4f2c-9a06-\ +200ac7c2c000"] +}, Open ]], + +Cell[TextData[{ + "As this second equilibrium is only biologically valid when b>d, we know \ +that \[Lambda] must be less than one:\n\t\[Lambda] will be between 0 and 1 \ +if:\t0<", + Cell[BoxData[ + RowBox[{"d", " ", + RowBox[{"Log", "[", + FractionBox["b", "d"], "]"}]}]], + CellChangeTimes->{ + 3.5141184099144697`*^9, 3.5141184643525333`*^9, {3.514514825051873*^9, + 3.514514854280603*^9}, {3.514514890991288*^9, 3.514514907147491*^9}, + 3.514514946481635*^9, {3.514515036962925*^9, 3.514515053139289*^9}, + 3.514680327392661*^9},ExpressionUUID-> + "e1f6299d-2b2d-4eb0-b55d-fee74721c19a"], + "<1\t\t", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"774edd9a-9a67-44d0-8a8a-020a73dbe7a3"], + "=", + Cell[BoxData[ + FractionBox[ + RowBox[{"Log", "[", + FractionBox["b", "d"], "]"}], "a"]], + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9, 3.51451505271852*^9, 3.514515317606764*^9, { + 3.514680321148003*^9, 3.5146803269805403`*^9}},ExpressionUUID-> + "d7ae64a2-19dc-4815-9c76-bc68706874fa"], + " is a stable equilibrium\n\t\[Lambda] will be between -1 and 0 if:\t1<", + Cell[BoxData[ + RowBox[{"d", " ", + RowBox[{"Log", "[", + FractionBox["b", "d"], "]"}]}]], + CellChangeTimes->{ + 3.5141184099144697`*^9, 3.5141184643525333`*^9, {3.514514825051873*^9, + 3.514514854280603*^9}, {3.514514890991288*^9, 3.514514907147491*^9}, + 3.514514946481635*^9, {3.514515036962925*^9, 3.514515053139289*^9}, + 3.514680327392661*^9},ExpressionUUID-> + "dffa81c0-13cc-4fdf-ade7-a1f29e29d1b6"], + "<2\t\t", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"3b86bee2-cfc3-4e5d-9b41-ae5ea68a90f4"], + "=", + Cell[BoxData[ + FractionBox[ + RowBox[{"Log", "[", + FractionBox["b", "d"], "]"}], "a"]], + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9, 3.51451505271852*^9, 3.514515317606764*^9, { + 3.514680321148003*^9, 3.5146803269805403`*^9}},ExpressionUUID-> + "78f8dec1-37ef-4c36-a16e-21586e953bc5"], + " is a stable equilibrium with damped oscillations\n\t\[Lambda] will be less \ +than -1 if:\t", + Cell[BoxData[ + RowBox[{"d", " ", + RowBox[{"Log", "[", + FractionBox["b", "d"], "]"}]}]], + CellChangeTimes->{ + 3.5141184099144697`*^9, 3.5141184643525333`*^9, {3.514514825051873*^9, + 3.514514854280603*^9}, {3.514514890991288*^9, 3.514514907147491*^9}, + 3.514514946481635*^9, {3.514515036962925*^9, 3.514515053139289*^9}, + 3.514680327392661*^9},ExpressionUUID-> + "876d6347-8a4d-4379-81c8-b99ba9b511be"], + ">2\t\t\t", + Cell[BoxData[ + FormBox[ + OverscriptBox["n", "^"], TraditionalForm]], + CellChangeTimes->{{3.514117010038558*^9, 3.514117037752617*^9}}, + ExpressionUUID->"f1118195-a0cc-4337-84b4-09781c07fcbe"], + "=", + Cell[BoxData[ + FractionBox[ + RowBox[{"Log", "[", + FractionBox["b", "d"], "]"}], "a"]], + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9, 3.51451505271852*^9, 3.514515317606764*^9, { + 3.514680321148003*^9, 3.5146803269805403`*^9}},ExpressionUUID-> + "4a7af36f-7ac6-4387-ba7d-a37544c98838"], + " is an unstable equilibrium with growing oscillations" +}], "Text", + CellChangeTimes->{{3.51468033295153*^9, 3.514680358685945*^9}, { + 3.51468039400795*^9, 3.514680444895501*^9}, 3.620056533469767*^9, { + 3.7881791882723227`*^9, + 3.788179190772379*^9}},ExpressionUUID->"e87db525-cef4-44ae-83fc-\ +7e378908e535"], + +Cell["For example, b must be greater than 27.3 if d = 0.5:", "Text", + CellChangeTimes->{{3.514680472904222*^9, 3.514680510757698*^9}, + 3.6200565334698763`*^9},ExpressionUUID->"5b95f0c5-09b6-491e-83d4-\ +02f5ba491ff0"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{ + RowBox[{"d", " ", + RowBox[{"Log", "[", + FractionBox["b", "d"], "]"}]}], "\[Equal]", "2"}], ",", "b"}], + "]"}]], "Input", + CellChangeTimes->{{3.5145153315226717`*^9, 3.5145153370939093`*^9}, { + 3.514680462641665*^9, 3.514680489888875*^9}, + 3.6200565334700203`*^9},ExpressionUUID->"ebf97833-1d1c-448f-bc07-\ +b0e3e3b4bc58"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{"b", "\[Rule]", + RowBox[{"d", " ", + SuperscriptBox["\[ExponentialE]", + RowBox[{"2", "/", "d"}]]}]}], "}"}], "}"}]], "Output", + GeneratedCell->False, + CellAutoOverwrite->False, + CellChangeTimes->{ + 3.514515338434828*^9, {3.5146804675895844`*^9, 3.5146804967100554`*^9}, + 3.620056533470158*^9},ExpressionUUID->"f5e77a29-becb-4327-ab99-\ +cb096a1fee80"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"%", "/.", + RowBox[{"d", "\[Rule]", "0.5"}]}]], "Input", + CellChangeTimes->{{3.514680493151495*^9, 3.514680498246073*^9}, + 3.620056533470278*^9},ExpressionUUID->"b77696b3-0607-4130-af39-\ +3af596842bd8"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{"b", "\[Rule]", "27.299075016572118`"}], "}"}], "}"}]], "Output", + GeneratedCell->False, + CellAutoOverwrite->False, + CellChangeTimes->{{3.5146804952080173`*^9, 3.514680498497553*^9}, + 3.620056533470394*^9},ExpressionUUID->"602f541e-f6c6-4693-b6d8-\ +2956887f9d9f"] +}, Open ]], + +Cell["Simulations:", "Text", + CellChangeTimes->{{3.5146805154752502`*^9, 3.514680518717536*^9}, + 3.620056533470502*^9},ExpressionUUID->"dfa9fe7d-52f5-4709-adbc-\ +7c86baf09615"], + +Cell[BoxData[{ + RowBox[{ + RowBox[{ + RowBox[{"species", "[", + RowBox[{"b_", ",", "d_", ",", "a_", ",", "n0_", ",", "t_"}], "]"}], ":=", + + RowBox[{ + RowBox[{"species", "[", + RowBox[{"b", ",", "d", ",", "a", ",", "n0", ",", "t"}], "]"}], "=", + "\[IndentingNewLine]", + RowBox[{"Block", "[", + RowBox[{ + RowBox[{"{", + RowBox[{"n", "=", + RowBox[{"species", "[", + RowBox[{"b", ",", "d", ",", "a", ",", "n0", ",", + RowBox[{"t", "-", "1"}]}], "]"}]}], "}"}], ",", + "\[IndentingNewLine]", "\t", + RowBox[{"n", "-", + RowBox[{"d", " ", "n"}], "+", + RowBox[{"b", " ", "n", " ", + RowBox[{"Exp", "[", + RowBox[{ + RowBox[{"-", "a"}], " ", "n"}], "]"}]}]}]}], "\[IndentingNewLine]", + "\t", "]"}]}]}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{"species", "[", + RowBox[{"b_", ",", "d_", ",", "a_", ",", "n0_", ",", "0"}], "]"}], ":=", + "n0"}]}], "Input", + CellChangeTimes->{{3.514424045707509*^9, 3.514424061967498*^9}, { + 3.5144255050950212`*^9, 3.514425607017445*^9}, {3.514425642488206*^9, + 3.514425669408059*^9}, {3.514425734177042*^9, 3.514425737442438*^9}, { + 3.514426238427285*^9, 3.5144262538256493`*^9}, {3.514426381804556*^9, + 3.514426383523755*^9}, 3.5144264576520653`*^9, {3.5144266314259853`*^9, + 3.5144266539839983`*^9}, {3.514427148128552*^9, 3.5144271570026703`*^9}, { + 3.514515141529313*^9, 3.5145151955683947`*^9}, {3.514515245461218*^9, + 3.5145152467156477`*^9}, + 3.6200565334707613`*^9},ExpressionUUID->"a9c27bf1-3e48-4a2b-9665-\ +0ae68b43f061"], + +Cell["and plot this list:", "Text", + CellChangeTimes->{{3.5144263221305637`*^9, 3.514426329021406*^9}, { + 3.514426565192073*^9, 3.5144265653575697`*^9}, + 3.6200565334708652`*^9},ExpressionUUID->"cce32caf-a2ac-4ca5-ba9a-\ +e8e9a1ac094c"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"species", "[", + RowBox[{"28", ",", "0.5", ",", "0.01", ",", "10", ",", "t"}], "]"}], + ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "200"}], "}"}]}], "]"}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{"All", ",", + RowBox[{"{", + RowBox[{"0", ",", "700"}], "}"}]}], "}"}]}]}], "]"}]], "Input", + CellChangeTimes->{{3.5144263013250847`*^9, 3.514426303622571*^9}, + 3.514515294826396*^9, {3.514515415614575*^9, 3.514515437932662*^9}, { + 3.514680524896224*^9, 3.514680527822625*^9}, {3.5146806365544662`*^9, + 3.514680652966771*^9}, + 3.620056533471031*^9},ExpressionUUID->"c7fb5c51-1831-4453-af5b-\ +47bede8f7315"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {Hue[0.67, 0.6, 0.6], LineBox[CompressedData[" +1:eJw9zQlYk4cdx/EgR1MuuRQFGsIhBaZyKIgg8uNGziSEMxCSkAQYKOoKAoJE +EBRErCjOiqu0IFU6pSvIVrA8Eaco4jV1tIgVsB4T7NAyEWvZ3NP83zxPnvf5 +5/N+87OT5QsUC1gs1pV33/8/f/tMB/z2dITmB7Qe5E5/uWyz5mZj2Elvr6F1 +leY2wcqphva57YWa2wINJcPsi6WlmnsJaj+8XvheE7kN/A9VBg/FknPRvtTt +/L4ucns47NzXsN+F3BHnTj3omr1C7gQry7rkTn1yZ1yuNjRYO0ruil57Y7v2 +6e2aezn68wq/eDtJvhKV13r+IR0hd4cRe/6TvjlyDyh3Qrh4gNwTbUq/2nu6 +2zT3Knzz6w7LNd3kq5HsLOQfNSH3QshPvB8SvyD3Ru6dZ56eVuRrsEvsn2J3 +lNwHLxuG2Dfsydeizm06XFhP7gu9p/EOh1zJ/VDs5XSlp5J8HdzVb/ifepD7 +41mflrlrCfl6TDSminR9yANQXS6wKt9CDkysmza9769xFZDcwh89lkMeCM6O +MAfvYPJAuEZsWJorIw8CvyHjLCeCPAiteyMy7orIg3GPNf3g82jyYPCMP4kd +TCAPgZv+uP41HnkIvC/Xsv145KHI2HTTp01IHoqtXb3fWkWRh6FgXhbknUwe +htuzlkJxGHk4/Gxe6u4SkYejzWma8zaQPAI7f+9R3ygmj4DpEOvEpD/5BoTq +9XtslpJvwM9xCVuW+ZJHopvldnqJnDwST/M6pz73Jo/CodYCn4NK8ihcahr0 +F68ij8bYi7kjD7PJo6HsvLpS4E4egz1uh92Ncslj8NhWZFmygjwWg69i9c03 +ksei75H+4C1X8jiIy5Y8mt1EHoczwu5dCc7kPAhGtP37NmscPBjs83uo5aRx +FQ82T5bGZ2/VuJoHs3yXO7cdqOfDYt569es/UM/H4DKj/ZftqOejIi65L7+A +ej46TljV3belXoDm5X9tu1lIvQCXfF6XmnCoF6Bm3rbMpoh6AQyF5WEZNtTH +46uwuK+ExdTHI9ow5pcBK+rj8d1ZzwMlJdTHY6mO9nDEUuqFSHs8mrB/O/VC +yF9wfMcsqRdiNNfW5lAp9UJ8zI1vq1tMfQLWHxyerCmjPgHeIzG90YuoT0BI +4Ou/bdlBfQKs8sdW2VpQn4iRiymK6HLqE+FjUPxwgTn1ibByTuq3UlGfiKeK +HztfmVKfhAJhQMN9ciShVze2Zc6E+iTUth+vadxJfRKiXLf165OzkqH6LI8X +XEF9MoQHPljlspD6ZPQ1GFY+IVcnIzywzkloTH0KvFdEdFZUUp+CGT5/tNaI ++hQcbnLIWbSL+hS0p1p8NmRIfSqUWi0OzeRIxbHzNdeWkKtSMd1UmuJQRX0q +jraVX9xkQL0IK2p6io+TQwTf/Vqz1/SpF6HzVcyURTX1Iswmfvy9FzkrDaXB +jWa7yJGGlV55z0+8T30ahvL/Gf6c6dMQ8++fej4gZ6XDzKhjnLeb+nSc3DNz +6xib+nSYnCtx7yBXpyN2hnfFnpwlRoTzX8rZe6gXY7qYv77jPerFuCdctzid +XC3GTGvEnUByVgY4swPep5k+A6+7HVaP6FGfgYpqfe4c07/zTrZhETlLgqI/ +so0CazTOlWC9z1tja3JI8LVevFcVuUSCenH9TL8u/b8EW/Jw7SJ5swQLTOuL +8snVEgwH2etp12p8TIKN7v2pXHKWFIdtC439yblSRBudFN/VoX0phEnmZh+R +S6Sw6/WOqidXSXEzOcH3JHmzFDq3255FkqulmNUNPvM9sy9FX8h6fQNylgx7 +Ijsb2HtpX4b0B7Yl17VpX4Y6l3x9L3KJDF1BHKNGcpUMjwv43hnkzTJIXx44 +IiZXy2CokHvtJh+TwS7Sc8aVnJWJSadfHU8z+5noXvJibm4B7Wfizam73FvM +fia2/vm7qqvkqkxYdDgG/8zsZ+I5d6rgOLn63fsxXa3mdbSfif+ef7+9gJwl +R5PObJonOVeOHtEN7VhmX47fbbOuiCOXyHFHoFI6M/tyKJ9wXHLJm+X4JfN5 +tw6zL0dY3Q+KKmZfDsFk+r0JLdpX4PHtD6M+ZfYVsDxS0ttPDgVK2gaenWX2 +FWjYuhat5CoFPuo9kjDE7CvQbHM1fje5WoGFpgeaxpl9BSzW1IznMvtKRDZe +v/ofZl+JH4cf3eUz+0roGrfMsPfRvhLN8yLOWmZfCauY4w7W5M1KcF5JTtkx ++0oEnPuTYjn5mBLqg4lKA2Y/C0VRQ5fWkXOz0BK6I/QVi/azkDt0VhDN7Gdh +3cTUmglyVRYuXIi0EDH7WXBcUe52g1ydhc3f/GtRDrOfhWDdG5xvyVnZuLMw +S1rI7Gfj7x4uc18y+9nIyLFgVTL7796/UPl1E7OfjeqWgTf1zH42WDoFAXXM +fjbObBxPOcrsZ6NswrWxjNnPgVlF/LITzH4OYidkp/Lf+f8AYwxgHw== + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{All, {0, 700}}, + PlotRangeClipping->True, + PlotRangePadding->{Automatic, Automatic}]], "Output", + GeneratedCell->False, + CellAutoOverwrite->False, + CellChangeTimes->{{3.514515267681076*^9, 3.514515295301469*^9}, { + 3.5145154162527847`*^9, 3.514515438341056*^9}, 3.514680528178451*^9, { + 3.514680636985405*^9, 3.5146806534961987`*^9}, + 3.6200565334727573`*^9},ExpressionUUID->"e30590a9-c540-40ed-8ba0-\ +050cdb5befc3"] +}, Open ]], + +Cell["\<\ +There is no general solution, as we might expect from the oscillations seen \ +above:\ +\>", "Text", + CellChangeTimes->{{3.51456273103664*^9, 3.514562734543154*^9}, { + 3.514680544193344*^9, 3.514680554486227*^9}, + 3.620056533472889*^9},ExpressionUUID->"5bdff7e1-684c-4997-9893-\ +1a80a59e1f64"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"RSolve", "[", + RowBox[{ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "==", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + RowBox[{"d", " ", + RowBox[{"n", "[", "t", "]"}]}], "+", + RowBox[{"b", " ", + RowBox[{"Exp", "[", + RowBox[{ + RowBox[{"-", "a"}], " ", + RowBox[{"n", "[", "t", "]"}]}], "]"}], " ", + RowBox[{"n", "[", "t", "]"}]}]}]}], ",", + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}]], "Input", + CellChangeTimes->{{3.514562737880988*^9, 3.5145627624916687`*^9}, + 3.620056533473072*^9},ExpressionUUID->"58a7e84e-bc5e-4cd9-b543-\ +49962fd9bf0a"], + +Cell[BoxData[ + RowBox[{"RSolve", "[", + RowBox[{ + RowBox[{ + RowBox[{"n", "[", + RowBox[{"1", "+", "t"}], "]"}], "\[Equal]", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + RowBox[{"d", " ", + RowBox[{"n", "[", "t", "]"}]}], "+", + RowBox[{"b", " ", + SuperscriptBox["\[ExponentialE]", + RowBox[{ + RowBox[{"-", "a"}], " ", + RowBox[{"n", "[", "t", "]"}]}]], " ", + RowBox[{"n", "[", "t", "]"}]}]}]}], ",", + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}]], "Output", + GeneratedCell->False, + CellAutoOverwrite->False, + CellChangeTimes->{3.514562763315646*^9, + 3.6200565334732428`*^9},ExpressionUUID->"a4d60120-14aa-44a6-8025-\ +7454aa30fd11"] +}, Open ]], + +Cell["\<\ +In reality speciation and extinction are such rare events, that we wouldn't \ +expect the equilibrium ever to be overshot. This suggests that we should \ +either use small enough time intervals that overshooting does not occur \ +(because b and d are small) or use a continuous-time model.\ +\>", "Text", + CellChangeTimes->{{3.514680556325108*^9, 3.514680613884286*^9}, + 3.6200565334734097`*^9},ExpressionUUID->"b7f8b7ff-6f72-4b62-96d5-\ +5529f7b87b30"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Continuous-time approach", "Subsection", + CellChangeTimes->{{3.563595464831003*^9, 3.563595479028769*^9}, + 3.6200565334735603`*^9},ExpressionUUID->"a2bce3ad-29ce-460d-88e0-\ +0ddbaecc8c43"], + +Cell[TextData[{ + "\t", + Cell[BoxData[ + FractionBox["dn", "dt"]], + CellChangeTimes->{3.5635954908382053`*^9},ExpressionUUID-> + "53c4668f-bc18-4ccb-93ad-262dc0013993"], + " = - d n[t] + b n[t] Exp[-a n[t]]" +}], "Text", + CellChangeTimes->{{3.563595437816786*^9, 3.563595499180064*^9}, + 3.620056533474012*^9},ExpressionUUID->"c6436ce7-86e7-43c3-b835-\ +b7b8ec54be39"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"0", "==", + RowBox[{ + RowBox[{ + RowBox[{"-", "d"}], " ", "nhat"}], " ", "+", " ", + RowBox[{"b", " ", + RowBox[{"Exp", "[", + RowBox[{ + RowBox[{"-", "a"}], " ", "nhat"}], "]"}], " ", "nhat"}]}]}], ",", + "nhat"}], "]"}]], "Input", + CellChangeTimes->{{3.5145620885906353`*^9, 3.5145620954550447`*^9}, { + 3.514562234647851*^9, 3.514562271064756*^9}, {3.514680167209667*^9, + 3.514680173982081*^9}, {3.563595505175157*^9, 3.563595507653721*^9}, + 3.62005653347421*^9},ExpressionUUID->"62782af1-49c7-4a1d-a048-\ +815c4b4d312f"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"nhat", "\[Rule]", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"nhat", "\[Rule]", + FractionBox[ + RowBox[{"Log", "[", + FractionBox["b", "d"], "]"}], "a"]}], "}"}]}], "}"}]], "Output", + GeneratedCell->False, + CellAutoOverwrite->False, + CellChangeTimes->{3.514562271602889*^9, 3.5146801707235937`*^9, + 3.563595508581452*^9, + 3.620056533474373*^9},ExpressionUUID->"4bfc5d0b-b53b-4c92-b189-\ +8b9a8a4f91c2"] +}, Open ]], + +Cell["\<\ +Here, I've used nhat to stand for the equilibrium. The first equilibrium to \ +consider is the no-species case. The second equilibrium is biologically \ +valid only if it is not negative, which requires that b>d.\ +\>", "Text", + CellChangeTimes->{{3.51468019478463*^9, 3.5146802491594763`*^9}, { + 3.563595563060568*^9, 3.563595569186257*^9}, + 3.62005653347453*^9},ExpressionUUID->"24bc2abf-6754-4aa9-a460-\ +eeeaf53144db"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"r", "=", + RowBox[{ + RowBox[{"D", "[", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"-", "d"}], " ", + RowBox[{"n", "[", "t", "]"}]}], "+", + RowBox[{"b", " ", + RowBox[{"n", "[", "t", "]"}], " ", + RowBox[{"Exp", "[", + RowBox[{ + RowBox[{"-", "a"}], " ", + RowBox[{"n", "[", "t", "]"}]}], "]"}]}]}], ",", + RowBox[{"n", "[", "t", "]"}]}], "]"}], "/.", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", "0"}]}]}]], "Input", + CellChangeTimes->{{3.514118347956435*^9, 3.5141183994468813`*^9}, { + 3.514118454362989*^9, 3.514118457111812*^9}, 3.514514816409915*^9, { + 3.514514936011118*^9, 3.5145149387008944`*^9}, {3.514514977671487*^9, + 3.514514978516873*^9}, {3.514515030612793*^9, 3.514515032579115*^9}, + 3.514680145041581*^9, 3.5146801883101683`*^9, {3.563595524753386*^9, + 3.5635955323099327`*^9}, + 3.620056533474749*^9},ExpressionUUID->"f37908d9-c92b-4adb-8853-\ +b38c4c4192ed"], + +Cell[BoxData[ + RowBox[{"b", "-", "d"}]], "Output", + GeneratedCell->False, + CellAutoOverwrite->False, + CellChangeTimes->{{3.514118386149518*^9, 3.514118407945298*^9}, + 3.514118459061335*^9, {3.514514817823138*^9, 3.514514852099307*^9}, { + 3.51451488720148*^9, 3.514514904294133*^9}, {3.514514936618411*^9, + 3.514514944362132*^9}, 3.5145149819696913`*^9, 3.514515034074918*^9, + 3.514680151955868*^9, 3.563595534505419*^9, + 3.620056533474864*^9},ExpressionUUID->"b3561524-58c2-44dc-bf33-\ +19f3e83f3263"] +}, Open ]], + +Cell["\<\ +The no-species case will be unstable (r>0), if b>d, that is, if speciation is \ +more common than extinction when there are few species present. + +Now considering the second equilibrium:\ +\>", "Text", + CellChangeTimes->{{3.514680256839128*^9, 3.514680314061429*^9}, { + 3.563595537877871*^9, 3.563595539443933*^9}, {3.563595576117279*^9, + 3.563595593497081*^9}, + 3.620056533475006*^9},ExpressionUUID->"e0384f15-834c-4d94-b0c5-\ +cb3b97420d7c"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"r", "=", + RowBox[{ + RowBox[{"D", "[", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"-", "d"}], " ", + RowBox[{"n", "[", "t", "]"}]}], "+", + RowBox[{"b", " ", + RowBox[{"n", "[", "t", "]"}], " ", + RowBox[{"Exp", "[", + RowBox[{ + RowBox[{"-", "a"}], " ", + RowBox[{"n", "[", "t", "]"}]}], "]"}]}]}], ",", + RowBox[{"n", "[", "t", "]"}]}], "]"}], "/.", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", + FractionBox[ + RowBox[{"Log", "[", + FractionBox["b", "d"], "]"}], "a"]}]}]}]], "Input", + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9, 3.51451505271852*^9, 3.514515317606764*^9, { + 3.514680321148003*^9, 3.5146803269805403`*^9}, {3.563595628725503*^9, + 3.5635956312770767`*^9}, + 3.6200565334752417`*^9},ExpressionUUID->"0f5ce446-cf44-4887-a5fd-\ +4423e3fac872"], + +Cell[BoxData[ + RowBox[{ + RowBox[{"-", "d"}], " ", + RowBox[{"Log", "[", + FractionBox["b", "d"], "]"}]}]], "Output", + GeneratedCell->False, + CellAutoOverwrite->False, + CellChangeTimes->{ + 3.5141184099144697`*^9, 3.5141184643525333`*^9, {3.514514825051873*^9, + 3.514514854280603*^9}, {3.514514890991288*^9, 3.514514907147491*^9}, + 3.514514946481635*^9, {3.514515036962925*^9, 3.514515053139289*^9}, + 3.514680327392661*^9, 3.563595632419421*^9, + 3.620056533475375*^9},ExpressionUUID->"faaace4c-5efc-480c-b8d0-\ +c8d2201fb32d"] +}, Open ]], + +Cell["\<\ +As this second equilibrium is only biologically valid when b>d, we know that \ +r must be negative, implying the equilibrium is stable.\ +\>", "Text", + CellChangeTimes->{{3.51468033295153*^9, 3.514680358685945*^9}, { + 3.51468039400795*^9, 3.514680444895501*^9}, {3.563595640043248*^9, + 3.563595674888691*^9}, + 3.620056533475507*^9},ExpressionUUID->"41e13911-680e-4263-93c7-\ +eb11a49e322d"], + +Cell["Numerical solutions:", "Text", + CellChangeTimes->{{3.5146805154752502`*^9, 3.514680518717536*^9}, { + 3.563595683737055*^9, 3.563595686891478*^9}, + 3.620056533475595*^9},ExpressionUUID->"293f34b2-086e-481d-a88e-\ +3127fdd22ed4"], + +Cell[BoxData[ + RowBox[{ + RowBox[{"species", "[", + RowBox[{"b_", ",", "d_", ",", "a_", ",", "n0_"}], "]"}], ":=", + RowBox[{ + RowBox[{"species", "[", + RowBox[{"b", ",", "d", ",", "a", ",", "n0"}], "]"}], "=", + "\[IndentingNewLine]", + RowBox[{"NDSolve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"D", "[", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}], "==", + RowBox[{ + RowBox[{ + RowBox[{"-", "d"}], " ", + RowBox[{"n", "[", "t", "]"}]}], "+", + RowBox[{"b", " ", + RowBox[{"Exp", "[", + RowBox[{ + RowBox[{"-", "a"}], " ", + RowBox[{"n", "[", "t", "]"}]}], "]"}], " ", + RowBox[{"n", "[", "t", "]"}]}]}]}], ",", + RowBox[{ + RowBox[{"n", "[", "0", "]"}], "\[Equal]", "n0"}]}], "}"}], ",", + RowBox[{"n", "[", "t", "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "200"}], "}"}]}], "]"}]}]}]], "Input", + CellChangeTimes->{{3.514424045707509*^9, 3.514424061967498*^9}, { + 3.5144255050950212`*^9, 3.514425607017445*^9}, {3.514425642488206*^9, + 3.514425669408059*^9}, {3.514425734177042*^9, 3.514425737442438*^9}, { + 3.514426238427285*^9, 3.5144262538256493`*^9}, {3.514426381804556*^9, + 3.514426383523755*^9}, 3.5144264576520653`*^9, {3.5144266314259853`*^9, + 3.5144266539839983`*^9}, {3.514427148128552*^9, 3.5144271570026703`*^9}, { + 3.514515141529313*^9, 3.5145151955683947`*^9}, {3.514515245461218*^9, + 3.5145152467156477`*^9}, {3.56359573265282*^9, 3.563595757391096*^9}, { + 3.563595890698227*^9, 3.563595905910779*^9}, + 3.620056533476055*^9},ExpressionUUID->"19955c9c-c237-4299-ae2f-\ +385a0a345cd6"], + +Cell["and plot this solution:", "Text", + CellChangeTimes->{{3.5144263221305637`*^9, 3.514426329021406*^9}, { + 3.514426565192073*^9, 3.5144265653575697`*^9}, {3.563595770073134*^9, + 3.563595771294092*^9}, + 3.620056533476164*^9},ExpressionUUID->"3e85b415-6994-47ae-bdd9-\ +a33fd66a6a43"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{"Evaluate", "[", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "/.", + RowBox[{"species", "[", + RowBox[{"28", ",", "0.5", ",", "0.01", ",", "10"}], "]"}]}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "200"}], "}"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{"All", ",", + RowBox[{"{", + RowBox[{"0", ",", "700"}], "}"}]}], "}"}]}]}], "]"}]], "Input", + CellChangeTimes->{{3.563595908892679*^9, 3.5635959272929497`*^9}, { + 3.5635960141826153`*^9, 3.56359601853242*^9}, + 3.6200565334763803`*^9},ExpressionUUID->"61c1fca2-1d25-404f-ac70-\ +10ce3b7c3398"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {Hue[0.67, 0.6, 0.6], LineBox[CompressedData[" +1:eJxF03k8VfkbB/Brpyhc+3oXCclSMrY6zyhbIqFkl/VmKbt7UYREoWJEpdIU +UkJCJGJUSFHKUipDlmKyZkl0f+fce2Z+f53X+/X9fs/zPJ/vOWTPo7Y+nAQC +gYODQMCelLOrN64qvN4RmLRzMImgBA/4VRWDaGUId+gfdyadd0ITvfSmCu0x +QmuyiYh3cIAs3WEXoYwWJGm99Uj8e094phXix0vrRGKGl7vdKmgQK86sYea/ +QeSdaIN1OkFwIdNkx0p6L8JFPFLQ5xQMZevTmpei+5F0h5TOJ/Uh0JrWZT7v +N4DkWfEfa+wPhekkwTH67UFk//GkmUdPw+BYc5nqYv5n5Kj2A+mLp8JhDadd +YETOCOKy/DDkg2oEXICF0rn0MaTX68KVVxURQI27OBOS9BUJztzQtXVjJJTX +G+lMR08gX3k/j5WcjgSjlYHIIyHfEKcGaonU35HQZpBY+4/fFDI//Gd3vWoU +3DEiHt9WNo24zl6fDD0cBTP93tfCb88g5e0t1x7kR4FeTHXj/YJZJHKhan3r +qyg4LsM/NJs/hwiHS3HdWY6CJ7WOXFvyviPZaREZRop0WON4RykkZx5Z+nnN +SBehg83Sikl55gJS2vTdd5szHXJyrP2m0hcRgZfJIo1hdPikm5+ikbqEWJJq +meapdFDqmSkOSvqBnDTmbNmSRwf/iJ3tJXHLyK1t6d5dJXQoF8v+ZyL6J2KY +NGgfUkeHhfujQpsiV5Bi3v49e1vpsN1OT9M/ZBUxHtEpuvGGDkmzqTbFgb+Q +oNnG7Ksf6fD8fH/IFz8mUleqrOw/SoeU3AttWdoE4O9NI2yapIM6DXHaWkaA +O0VRLhzzdOj87ct4lzoH6L6pshT4SYdQvvMxobc5QK1MIMKZwADxXn1BURVO +MGseTRHiYUBN4VDevQJO0Ij7fmaLAAOcI89s3kflAs3ZFLV+QQb8MtFpmM7n +AoranLSEMAOui3+0PqfADTV2sTbTogzYNXJyQDOPG1Y+i2yOEGfAl0qN4E5p +Hmj9VF5VKsmAM0m9hKM5PNDym+nTAmkGaNjHn18nzgvNOyQ2esoyoIuqSinN +5IXzVcv3x+UYEDH3usJKmA/uqtScMlFggFRz9M5v6XzwxfvYVJQiA+oyqW/T +1vLDbx+jbyeTGODm+cJbPZUfmnOaBiPIDODYEjHfzisARZy/dlhQGHCTQyE5 +IEkAZjSu8HFTGWD2+pnEWs418ERxF7EY9Xj+0aLbcWvAYuPJbwZKDMgIltLb +vboGkjuM3tSh1oam1q/Ra6GkfK528wYGvF3v75i6tBY6Ag95Z6KmD4iOq0QK +QuzZascJ1LJlddGtc4KwvGHHD31lBjQc915LCxGCAs+s8DjUh6yF8vimhOCn +2Y2Pj1BzK1SrFwWug9DT+tQ51EXf3OpNx9eBZvqMDHUjA3bX81mP+q2HL6Gh +cVaotZme8xLT66HgyMWvEajTSO4dVCNh8H1YbnwRdXyTIMUoXhhg/yWNGtTh +ng8j7J8IwxRHl/4b1DQuWlsgvwjM3KodGkftclNc/uQeEQgj5mYxUduYNAdf +OScCA+Fxd0VU0PsdDX5S9VYEvO6QEsio9U4pSHVIiULg72HOmqjVVV4EjLqI +wsc8a7ohalIb4/GvfFHIafoqbIqa6L+RKDkiCpOj1fv3ouZd2+2rqUoEswa1 +EAfUy3cSHpoFEYGrpTHFDfXkHq11HveI8PLp3UfeqIe+fTxEnyfC6+Pjqv6o +ezLOVJ3TFwP+H5++HEH9XFNfoPiYGJRuHV8fhrrh1ahLU5MYLLs63ItEXRHy +R/k7HnHoDPrzEwN1oagx96yFOKy8Vi6MRX3p/pTDmgxx0FC3FItDnWF/5Q6l +Sxw2rOvUOYH6xPxupoGEBLQkfRNORB1+YcnWzkkCXmV43EtCTfutsDDgqgTc +7W6ST0bt0me3nDgkAW2Lti6nUNswOKzzlCWh+ykpLAXLU6bseqW/JMhbrfim +YnnWucy/KJWEcKKh0WksT5c1FiOzkuB38/0CZtLqg7xVXSlYEeO+dAa12FWf +afEYKRgwalZJQ82PEHdpPJaC4NbCAswrA405plzSUFvTLpqOeir+yISbmTQE +t1uGYh4iyyFRZ6QhokjwGeaev9oyz3ZKg2Cyw/oMLE+vqNEiogxUFh7ci7mB +e4NBo4MMaHuancJcUdCV3ndZBnwnDGswF5rGD04PyMCWhOUhzJfGNm8TUJIF +eR1T/rNYnin9KWSaLASUjatgTlBN/aBfIgvKm6JMMEc+19WynZaFq7ZBbpj9 +A4YT/XXkIJfXJhyzq2BmbwJdDtwtjp/CbHMX2XT5kRwU5hnnYt5l/e34fYI8 +GGR/KcSsN3Wpq32XPOy0rL6PWf2cufJwijxk+XxuwEzSXmCsvJAH2xuFrZjF +um68FBNRAOmdW19j5g/bR968XwE8vxb2YV4hMsNNLipA9nbVAczTlSWtrh8V +4Hrt8DDm4f1OcpFkRbDbRBjH3LfAF5zhowh1tbGTmNtzqpoLixWBHEybxdyg +5yX5+JsicCf2zWN+F5hSNSFFAnnnwSXMdtvdBxYNSHBLPeUn5pdCugLcriTo +onSvYu6yFM3tiCVBelslk1UvdVL5Yh4JxjqcOM6h/tTyvMrrEQnWab7hxDzM +U7RL4wMJJrMo3JjHdya+WfpJguRVcx7M0yfcPZtlydAbYMqLeeGx4Uy6IRlO +vJHjw7yyKhl/0JkMyw3vWeY0+r6OGkOGTUqJ/Jj5o19d+XaJDGJcEgKY19WU +qNc8JEO1cxbLxIWUuoT3ZCiyYLIspeOz22qZDPcIh9ZgVgj9/Z2kDAV+/lnD +slK5PG1InwLJWrxrMatN/lgocaRAVrsFy1rqPSejGBR4EZ3Msq5/hZjxRQoo +x9WzbHQr44ZgLQWu902ybDzqv6W3jwLbT8kIYjZXMmu6vkQBjZ/AsrUn1SZQ +igpu9V4s2+czP+nqUeHhVALLjp/6gzgOUsE48yrLbnI1K+1RVNhXUM2yt9Mf +Zy7kUGHDTDvL/rnBMoceUOGIwgDLwT17ijf1UmHT5mmWY215WhollCCMV1AI +c0pH/fD+A0oATDLL155pkOK7laAnG1iubrjmfNt+A6iM2bHcUS2c8/bNBjjs +6cPySOmJrl+2yrBXI5JlsWteFnb7NsJB3gyWjc+aNBbtVYG+tWks8y7KTXJv +U4eTfNEs+2guC2kLaQH/wxCWHUvKmFS1LZD1kcaylarPjISZDoTas+sR4kK2 +TiO6sC2X7Yq3xyLa9PQghszeHzlnJzrmbAC6CoEsG4qqlXHHGQFx+SjLSdwq +8xtzd8CKYSjLfj8zrxQcBOjWZHvCo56mZvc7dP1g93P02djWMitj0BxhO1Y4 +Sv2A6064MM72aSfeDauBu8Cck31+QbjJJMffBCwU2fZqifHVppnCB322M/2e +O3d4mAHTnO0mPul9AY7mcBk3I+1FmJqfBfxtyra2SPyFr+G7wQu3Oaf74OVg +S3iL22Nuu7p14B6YMGOb0HbiJuWYFeRYsH396lO5xXRrSLJkm9vtyuGOi3vB +x4rt+xkG/V22NsC5l+0/lB6J13TagJAN2+EPt9tc2bMPjuG+9FfIdeLbfeCM ++/HzgtlUZ1uoxM+LpU71/nhnC7XWbB82068/fNAOYvB6nPRttf6DdjCL95N3 +S7sqwN8e7HezLdERJTs5bQ8teB7n5+pPBEftB3d8PqNO6dh/vu8HS3z+0dsR +kbTQA1Bswnb3UuKpiOUDcBr3E9PM3IQEBxjFPbS7ensqx0E4j5/n2Pt+6Gz8 +QYj6Nz9z81nJ1YMQjdcn/F7Nkc9whFQ8z10lPRtrCU5wA+83RXLRquuUE2Tj +86zobeYf4XEG/T1sBzt5/bWY6AyJuFUmLbMuC7pAGO7BEzreSLYLiOKOXuN3 +zVvWFSLx94llXXyfet0VKvB6H18PFt9ScIMxvJ9CYTVGy2U3kMJd2aTkHkV1 +h13/fl+hiiYb77jDeXw+5j857l/EPEAW91VSvtx2ew+YxPMotX6ZYZvpAUzc +9bHLBNorD9iJ75/6HP/rKfEQ1OImW/KtUB0OwR68nn96bvOv7EMwgruyU/XM +u7eHIB7vj2Qp9mlFyhNk8XnSnv3SIrl6Qh5uYfnvVo15njCBOyvsq7/HB0/g +xvNIecK1vUnGC6bw9VhxhfUURy+oxp157Xxge54XOOIuVuV5Hv6313959WUk +zlxS9IYw3LzfOaSb3Lz/+x8PZL5r17zhDWm4i7TuHb865g0auGltd0dfqvnA +Ij6/qudt69UgH5jCzdlzL764xAf48f39FrUV+yd8QA93z4J08G5NX4jB3XUj +ejMS5gvNuEc2jVaWV/gCJ97f0v19RpRZX9DGHas7RLfX8gMr3Mya0KrkI37g +grsg3OUYR4UfeOC21DI1iZ3//7pAi0FvmA4N7HC3uGoeDgijgTluAz6b8qpa +GiC4S8uDF5lMGhji/h9J/cEG + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{All, {0, 700}}, + PlotRangeClipping->True, + PlotRangePadding->{Automatic, Automatic}]], "Output", + GeneratedCell->False, + CellAutoOverwrite->False, + CellChangeTimes->{ + 3.563595862701022*^9, {3.5635959094759808`*^9, 3.563595927757668*^9}, { + 3.563596010998698*^9, 3.56359602685699*^9}, + 3.620056533479197*^9},ExpressionUUID->"7a9c3600-b070-4979-8624-\ +5a957cf57ca1"] +}, Open ]], + +Cell[TextData[{ + "There is no general solution that ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " knows:" +}], "Text", + CellChangeTimes->{{3.51456273103664*^9, 3.514562734543154*^9}, { + 3.514680544193344*^9, 3.514680554486227*^9}, {3.563595704359613*^9, + 3.563595708151515*^9}, + 3.6200565334793262`*^9},ExpressionUUID->"da642108-c0a8-4dcc-a420-\ +5c13d26a2602"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"DSolve", "[", + RowBox[{ + RowBox[{ + RowBox[{"D", "[", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}], "==", + RowBox[{ + RowBox[{ + RowBox[{"-", "d"}], " ", + RowBox[{"n", "[", "t", "]"}]}], "+", + RowBox[{"b", " ", + RowBox[{"Exp", "[", + RowBox[{ + RowBox[{"-", "a"}], " ", + RowBox[{"n", "[", "t", "]"}]}], "]"}], " ", + RowBox[{"n", "[", "t", "]"}]}]}]}], ",", + RowBox[{"n", "[", "t", "]"}], ",", "t"}], "]"}]], "Input", + CellChangeTimes->{{3.514562737880988*^9, 3.5145627624916687`*^9}, { + 3.563595690339922*^9, 3.563595697523178*^9}, + 3.620056533479548*^9},ExpressionUUID->"5b28911a-3582-49d2-a996-\ +7d8fb3def27e"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", + RowBox[{ + RowBox[{"InverseFunction", "[", + RowBox[{ + RowBox[{ + SubsuperscriptBox["\[Integral]", "1", "#1"], + RowBox[{ + FractionBox[ + SuperscriptBox["\[ExponentialE]", + RowBox[{"a", " ", + RowBox[{"K", "[", "1", "]"}]}]], + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"-", "b"}], "+", + RowBox[{"d", " ", + SuperscriptBox["\[ExponentialE]", + RowBox[{"a", " ", + RowBox[{"K", "[", "1", "]"}]}]]}]}], ")"}], " ", + RowBox[{"K", "[", "1", "]"}]}]], + RowBox[{"\[DifferentialD]", + RowBox[{"K", "[", "1", "]"}]}]}]}], "&"}], "]"}], "[", + RowBox[{ + RowBox[{"-", "t"}], "+", + RowBox[{"C", "[", "1", "]"}]}], "]"}]}], "}"}], "}"}]], "Output", + GeneratedCell->False, + CellAutoOverwrite->False, + CellChangeTimes->{3.514562763315646*^9, 3.5635957558042316`*^9, + 3.563596167686016*^9, + 3.620056533479851*^9},ExpressionUUID->"85661489-628d-4104-a702-\ +17f201a71056"] +}, Open ]] +}, Closed]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Part 5: Extending to models with more than one variable", "Section", + CellChangeTimes->{{3.514165215616572*^9, + 3.514165236893621*^9}},ExpressionUUID->"19ba622d-4e76-4a8c-a456-\ +266950e623bf"], + +Cell["\<\ +The above models were all in one variable (e.g., the population size or the \ +allele frequency). Fortunately, the ideas are the same (but the methods more \ +cumbersome) with models involving more than one variable. As an example, \ +let's work with a model of an alternation of generations between haploids and \ +diploids. + +Alternation of generations is a life history common to many algae, in which \ +both the haploid and the diploid phases exist as independently growing and \ +reproducing organisms. + +Haploid individuals (gametophytes) produce diploid individuals by producing \ +haploid gametes that then unite. + +Diploid individuals (sporophytes) produce haploid individuals by meiosis. + +During a year, we assume that parents reproduce and then die, where: + +\ta = the number of diploid offspring produced per haploid parent +\tb = the number of haploid offspring produced per diploid parent +\t +Then, if h[t] represents the number of haploid individuals and d[t] the \ +number of diploid individuals, we can track the size of both populations over \ +time using discrete-time recursions are thus: + +Haploids: \th[t+1] = b d[t] +Diploids:\td[t+1] = a h[t] + +We can describe analogous procedures for continuous-time models, but to keep \ +matters simple , we'll focus here only on discrete-time models\ +\>", "Text", + CellChangeTimes->{{3.514427943218479*^9, 3.514427992056077*^9}, { + 3.514430456335277*^9, 3.514430650251234*^9}, {3.514431049360495*^9, + 3.514431099211742*^9}, {3.563595372269218*^9, 3.563595372744619*^9}, { + 3.5636672800454817`*^9, + 3.563667282308138*^9}},ExpressionUUID->"c745fa0b-2400-4d93-8e80-\ +af69d9d1bdec"], + +Cell[CellGroupData[{ + +Cell["Equilibria", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, + 3.513952890146652*^9}},ExpressionUUID->"b5030c12-f365-4c49-bc72-\ +9ddf08ba9dcf"], + +Cell[TextData[{ + "An equilibrium is defined in the same way, as a special point at which the \ +system stays if started there. The only trick is to make sure that all of \ +the ", + StyleBox["variables", + FontColor->RGBColor[1, 0, 0]], + " remain constant." +}], "Text", + CellChangeTimes->{{3.514428019317086*^9, 3.514428101517205*^9}, { + 3.5144281484116297`*^9, 3.514428153504444*^9}, {3.514428229695262*^9, + 3.5144282331832857`*^9}, {3.56366728807489*^9, + 3.563667288434721*^9}},ExpressionUUID->"95c1bf97-fd52-4cec-97bd-\ +0eeff9d637ee"], + +Cell["For the model of alternating generations:", "Text", + CellChangeTimes->{{3.514428428226385*^9, 3.51442845235435*^9}, { + 3.514431111990419*^9, + 3.5144311178747377`*^9}},ExpressionUUID->"64e9c8fa-6a84-434f-a573-\ +70054ad6e192"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + FormBox[ + OverscriptBox["h", "^"], + TraditionalForm], " ", "==", + FormBox[ + RowBox[{"b", + OverscriptBox["d", "^"]}], + TraditionalForm]}], ",", + RowBox[{ + FormBox[ + OverscriptBox["d", "^"], + TraditionalForm], " ", "\[Equal]", + RowBox[{"a", + OverscriptBox["h", "^"]}]}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + OverscriptBox["h", "^"], ",", + OverscriptBox["d", "^"]}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.514428199117491*^9, 3.5144282532487717`*^9}, { + 3.514428327624214*^9, 3.514428414477846*^9}, {3.514431123543721*^9, + 3.514431166602357*^9}},ExpressionUUID->"064c0c7f-fac7-484a-88ca-\ +062fea785f14"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{ + RowBox[{ + OverscriptBox["h", "^"], "\[Rule]", "0"}], ",", + RowBox[{ + OverscriptBox["d", "^"], "\[Rule]", "0"}]}], "}"}], "}"}]], "Output", + CellChangeTimes->{ + 3.5144311706554203`*^9},ExpressionUUID->"bfbe1d41-ef42-440b-b7f6-\ +74ca26a9918a"] +}, Open ]], + +Cell[TextData[{ + "Here we've asked ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " for all of the sets of solutions for the number of haploids and diploids \ +", + Cell[BoxData[ + RowBox[{"{", + RowBox[{ + OverscriptBox["h", "^"], ",", + OverscriptBox["d", "^"]}], "}"}]], + CellChangeTimes->{{3.514428199117491*^9, 3.5144282532487717`*^9}}, + ExpressionUUID->"b6148474-e4f7-4533-8550-cbbe28893810"], + " that cause both of these values to remain constant in the next generation. \ + The answer is that there's only one equilibrium point, with neither haploids \ +or diploids." +}], "Text", + CellChangeTimes->{{3.51442825542505*^9, 3.514428315406611*^9}, { + 3.514431180419536*^9, + 3.514431222791284*^9}},ExpressionUUID->"e18bc38e-3af4-4ebc-9275-\ +bad02d3fc5ef"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Stability", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.514428463172866*^9, + 3.514428464250293*^9}},ExpressionUUID->"ad16f01f-31e5-4acf-b6d9-\ +945d60c058a9"], + +Cell[TextData[{ + "To determine stability, we need to have a multi-dimensional analogue of \ +\[Lambda] that describes the factor by which the distance from the \ +equilibrium grows each generation.\n\n", + StyleBox["Idea: ", + FontWeight->"Bold"], + "We again approximate the recursions near an equilibrium point using the \ +Taylor series, but we do this for each recursion equation and each variable. \ +For example, if we have two recursion equations, f and g, describing changes \ +in two variables, n and m, we could apply the Taylor series as before and \ +rearrange the results as:\n\n\t\t", + Cell[BoxData[ + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], "=", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + SubscriptBox[ + RowBox[{"(", + FractionBox["df", "dn"], ")"}], + RowBox[{ + OverscriptBox["n", "^"], ",", + OverscriptBox["m", "^"]}]]}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"m", "[", "t", "]"}], "-", + OverscriptBox["m", "^"]}], ")"}], " ", + SubscriptBox[ + RowBox[{"(", + FractionBox["df", "dm"], ")"}], + RowBox[{ + OverscriptBox["n", "^"], ",", + OverscriptBox["m", "^"]}]]}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"5d9357b1-1754-4cff-98e0-24b3ed26ba4e"], + "\t\n\t\t", + Cell[BoxData[ + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"m", "[", + RowBox[{"t", "+", "1"}], "]"}], "-", + OverscriptBox["m", "^"]}], ")"}], "=", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}], ")"}], " ", + SubscriptBox[ + RowBox[{"(", + FractionBox["dg", "dn"], ")"}], + RowBox[{ + OverscriptBox["n", "^"], ",", + OverscriptBox["m", "^"]}]]}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{"m", "[", "t", "]"}], "-", + OverscriptBox["m", "^"]}], ")"}], " ", + SubscriptBox[ + RowBox[{"(", + FractionBox["dg", "dm"], ")"}], + RowBox[{ + OverscriptBox["n", "^"], ",", + OverscriptBox["m", "^"]}]]}]}]}]], + CellChangeTimes->{3.514117055633194*^9, 3.514117133427924*^9}, + ExpressionUUID->"d5f4dba0-27f3-4fd3-9672-89c912e6ca6a"], + "\t\n \nBook-keeping is easier, however, and we can use the power of matrix \ +algebra, if we write this in matrix form:\n\n\t\tdistance to equilibrium in \ +next generation \t= ", + StyleBox["stability matrix", + FontColor->RGBColor[1, 0, 0]], + " times distance to equilibrium in previous generation\n\t\t\n\t\t\t\t", + Cell[BoxData[ + FormBox[ + RowBox[{"(", GridBox[{ + { + RowBox[{ + RowBox[{"n", "[", + RowBox[{"t", "+", "1"}], "]"}], "-", + OverscriptBox["n", "^"]}]}, + { + RowBox[{ + RowBox[{"m", "[", + RowBox[{"t", "+", "1"}], "]"}], "-", + OverscriptBox["m", "^"]}]} + }], ")"}], TraditionalForm]],ExpressionUUID-> + "7e1c2840-1a3f-4c4f-99d2-cf152838fbaf"], + " \t\t= ", + Cell[BoxData[ + FormBox[ + RowBox[{"(", GridBox[{ + { + FractionBox["df", "dn"], + FractionBox["df", "dm"]}, + { + FractionBox["dg", "dn"], + FractionBox["dg", "dm"]} + }], ")"}], TraditionalForm]],ExpressionUUID-> + "2081748d-f4e6-4511-8493-594d71332ea4"], + " ", + Cell[BoxData[ + FormBox[ + RowBox[{"(", GridBox[{ + { + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "-", + OverscriptBox["n", "^"]}]}, + { + RowBox[{ + RowBox[{"m", "[", "t", "]"}], "-", + OverscriptBox["m", "^"]}]} + }], ")"}], TraditionalForm]],ExpressionUUID-> + "1594ab0c-47a6-44ac-ac67-6c5d0b8467d6"], + " \n\t\t\t\t\nBut how do we tell if this matrix shrinks the distance or \ +expands the distance?" +}], "Text", + CellChangeTimes->{{3.514428471481825*^9, 3.5144286450102386`*^9}, { + 3.5144288254112473`*^9, 3.5144293727929068`*^9}, {3.5144294449727917`*^9, + 3.514429497649947*^9}, {3.514431777103921*^9, + 3.514431792431275*^9}},ExpressionUUID->"0e3237a5-0c14-42f5-9ef7-\ +1f85d7372688"], + +Cell[TextData[{ + StyleBox["DEFINITION: ", + FontWeight->"Bold"], + "A matrix involving d variables has d eigenvalues that describe the factor \ +by which the system grows along different directions (called eigenvectors). \ +The ", + StyleBox["leading eigenvalue", + FontColor->RGBColor[1, 0, 0]], + ", \[Lambda], of a matrix is the largest in magnitude of these eigenvalues, \ +and it predicts whether the matrix stretches (|\[Lambda]| > 1) or shrinks (|\ +\[Lambda]| < 1) a vector that it multiplies. If \[Lambda] is a complex \ +number, the system will cycle.\n\n", + StyleBox["CAUTION: ", + FontWeight->"Bold"], + "When calculating the stability matrix, decide on an order for the variables \ +and then take the derivative of the recursion for the first variable in the \ +first row with respect to the first variable in the first column. Keep the \ +order of the variables the same for all subsequent rows and columns." +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117377492393*^9}, { + 3.514117840393688*^9, 3.5141181925597687`*^9}, {3.514118250452888*^9, + 3.5141182831133347`*^9}, {3.514429521011125*^9, 3.514429568501519*^9}, { + 3.514429683894281*^9, 3.514429707893236*^9}, {3.514429743607738*^9, + 3.514429845831918*^9}, {3.514430368427335*^9, 3.5144303866734123`*^9}, { + 3.514432307183123*^9, 3.514432311402034*^9}, {3.51468076248174*^9, + 3.514680844022449*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"f8b0a314-f0df-493a-b48c-32fd1769ea94"], + +Cell["\<\ +For example, take the two recursion equations for the haploid-diploid model:\ +\>", "Text", + CellChangeTimes->{{3.514429858727319*^9, 3.514429896174037*^9}, { + 3.514431270800791*^9, + 3.51443127371848*^9}},ExpressionUUID->"3a9ab152-0b77-41b8-90da-\ +ca717514a666"], + +Cell[BoxData[{ + RowBox[{ + RowBox[{"eqnh", "=", + RowBox[{"b", " ", + RowBox[{"d", "[", "t", "]"}]}]}], ";"}], "\n", + RowBox[{ + RowBox[{"eqnd", "=", + RowBox[{"a", " ", + RowBox[{"h", "[", "t", "]"}]}]}], ";"}]}], "Input", + CellChangeTimes->{{3.514429904547501*^9, 3.51442992342336*^9}, { + 3.514431234883485*^9, 3.514431248744069*^9}, {3.514680714504559*^9, + 3.514680716230988*^9}},ExpressionUUID->"b4b9976b-2d47-430f-a300-\ +f8f889415d91"], + +Cell["\<\ +The first equation gives us h[t+1], so we must take the derivatives first \ +with respect to h[t] and then d[t], and then evaluate at the equilibrium of \ +interest (here 0,0):\ +\>", "Text", + CellChangeTimes->{{3.5144312770812607`*^9, + 3.514431327404771*^9}},ExpressionUUID->"e6e3a9ae-4680-4b3e-9a42-\ +c1c2ec8d3c60"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"matrix", "=", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"D", "[", + RowBox[{"eqnh", ",", + RowBox[{"h", "[", "t", "]"}]}], "]"}], ",", + RowBox[{"D", "[", + RowBox[{"eqnh", ",", + RowBox[{"d", "[", "t", "]"}]}], "]"}]}], "}"}], ",", + "\[IndentingNewLine]", + RowBox[{"{", + RowBox[{ + RowBox[{"D", "[", + RowBox[{"eqnd", ",", + RowBox[{"h", "[", "t", "]"}]}], "]"}], ",", + RowBox[{"D", "[", + RowBox[{"eqnd", ",", + RowBox[{"d", "[", "t", "]"}]}], "]"}]}], "}"}]}], "}"}], "/.", + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"h", "[", "t", "]"}], "\[Rule]", "0"}], ",", + RowBox[{ + RowBox[{"d", "[", "t", "]"}], "\[Rule]", "0"}]}], "}"}]}]}]], "Input", + CellChangeTimes->{{3.51442993198416*^9, 3.5144299850653954`*^9}, { + 3.5144300475033083`*^9, 3.514430056546912*^9}, {3.514431255563335*^9, + 3.5144312648468647`*^9}, {3.5144313318662977`*^9, 3.514431341037857*^9}, + 3.514564601334771*^9, 3.5145646391440372`*^9, {3.514680733307054*^9, + 3.514680739961896*^9}},ExpressionUUID->"c12a312f-b33b-4e0a-93d7-\ +3f90b7ff94b4"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"0", ",", "b"}], "}"}], ",", + RowBox[{"{", + RowBox[{"a", ",", "0"}], "}"}]}], "}"}]], "Output", + CellChangeTimes->{ + 3.5146808773161173`*^9},ExpressionUUID->"1b7940f6-cd18-4472-99d7-\ +9ec0615b1b1c"] +}, Open ]], + +Cell["The eigenvalues of which are:", "Text", + CellChangeTimes->{{3.51442999874765*^9, 3.514430033710093*^9}, { + 3.514431354718349*^9, + 3.514431358603902*^9}},ExpressionUUID->"8a46c20a-c617-4220-a1c3-\ +8385a4e2bec5"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Eigenvalues", "[", "%", "]"}]], "Input", + CellChangeTimes->{{3.514430075822959*^9, + 3.514430078517954*^9}},ExpressionUUID->"eebf09de-33e2-4ef8-8c89-\ +cddead8bbf29"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"-", + SqrtBox["a"]}], " ", + SqrtBox["b"]}], ",", + RowBox[{ + SqrtBox["a"], " ", + SqrtBox["b"]}]}], "}"}]], "Output", + CellChangeTimes->{3.514430079485057*^9, 3.514431346378005*^9, + 3.514680879492571*^9},ExpressionUUID->"55a9be03-cd32-442e-8c54-\ +f3582ad448d5"] +}, Open ]], + +Cell[TextData[{ + "Because a and b describe the number of offspring, these eigenvalues must be \ +positive. The magnitude of these two eigenvalues is the same, |\[Lambda]| = ", + Cell[BoxData[ + SqrtBox[ + RowBox[{"a", " ", "b"}]]], + CellChangeTimes->{3.514430079485057*^9, 3.514431346378005*^9}, + ExpressionUUID->"b7b4191f-5d9f-47eb-aba1-aa0eb06e4798"], + ", which tells us that the system will move away from the equilibrium at \ +{0,0} ", + "only if ", + Cell[BoxData[ + RowBox[{ + SqrtBox[ + RowBox[{"a", " ", "b"}]], ">", "1"}]], + CellChangeTimes->{3.514430079485057*^9, 3.514431346378005*^9}, + ExpressionUUID->"d79f22b6-213b-4554-b3a6-552882e11c03"], + ", which implies that the product of a and b must be greater than one.", + "\n\n\t\[Rule] A haploid-diploid species can grow in size even if one phase \ +produces less than\n\ta replacement number of offspring (e.g., a < 1), as \ +long as the other phase compensates (e.g., b > 1)." +}], "Text", + CellChangeTimes->{{3.514431364358465*^9, 3.514431649578076*^9}, { + 3.5144322868208647`*^9, 3.51443229324233*^9}, + 3.5636674384458714`*^9},ExpressionUUID->"4c2c6ca4-9859-4037-be95-\ +55e188f5b51a"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Simulation", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.514428463172866*^9, 3.514428464250293*^9}, {3.514432430011691*^9, + 3.514432431921852*^9}},ExpressionUUID->"e83b0893-70af-4294-a70a-\ +94dc75e2de25"], + +Cell["\<\ +We can use the same basic code as with the logistic model to track the size \ +of the haploid and diploid populations. The only difference is that the \ +result is now a vector {h,d}, whose first part is the number of haploids and \ +whose second part is the number of diploids.\ +\>", "Text", + CellChangeTimes->{{3.5144328332623262`*^9, + 3.514432913107875*^9}},ExpressionUUID->"387787a9-3664-4801-a41f-\ +d6fe64c431b4"], + +Cell[BoxData[{ + RowBox[{ + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a_", ",", "b_", ",", "h0_", ",", "d0_", ",", "t_"}], "]"}], ":=", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a", ",", "b", ",", "h0", ",", "d0", ",", "t"}], "]"}], "=", + "\[IndentingNewLine]", + RowBox[{"Block", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"h", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a", ",", "b", ",", "h0", ",", "d0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "1"}], "]"}]}], ",", + RowBox[{"d", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a", ",", "b", ",", "h0", ",", "d0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "2"}], "]"}]}]}], "}"}], + ",", "\[IndentingNewLine]", "\t", + RowBox[{"{", + RowBox[{ + RowBox[{"b", " ", "d"}], ",", " ", + RowBox[{"a", " ", "h"}]}], "}"}]}], "\[IndentingNewLine]", "\t", + "]"}]}]}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a_", ",", "b_", ",", "h0_", ",", "d0_", ",", "0"}], "]"}], ":=", + RowBox[{"{", + RowBox[{"h0", ",", "d0"}], "}"}]}]}], "Input", + CellChangeTimes->{{3.514424045707509*^9, 3.514424061967498*^9}, { + 3.5144255050950212`*^9, 3.514425607017445*^9}, {3.514425642488206*^9, + 3.514425669408059*^9}, {3.514425734177042*^9, 3.514425737442438*^9}, { + 3.514426238427285*^9, 3.5144262538256493`*^9}, {3.514426381804556*^9, + 3.514426383523755*^9}, 3.5144264576520653`*^9, {3.5144266314259853`*^9, + 3.5144266539839983`*^9}, {3.514427148128552*^9, 3.5144271570026703`*^9}, { + 3.514432474189856*^9, 3.514432582465474*^9}, {3.5636675220157833`*^9, + 3.563667523868281*^9}},ExpressionUUID->"24d86754-888c-4944-957e-\ +8abe0942fe45"], + +Cell["\<\ +Some notes: +\t* Block keeps a set of calculations together, defining local variables in \ +the first {}. The output will be the last entry of the Block. +\t* := sets the left to the right-hand side only after being called and \ +remembers this value. +\t* We have to set a starting point or else the system will end up in an \ +infinite loop going backwards in time.\ +\>", "Text", + CellChangeTimes->{{3.514426408190782*^9, + 3.51442655970971*^9}},ExpressionUUID->"3da61e30-63c4-414f-950a-\ +b8bf68d9cb9b"], + +Cell["\<\ +We can then make a table of population sizes for {haploids, diploids}:\ +\>", "Text", + CellChangeTimes->{{3.514426311595162*^9, 3.514426337581416*^9}, { + 3.5144326128151073`*^9, + 3.514432625364406*^9}},ExpressionUUID->"c9d99922-8617-4632-9b94-\ +045d2b428fe0"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"0.7", ",", "1.5", ",", "10", ",", "10", ",", "t"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5144262691718893`*^9, 3.514426294228351*^9}, { + 3.5144263455531607`*^9, 3.5144263905959597`*^9}, {3.514426567695655*^9, + 3.514426611405775*^9}, {3.51442669599331*^9, 3.514426706329217*^9}, { + 3.514432589298902*^9, + 3.514432602070593*^9}},ExpressionUUID->"61de1e26-2fd5-4130-83f8-\ +c149b1b1f884"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"10", ",", "10"}], "}"}], ",", + RowBox[{"{", + RowBox[{"15.`", ",", "7.`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"10.5`", ",", "10.5`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"15.75`", ",", "7.35`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"11.024999999999999`", ",", "11.024999999999999`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"16.537499999999998`", ",", "7.7174999999999985`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"11.576249999999998`", ",", "11.576249999999998`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"17.364374999999995`", ",", "8.103374999999998`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"12.155062499999996`", ",", "12.155062499999996`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"18.232593749999992`", ",", "8.508543749999996`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"12.762815624999995`", ",", "12.762815624999995`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"19.144223437499992`", ",", "8.933970937499996`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"13.400956406249994`", ",", "13.400956406249994`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"20.10143460937499`", ",", "9.380669484374996`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"14.071004226562493`", ",", "14.071004226562492`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"21.106506339843737`", ",", "9.849702958593745`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"14.774554437890618`", ",", "14.774554437890615`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"22.161831656835922`", ",", "10.342188106523432`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"15.513282159785149`", ",", "15.513282159785144`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"23.269923239677716`", ",", "10.859297511849604`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"16.288946267774406`", ",", "16.2889462677744`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"24.4334194016616`", ",", "11.402262387442084`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"17.103393581163125`", ",", "17.103393581163118`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"25.655090371744677`", ",", "11.972375506814187`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"17.95856326022128`", ",", "17.958563260221272`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"26.93784489033191`", ",", "12.570994282154894`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"18.85649142323234`", ",", "18.856491423232335`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"28.284737134848502`", ",", "13.199543996262639`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"19.799315994393957`", ",", "19.79931599439395`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"29.698973991590925`", ",", "13.85952119607577`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"20.789281794113656`", ",", "20.789281794113645`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"31.183922691170466`", ",", "14.552497255879558`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"21.828745883819337`", ",", "21.828745883819323`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"32.743118825728985`", ",", "15.280122118673535`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"22.920183178010305`", ",", "22.920183178010287`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"34.38027476701543`", ",", "16.044128224607213`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"24.06619233691082`", ",", "24.0661923369108`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"36.0992885053662`", ",", "16.84633463583757`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"25.269501953756357`", ",", "25.269501953756336`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"37.904252930634506`", ",", "17.68865136762945`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"26.532977051444178`", ",", "26.532977051444153`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"39.79946557716623`", ",", "18.573083936010924`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"27.859625904016386`", ",", "27.85962590401636`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"41.789438856024546`", ",", "19.501738132811468`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"29.252607199217202`", ",", "29.25260719921718`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"43.87891079882577`", ",", "20.47682503945204`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"30.715237559178064`", ",", "30.71523755917804`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"46.07285633876706`", ",", "21.500666291424643`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"32.25099943713697`", ",", "32.25099943713694`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"48.37649915570541`", ",", "22.575699605995876`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"33.86354940899381`", ",", "33.863549408993784`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"50.79532411349068`", ",", "23.704484586295667`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"35.5567268794435`", ",", "35.556726879443474`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"53.33509031916521`", ",", "24.88970881561045`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"37.33456322341568`", ",", "37.33456322341564`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"56.001844835123464`", ",", "26.134194256390973`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"39.20129138458646`", ",", "39.20129138458642`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"58.801937076879625`", ",", "27.44090396921052`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"41.16135595381578`", ",", "41.161355953815736`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"61.74203393072361`", ",", "28.812949167671043`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"43.21942375150657`", ",", "43.219423751506525`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"64.82913562725979`", ",", "30.253596626054595`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"45.380394939081896`", ",", "45.380394939081846`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"68.07059240862277`", ",", "31.766276457357325`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"47.64941468603599`", ",", "47.64941468603594`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"71.47412202905392`", ",", "33.35459028022519`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"50.03188542033779`", ",", "50.03188542033774`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"75.0478281305066`", ",", "35.022319794236445`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"52.53347969135467`", ",", "52.53347969135462`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"78.80021953703194`", ",", "36.773435783948266`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"55.1601536759224`", ",", "55.16015367592235`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"82.74023051388353`", ",", "38.61210757314568`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"57.91816135971852`", ",", "57.91816135971847`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"86.87724203957771`", ",", "40.54271295180296`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"60.81406942770444`", ",", "60.81406942770439`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"91.22110414155658`", ",", "42.569848599393104`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"63.85477289908965`", ",", "63.8547728990896`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"95.78215934863441`", ",", "44.69834102936275`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"67.04751154404413`", ",", "67.04751154404408`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"100.57126731606613`", ",", "46.93325808083089`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"70.39988712124634`", ",", "70.39988712124628`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"105.59983068186942`", ",", "49.27992098487243`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"73.91988147730865`", ",", "73.91988147730859`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"110.87982221596289`", ",", "51.74391703411605`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"77.61587555117407`", ",", "77.61587555117401`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"116.42381332676102`", ",", "54.331112885821845`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"81.49666932873276`", ",", "81.49666932873271`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"122.24500399309906`", ",", "57.04766853011293`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"85.5715027951694`", ",", "85.57150279516934`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"128.357254192754`", ",", "59.90005195661857`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"89.85007793492785`", ",", "89.8500779349278`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"134.7751169023917`", ",", "62.895054554449494`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"94.34258183167424`", ",", "94.34258183167418`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"141.51387274751127`", ",", "66.03980728217196`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"99.05971092325794`", ",", "99.05971092325788`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"148.58956638488684`", ",", "69.34179764628055`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"104.01269646942083`", ",", "104.01269646942077`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"156.01904470413115`", ",", "72.80888752859458`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"109.21333129289187`", ",", "109.2133312928918`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"163.8199969393377`", ",", "76.4493319050243`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"114.67399785753645`", ",", "114.67399785753638`"}], "}"}]}], + "}"}]], "Output", + CellChangeTimes->{ + 3.5144326027095003`*^9},ExpressionUUID->"47611ce0-2125-4b36-89dd-\ +b42d8b7682db"] +}, Open ]], + +Cell["or plotting haploids in red and diploids in blue:", "Text", + CellChangeTimes->{{3.5144263221305637`*^9, 3.514426329021406*^9}, { + 3.514426565192073*^9, 3.5144265653575697`*^9}, {3.514432634174358*^9, + 3.514432637243886*^9}, {3.5144327125256863`*^9, + 3.514432718011566*^9}},ExpressionUUID->"25e7b837-c443-4112-949e-\ +912b357896ba"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"0.7", ",", "1.5", ",", "10", ",", "10", ",", "t"}], "]"}], + ",", "1"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}], ",", + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"0.7", ",", "1.5", ",", "10", ",", "10", ",", "t"}], "]"}], + ",", "2"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]}], "}"}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Red", ",", "Blue"}], "}"}]}]}], "]"}]], "Input", + CellChangeTimes->{{3.514432638805904*^9, + 3.514432693910797*^9}},ExpressionUUID->"fa209c03-e262-41ff-80f5-\ +c0fc7049a4cf"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {RGBColor[1, 0, 0], LineBox[CompressedData[" +1:eJw9kA1M1HUcxv8omAoiLcTAF5DBcRrJ+4u8Phwvx3HAvR8HgrzjxQShphKF +HYshisEgQCkyFxJykjHwBWWVjOJNkAJHTHnT1JkgIAaINQrG999vu333uWfP +9v88uxIOS5PXMAyTvPxbuatvxnf1WoH+oLuX7nq61nSNVq/GjtgYPSvPgEP8 +NipX3kl74u0YrM7w3mhjQ2yB8Wzjy/wYB2JLrKvfHpUk4oL9Dt3ccv9CT0di +Dg7l6v5SnL+bmIs349sGJqyciPdAOHWMG9K7h9gWzbOR5xZMnf/3UD/P0UZZ +2RLbY9P7o//6b3MhdkD2IbeU0tPvEjsiqqSuJ223K7ETNLdlEz3rWF9nnBs6 +3mAa6Ebsgoyk2fhXAtbXFTUVE6V/pbsTu4F3LZPJMmN93RFXomWu1O4j3od3 +ekZSkubY3AM+jaFfmMx4EHsizqRKz/8+u4cXPtuVWvAo2IvYG8e3bl38uofd +wwce1d/MTTd6E/tiVN861rCb3QPoLLletMXOd5U1wHBjUwP3LruHHyzb8/N2 +xoJyPzg/nDYvmWD34KH6z5e/19v7Uc7DDr7l3y+MWF9/SK5GfnzVgEe5P46d +yTFeCmB9A1DucKD4x5dsHoALWTvsMgtY30AcNVP+IX/iT3kgPizMyjQa9qQ8 +CBVqM4XB4wDKg+ATWziiBevLR+oJLkczE0g5H+pTen2m130oD0aXTcB+2QY+ +5cHQPn34k4UF+TICLEbfNXewD6ZcgMebPuoqmGLzEPSXue/tTRZQHoJunaIB +XgftwQhRt0bh/UgbQrkQD3JbFvq15MuEoptX+YHX8l3NQ7H4IO9ZWyX5MmGY +lHaM1aSEUR6GS7IhUW0Z+TLhyMr5eeH1aDjl4bgXMfiWSRX5MiKMtY4XGbmI +KRdh6MgbnQ0NQZSLEXNWryJPV7LKEOPkek89iwF2DzESgibXqkYpvyXGfGdI +v7Eu+TISNJk0f7W5TUp9CdQ3dIwEAayvBBuEOj2uTTLqSzDuon72SZmQ+lIk +cu9Mx34vp74UJe43Rflz7B5SqLW3W6yaFdSXYkkuTnNSky8jww3ff0o4d5TU +lyHjdIfje89F1JdBVLflieFsBPVlODF/P21jG+3ByNH+outCsVUk9eUwnOfc +OlNJvho5Nmd6nE9MiaK+HFxRsXIsm3wZBa7ND+qImvdTf5nrBbmpB8lXo4D+ +p1Ot5ttiqK+Aao6T3hVLvowSS4c9rC8XH6C+En1Xjmg+TyJfjRJn+arz6fpx +1FfCNyn4u4NHyZeJgK1wvrV3iHJE4GKfaniynHw1EWj5kleT2RBP/QgMftsW +1t+mor4KO3+Q3hwpTaC+Cq897+n+ypCvRoVX9dVrqzSJ1FehvVDoXhtGvkwk +frvonuqdnUT9SERPPu2wvBSN/wB4LKmo + "]]}, + {RGBColor[0, 0, 1], LineBox[CompressedData[" +1:eJw9kHtQVGUYxhflNoANKUkxkOvGdb1wWW66IA+wwMICu8veiaLF5daAXJJg +TKYDATqAMiiMI6LlSDghJClesgmXoEDBJCQlFwXpD0lABQRTGS3j3b6ZM+88 +53eeb87vXZ+Sk5C6gsVipf77vJ7L53HI8nQGvaDpSNOSpgtNW6T9d5wo22Hg +9bFxpfw2nMqnpBfvvvv/PTdP5AZbublRZuN0fkbtjC+bMgfmrY6JOrE7jP9x +9FTbSLLpesquyCox/bmmwoOyO3yeiHO97xo5F6KHhe4x17iUN+LIvMzx/k8c +ypuRPlPckui8kbIXluacBTZn36PsjaKsgLQD1Zso+0Dhsy+Kd9q4Dx6K+2VT +A+aelH0Bw8ythQvGffhhh25O+3e0F2V/rJyfVixcM+4jADifxypy8KYciJrU +IZ5h1riPLfAYuJOmWzDyrfjdaTBJ42z05ePDtY1m4QYfykGQrdt5nJtm9A3G +bnv7Z18O8ChvQ/GlCo81FzdQDoHB2iX5jau+lIHB8IapcQfyZYCRM2fb3Yf9 +iIeiYVM9N6tmM/FQeE48Wlc75U88DJ1lXUsia/JlwmAfxXkxaxtIPBzPdS9T +vhkx8nDkHSq2eynYQlyAbEnnTlE7+TICHC1y8szbu5V4BJotXnx17gD5MhHI +ryrKsx3lE4/EcJ3FX3kM+TKRCEyuutOCYOJRiEj61vfNXeTLREFbaXb9nQvb +iAsxMf5FywaGfBkhmicnLrPZIB6NPaubbLQHyZeJxr1Vn13Z+9DIY7CqbbWD +piOAeAx+Mdl/I6w3lLgIJSueP+n+k/bBiDBa8sPToZYw4rE4Xmq+P5FDvkws +5u+VPeg+HE48DjU57LfGcsmXicPXshHxyToB8XhwCvpynAaDiMdjWHVzzdrG +COJiXI1KPjcF8mXE+K3Aoq+9PZK4BFrrpu+4PSHLGRKUWvLN2Dei6HsJnpWP ++m9vI1+9BI/6YobsTKOpL0WEq8lHhlLyhRTa701sowUx1Jei/teG2Vcp5KuX +4g+/jAef14mon4DzLrsrNfHkiwRUBl4SVyzEUj8Br/b5HSuMIF99Ap7KJdm8 +jHjqyyCyLB94LCRfyJBZ3euTOSOmvgwdQpfg7Rry1ctQtmjItuqWUF+OH+d4 +rIJC8oUcVouu+kOHpdSXY7wz85PhE0Lqy+EsrlGO7UqgvgLH+CmtgWO0Dyhw +pjW65ON0GfUV6J/lTWq55KtXQL7guuNKspz6StjNNrIcKsgXSvR3FDAHdQrq +KyH3sr7vOx9HfSX4OmFb+qdK6qtQdbnfpTaffKFC03X16HS9ivoq1PTc4lWX +kq9ehaHm7rihbjX11VhyC1o5riBfqLHIv206yEqkvhqeH/gM9vDIV69GV5Uo +8GTc+9TXIFh45HaXI/lCA9X0ZC/nVBL+ATiHpu0= + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{{0., 101.}, {0., 163.8199969393377}}, + PlotRangeClipping->True, + PlotRangePadding->{ + Scaled[0.02], + Scaled[0.02]}]], "Output", + CellChangeTimes->{3.514432694745741*^9, + 3.5636675294731216`*^9},ExpressionUUID->"bddef3f5-0a3a-4e13-afbc-\ +5f6245eb5cc0"] +}, Open ]], + +Cell["\<\ +Notice that in this case the diploids have higher reproductive capacity (1.5 \ +offspring on average), yet it is the haploid population size that grows to a \ +larger size. This is, of course, because diploids beget haploids.\ +\>", "Text", + CellChangeTimes->{{3.514432739753072*^9, + 3.5144328205024443`*^9}},ExpressionUUID->"650ae84b-5ec7-4b74-8867-\ +978a9284c976"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["A case with complex eigenvalues [EXTRA]", "Subsection", + CellChangeTimes->{{3.514165215616572*^9, 3.514165236893621*^9}, { + 3.514430683797038*^9, 3.514430689690156*^9}, {3.514512244518821*^9, + 3.5145122466138*^9}},ExpressionUUID->"855ac022-6df1-4808-b4e6-bd05ae13e8d7"], + +Cell["\<\ +Some systems cycle over time. As an example, let's consider the classic \ +predator-prey model. + +Let H[t] represent the numbers of prey and P[t] represent the numbers of \ +predators. The prey are assumed to grow exponentially, but they are +captured by predators at a rate that depends on both the availability of prey \ +and predators. + +The discrete-time recursions are thus: + +Prey: \t\tH[t+1] = H[t] + r H[t] - b H[t] P[t] +Predator:\tP[t+1] = P[t] + c H[t] P[t] - d P[t] + +which uses the following parameters: +\tthe growth rate of the prey in the absence of the predator (r), +\tthe capture rate at which predators contact and kill prey (b), +\tthe rate at which eaten prey are turned into predator babies (c), +\tand the death rate of predators (d).\ +\>", "Text", + CellChangeTimes->{{3.514427943218479*^9, 3.514427992056077*^9}, { + 3.51443070318458*^9, + 3.5144308123841467`*^9}},ExpressionUUID->"adbfe2dd-c363-48a4-a73d-\ +6c3886b8fe53"], + +Cell["The equilibrium of this model is:", "Text", + CellChangeTimes->{{3.514428019317086*^9, 3.514428101517205*^9}, { + 3.5144281484116297`*^9, 3.514428153504444*^9}, {3.514428229695262*^9, + 3.5144282331832857`*^9}, {3.514430772647252*^9, + 3.51443080603729*^9}},ExpressionUUID->"dacd7d5c-f30d-43d8-aade-\ +b70915a608ab"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + FormBox[ + OverscriptBox["H", "^"], + TraditionalForm], " ", "==", + RowBox[{ + FormBox[ + OverscriptBox["H", "^"], + TraditionalForm], "+", + RowBox[{"r", " ", + FormBox[ + OverscriptBox["H", "^"], + TraditionalForm]}], "-", + RowBox[{"b", " ", + FormBox[ + OverscriptBox["H", "^"], + TraditionalForm], " ", + FormBox[ + OverscriptBox["P", "^"], + TraditionalForm]}]}]}], ",", + RowBox[{ + FormBox[ + OverscriptBox["P", "^"], + TraditionalForm], " ", "==", + RowBox[{ + OverscriptBox["P", "^"], "+", + RowBox[{"c", " ", + FormBox[ + OverscriptBox["H", "^"], + TraditionalForm], " ", + FormBox[ + OverscriptBox["P", "^"], + TraditionalForm]}], "-", + RowBox[{"d", " ", + FormBox[ + OverscriptBox["P", "^"], + TraditionalForm]}]}]}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + OverscriptBox["H", "^"], ",", + OverscriptBox["P", "^"]}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.514428199117491*^9, 3.5144282532487717`*^9}, { + 3.514428327624214*^9, + 3.514428414477846*^9}},ExpressionUUID->"098a5b2f-d58c-49f7-8e01-\ +49d551a1f714"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + OverscriptBox["H", "^"], "\[Rule]", "0"}], ",", + RowBox[{ + OverscriptBox["P", "^"], "\[Rule]", "0"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{ + OverscriptBox["H", "^"], "\[Rule]", + FractionBox["d", "c"]}], ",", + RowBox[{ + OverscriptBox["P", "^"], "\[Rule]", + FractionBox["r", "b"]}]}], "}"}]}], "}"}]], "Output", + CellChangeTimes->{ + 3.51442841517968*^9},ExpressionUUID->"a8f24c50-9f41-48f7-a6d3-72aa8107d410"] +}, Open ]], + +Cell[TextData[{ + "Here we've asked ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " for all of the sets of solutions for the number of prey and predators ", + Cell[BoxData[ + RowBox[{"{", + FormBox[ + RowBox[{ + RowBox[{ + OverscriptBox["H", "^"], ",", + OverscriptBox["P", "^"]}], "}"}], + TraditionalForm]}]], + CellChangeTimes->{{3.514428199117491*^9, 3.5144282532487717`*^9}}, + ExpressionUUID->"b0399046-ad53-4440-bba5-3a2672464d94"], + "that cause both of these values to remain constant in the next generation." +}], "Text", + CellChangeTimes->{{3.51442825542505*^9, + 3.514428315406611*^9}},ExpressionUUID->"7dc3ed25-f099-4e15-a3c3-\ +4187128ca5f3"], + +Cell["Finding the ", "Text", + CellChangeTimes->{{3.514429858727319*^9, 3.514429896174037*^9}, { + 3.514431755945674*^9, + 3.514431757791016*^9}},ExpressionUUID->"9a121723-c825-4085-bfe6-\ +d6e64694c4af"], + +Cell[BoxData[{ + RowBox[{ + RowBox[{"eqnH", "=", + RowBox[{ + RowBox[{"H", "[", "t", "]"}], " ", "+", " ", + RowBox[{"r", " ", + RowBox[{"H", "[", "t", "]"}]}], " ", "-", " ", + RowBox[{"b", " ", + RowBox[{"H", "[", "t", "]"}], " ", + RowBox[{"P", "[", "t", "]"}]}]}]}], ";"}], "\n", + RowBox[{ + RowBox[{"eqnP", "=", " ", + RowBox[{ + RowBox[{"P", "[", "t", "]"}], " ", "+", " ", + RowBox[{"c", " ", + RowBox[{"H", "[", "t", "]"}], " ", + RowBox[{"P", "[", "t", "]"}]}], " ", "-", " ", + RowBox[{"d", " ", + RowBox[{"P", "[", "t", "]"}]}]}]}], ";"}]}], "Input", + CellChangeTimes->{{3.514429904547501*^9, 3.51442992342336*^9}, { + 3.514681020255619*^9, + 3.514681022085836*^9}},ExpressionUUID->"71426e94-b246-452c-be0b-\ +9c386eb2818a"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"matrix", "=", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"D", "[", + RowBox[{"eqnH", ",", + RowBox[{"H", "[", "t", "]"}]}], "]"}], ",", + RowBox[{"D", "[", + RowBox[{"eqnH", ",", + RowBox[{"P", "[", "t", "]"}]}], "]"}]}], "}"}], ",", + "\[IndentingNewLine]", + RowBox[{"{", + RowBox[{ + RowBox[{"D", "[", + RowBox[{"eqnP", ",", + RowBox[{"H", "[", "t", "]"}]}], "]"}], ",", + RowBox[{"D", "[", + RowBox[{"eqnP", ",", + RowBox[{"P", "[", "t", "]"}]}], "]"}]}], "}"}]}], "}"}]}]], "Input", + CellChangeTimes->{{3.51442993198416*^9, 3.5144299850653954`*^9}, { + 3.5144300475033083`*^9, 3.514430056546912*^9}, {3.514681024117813*^9, + 3.51468102932576*^9}},ExpressionUUID->"5de1e242-2f7a-4bad-ac49-\ +a8f9982ef37c"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"1", "+", "r", "-", + RowBox[{"b", " ", + RowBox[{"P", "[", "t", "]"}]}]}], ",", + RowBox[{ + RowBox[{"-", "b"}], " ", + RowBox[{"H", "[", "t", "]"}]}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"c", " ", + RowBox[{"P", "[", "t", "]"}]}], ",", + RowBox[{"1", "-", "d", "+", + RowBox[{"c", " ", + RowBox[{"H", "[", "t", "]"}]}]}]}], "}"}]}], "}"}]], "Output", + CellChangeTimes->{3.514429985443801*^9, 3.51443004824973*^9, + 3.514681031499619*^9},ExpressionUUID->"377ffe04-779a-4bf9-a404-\ +958d04aa437a"] +}, Open ]], + +Cell["\<\ +Let's consider the stability of the equilibrium with both prey and predators \ +present:\ +\>", "Text", + CellChangeTimes->{{3.51442999874765*^9, + 3.514430033710093*^9}},ExpressionUUID->"dbad70cc-7af3-4a3c-b334-\ +bdbe93532d09"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"matrix", "/.", + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"H", "[", "t", "]"}], "\[Rule]", + FractionBox["d", "c"]}], ",", + RowBox[{ + RowBox[{"P", "[", "t", "]"}], "\[Rule]", + FractionBox["r", "b"]}]}], "}"}]}]], "Input", + CellChangeTimes->{{3.514430040650399*^9, + 3.514430069985098*^9}},ExpressionUUID->"38d15bf3-de85-4369-b68f-\ +01e5e65db9da"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"1", ",", + RowBox[{"-", + FractionBox[ + RowBox[{"b", " ", "d"}], "c"]}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + FractionBox[ + RowBox[{"c", " ", "r"}], "b"], ",", "1"}], "}"}]}], "}"}]], "Output", + CellChangeTimes->{{3.514430059567871*^9, 3.514430070433909*^9}, + 3.514681032884527*^9},ExpressionUUID->"4db48e60-f0fb-4978-b03b-\ +40f6acfed804"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Eigenvalues", "[", "%", "]"}]], "Input", + CellChangeTimes->{{3.514430075822959*^9, + 3.514430078517954*^9}},ExpressionUUID->"b4bf41ef-f692-4aac-84d9-\ +1b3ccd5a58e5"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"\[ImaginaryI]", " ", + RowBox[{"(", + RowBox[{ + RowBox[{"-", "\[ImaginaryI]"}], "+", + RowBox[{ + SqrtBox["d"], " ", + SqrtBox["r"]}]}], ")"}]}], ",", + RowBox[{ + RowBox[{"-", "\[ImaginaryI]"}], " ", + RowBox[{"(", + RowBox[{"\[ImaginaryI]", "+", + RowBox[{ + SqrtBox["d"], " ", + SqrtBox["r"]}]}], ")"}]}]}], "}"}]], "Output", + CellChangeTimes->{3.514430079485057*^9, + 3.51468103504421*^9},ExpressionUUID->"37bc675d-09ed-40ec-a5cc-e7b1b8f541f3"] +}, Open ]], + +Cell[TextData[{ + "where ", + Cell[BoxData[ + RowBox[{"\[ImaginaryI]", "=", + SqrtBox[ + RowBox[{"-", "1"}]]}]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "eccee3f6-81f1-4b92-a4ff-1c5d05438d6a"], + ". The above eigenvalues can be written more simply as {", + Cell[BoxData[ + RowBox[{ + RowBox[{"1", "+", + RowBox[{"\[ImaginaryI]", + SqrtBox[ + RowBox[{"d", " ", "r"}]]}]}], ",", + RowBox[{"1", "-", + RowBox[{"\[ImaginaryI]", + SqrtBox[ + RowBox[{"d", " ", "r"}]]}]}]}]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "15b76ab0-0c86-4b08-b934-8f6b5759a4cb"], + "}. Note that the death rate of predators (d) and the intrinsic growth rate \ +of prey (r) can be assumed to be positive in this model, so these eigenvalues \ +are complex numbers.\n\nStill, the recipe for discrete-time models remains \ +the same: we find the absolute magnitude of the eigenvalue and if it is \ +greater than one then the system is unstable. (The rule is slightly \ +different for continuous-time models. See Chapter 8.)" +}], "Text", + CellChangeTimes->{{3.514431883298354*^9, 3.51443192551478*^9}, { + 3.514431961236163*^9, 3.514432105822605*^9}, {3.514432189176014*^9, + 3.514432192277246*^9}},ExpressionUUID->"cf31d981-a20d-4e1f-bc3e-\ +6384ee4a48c3"], + +Cell[TextData[{ + StyleBox["DEFINITION: ", + FontWeight->"Bold"], + "The absolute magnitude of a complex number is ", + Cell[BoxData[ + SqrtBox[ + RowBox[{ + SuperscriptBox[ + RowBox[{"(", + RowBox[{"real", " ", "part"}], ")"}], "2"], "+", + SuperscriptBox[ + RowBox[{"(", + RowBox[{"complex", " ", "part"}], ")"}], "2"]}]]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "eeb5e113-673d-428f-87d5-317bc7ae171d"], + ". " +}], "Text", + CellChangeTimes->{{3.513952892348854*^9, 3.513953040559141*^9}, { + 3.5139530860602407`*^9, 3.513953248089283*^9}, {3.5139532807435417`*^9, + 3.5139533435238113`*^9}, {3.513953820688054*^9, 3.513953821172909*^9}, { + 3.5139541156033278`*^9, 3.51395418519324*^9}, {3.514117216818845*^9, + 3.51411725649579*^9}, {3.5141173045923347`*^9, 3.514117377492393*^9}, { + 3.514117840393688*^9, 3.5141181925597687`*^9}, {3.514118250452888*^9, + 3.5141182831133347`*^9}, {3.514429521011125*^9, 3.514429568501519*^9}, { + 3.514429683894281*^9, 3.514429707893236*^9}, {3.514429743607738*^9, + 3.514429845831918*^9}, {3.514430368427335*^9, 3.5144303866734123`*^9}, { + 3.514432121433972*^9, 3.514432163272746*^9}}, + Background->RGBColor[ + 0.9900968947890441, 1., + 0.7349202716105898],ExpressionUUID->"86f59446-8f78-4386-8bd3-46be8378d541"], + +Cell[TextData[{ + "Here, the real part is \"1\" and the complex part is the part \"", + Cell[BoxData[ + SqrtBox[ + RowBox[{"d", " ", "r"}]]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "df166b98-14a1-4654-8900-ab49be6c2bf1"], + "\" multiplying ", + Cell[BoxData[ + RowBox[{"\[ImaginaryI]", "=", + SqrtBox[ + RowBox[{"-", "1"}]]}]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "ef9bfb9a-d41c-42de-b1be-28582fef9a93"], + ". So the magnitude of both eigenvalues is ", + Cell[BoxData[ + SqrtBox[ + RowBox[{ + SuperscriptBox[ + RowBox[{"(", "1", ")"}], "2"], "+", + SuperscriptBox[ + RowBox[{"(", + SqrtBox[ + RowBox[{"d", " ", "r"}]], ")"}], "2"]}]]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "771553ad-faa9-42d4-a67a-095c71d39eb7"], + ", or just ", + Cell[BoxData[ + SqrtBox[ + RowBox[{"1", "+", + RowBox[{"d", " ", "r"}]}]]], + CellChangeTimes->{3.514430079485057*^9},ExpressionUUID-> + "9aeb241b-8179-4c03-996e-a0373182b872"], + ", which must be a number greater than one." +}], "Text", + CellChangeTimes->{{3.514432168786694*^9, + 3.5144322771621237`*^9}},ExpressionUUID->"e10779af-4db5-4e4c-83af-\ +e298fca8bb43"], + +Cell[TextData[{ + "\t\[Rule] The predator-prey model will cycle (because \[Lambda] is \ +complex) and expand away \n\tfrom the equilibrium at ", + Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"H", "[", "t", "]"}], "\[Rule]", + FractionBox["d", "c"]}], ",", + RowBox[{ + RowBox[{"P", "[", "t", "]"}], "\[Rule]", + FractionBox["r", "b"]}]}], "}"}]], + CellChangeTimes->{{3.514430040650399*^9, 3.514430069985098*^9}}, + ExpressionUUID->"186d1694-4f00-4fe9-b142-23e5c25676e3"], + " (because ", + "|\[Lambda]| > 1)." +}], "Text", + CellChangeTimes->{{3.5144323346975193`*^9, + 3.5144324054909477`*^9}},ExpressionUUID->"191a1bec-aaf8-4c6c-bb38-\ +585b844c8776"], + +Cell["\<\ +We can use the same basic code again to track the prey and predator \ +population sizes.\ +\>", "Text", + CellChangeTimes->{{3.5144328332623262`*^9, 3.514432913107875*^9}, { + 3.5144329503095703`*^9, + 3.514432963834735*^9}},ExpressionUUID->"bb1b30ee-b64b-44be-8fed-\ +3512c87c9db5"], + +Cell[BoxData[{ + RowBox[{"Clear", "[", "predprey", "]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "r_", ",", "b_", ",", "c_", ",", "d_", ",", "H0_", ",", "P0_", ",", + "t_"}], "]"}], ":=", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "r", ",", "b", ",", "c", ",", "d", ",", "H0", ",", "P0", ",", "t"}], + "]"}], "=", "\[IndentingNewLine]", + RowBox[{"Block", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"H", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "r", ",", "b", ",", "c", ",", "d", ",", "H0", ",", "P0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "1"}], "]"}]}], ",", + RowBox[{"P", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "r", ",", "b", ",", "c", ",", "d", ",", "H0", ",", "P0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "2"}], "]"}]}]}], "}"}], + ",", "\[IndentingNewLine]", "\t", + RowBox[{"{", + RowBox[{ + RowBox[{"H", " ", "+", " ", + RowBox[{"r", " ", "H"}], " ", "-", " ", + RowBox[{"b", " ", "H", " ", "P"}]}], ",", " ", + RowBox[{"P", "+", " ", + RowBox[{"c", " ", "H", " ", "P"}], " ", "-", " ", + RowBox[{"d", " ", "P"}]}]}], "}"}]}], "\[IndentingNewLine]", "\t", + "]"}]}]}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "r_", ",", "b_", ",", "c_", ",", "d_", ",", "H0_", ",", "P0_", ",", "0"}], + "]"}], ":=", + RowBox[{"{", + RowBox[{"H0", ",", "P0"}], "}"}]}]}], "Input", + CellChangeTimes->{{3.514424045707509*^9, 3.514424061967498*^9}, { + 3.5144255050950212`*^9, 3.514425607017445*^9}, {3.514425642488206*^9, + 3.514425669408059*^9}, {3.514425734177042*^9, 3.514425737442438*^9}, { + 3.514426238427285*^9, 3.5144262538256493`*^9}, {3.514426381804556*^9, + 3.514426383523755*^9}, 3.5144264576520653`*^9, {3.5144266314259853`*^9, + 3.5144266539839983`*^9}, {3.514427148128552*^9, 3.5144271570026703`*^9}, { + 3.514432474189856*^9, 3.514432582465474*^9}, {3.514432967303516*^9, + 3.5144330531098347`*^9}, {3.5144331118463917`*^9, + 3.5144331334910192`*^9}, {3.5146810677550793`*^9, + 3.5146810710887957`*^9}},ExpressionUUID->"ac165de2-81ec-43b8-85f4-\ +e5f933894914"], + +Cell["\<\ +We can then make a table of population sizes for {prey, predators}:\ +\>", "Text", + CellChangeTimes->{{3.514426311595162*^9, 3.514426337581416*^9}, { + 3.5144326128151073`*^9, 3.514432625364406*^9}, {3.514433379634694*^9, + 3.514433385176149*^9}},ExpressionUUID->"4a4e8c9e-4873-421f-bc44-\ +416db59e6084"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "0.7", ",", "0.01", ",", "0.0001", ",", "0.1", ",", "900", ",", "70", ",", + "t"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5144262691718893`*^9, 3.514426294228351*^9}, { + 3.5144263455531607`*^9, 3.5144263905959597`*^9}, {3.514426567695655*^9, + 3.514426611405775*^9}, {3.51442669599331*^9, 3.514426706329217*^9}, { + 3.514432589298902*^9, 3.514432602070593*^9}, {3.514433055820443*^9, + 3.514433088432345*^9}, {3.514433167641354*^9, 3.5144331683913803`*^9}, { + 3.5144332023425407`*^9, 3.514433214664681*^9}, {3.514433244887226*^9, + 3.514433263310009*^9}, {3.514433304783252*^9, 3.514433328898786*^9}, + 3.514433370212604*^9, 3.5144334377781887`*^9, {3.514433469033687*^9, + 3.51443349120623*^9}},ExpressionUUID->"bd2c85b5-2090-42ef-9267-\ +7b6b37605ab3"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"900", ",", "70"}], "}"}], ",", + RowBox[{"{", + RowBox[{"900.`", ",", "69.3`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"906.3`", ",", "68.607`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"918.924759`", ",", "67.96415241`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"937.6326665600147`", ",", "67.41313140639986`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"961.8879915345913`", ",", "66.99269368193421`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"990.814909876727`", ",", "66.73737107106157`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1023.1415237586003`", ",", "66.67607219427377`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1057.1500093587433`", ",", "66.83037078515517`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1090.657744900113`", ",", "67.21230641673716`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1121.0619408700525`", ",", "67.82163802966484`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1145.482727853867`", ",", "68.64269994295057`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1161.0303655725188`", ",", "69.64133266644606`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1165.1946022264692`", ",", "70.76276959226958`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1156.3068521099192`", ",", "71.9317323497934`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1133.970098584834`", ",", "73.05607461483436`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1099.3151262621707`", ",", "74.03480756667139`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1054.9598763661816`", ",", "74.77008519279934`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1004.637391513664`", ",", "75.18102065660786`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"952.5869207353347`", ",", "75.21588503932601`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"902.901082050124`", ",", "74.85926336739286`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"859.0267405262686`", ",", "74.132388020243`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"823.528422410077`", ",", "73.0873195830645`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"798.1034681529085`", ",", "71.79753612420028`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"783.7572700043646`", ",", "70.34796877033605`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"781.0300394695109`", ",", "68.82674508868153`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"790.1935127664594`", ",", "67.31964612313047`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"811.3734952206668`", ",", "65.90723627564057`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"844.5810953021254`", ",", "64.6640511138066`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"889.6475108498992`", ",", "63.65904951406307`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"946.0596190122615`", ",", "62.956556056982436`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1012.6947979449156`", ",", "62.61696599504348`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1087.4623992436145`", ",", "62.69645696816655`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1166.8856835273803`", ",", "63.24481522321754`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1245.7109675834758`", ",", "64.30028064502649`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1316.712996709859`", ",", "65.88020906234433`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1370.958819423246`", ",", "67.96672090594504`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1398.8342384866814`", ",", "70.4880063606789`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1392.007838427512`", ",", "73.29930939460947`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1346.081193040573`", ",", "76.1726997780105`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1262.9916422259164`", ",", "78.80889365964002`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1151.7360515320943`", ",", "80.88150169619566`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1026.4098735489324`", ",", "82.10876566713236`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"902.1243071765825`", ",", "82.32561387898515`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"790.931948365527`", ",", "81.51984622943327`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"699.8178041343576`", ",", "79.81552668736032`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"631.1270008066508`", ",", "77.41960668084185`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"584.2998596902037`", ",", "74.5638064295687`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"557.6335451257012`", ",", "71.46418795008827`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"549.4687419523207`", ",", "68.30285200269316`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"558.7940397021915`", ",", "65.22559501859138`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"585.4731301695474`", ",", "62.34780288997402`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"630.27468811636`", ",", "59.76331893269532`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"694.7938977867811`", ",", "57.5537177595361`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"781.2699072948442`", ",", "55.797143173009324`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"892.2325536602937`", ",", "54.576691743117806`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1029.8443307795724`", ",", "53.98853267323529`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1194.7375193188823`", ",", "54.14965783597567`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1384.1075040929013`", ",", "55.204154839870085`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1588.8979072482257`", ",", "57.324587852980144`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1790.2972655873116`", ",", "60.70042083502885`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1956.7873770889175`", ",", "65.49755849562109`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"2044.890584107416`", ",", "71.76428221549642`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"2008.8129432056478`", ",", "79.26286449171637`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1822.7393223844492`", ",", "87.25900485319626`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1508.1526542730005`", ",", "94.43814630568227`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1139.5881021087341`", ",", "99.23704577666771`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"806.4062070297447`", ",", "100.62227686455198`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"559.466265660164`", ",", "98.6742920410008`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"399.0432747738872`", ",", "94.32735660538464`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"301.96659430983874`", ",", "88.65869067290387`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"245.62358154206333`", ",", "82.47001789346011`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"214.99427697321045`", ",", "76.24867422059707`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"201.55998501222635`", ",", "70.26310965695967`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"201.0296612270927`", ",", "64.65302182420062`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"211.77867333978875`", ",", "59.48743714924325`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"234.04203947913288`", ",", "54.798510486304004`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"269.6199155681935`", ",", "50.601174953136926`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"321.9230112807673`", ",", "46.90536590967485`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"396.26995278861665`", ",", "43.72482098259424`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"500.39059227601496`", ",", "41.08502215898115`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"645.0784211511677`", ",", "39.03237580026361`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"844.8438824068542`", ",", "37.647032555738555`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1118.1759486367782`", ",", "37.06291581471344`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1486.4705021789005`", ",", "37.500910338278324`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1969.5598834770658`", ",", "39.32521900672114`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"2573.7180642651338`", ",", "43.138034482507805`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"3265.0693232055014`", ",", "49.92674489470929`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"3920.4750178171307`", ",", "61.235498721560575`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"4264.085100874611`", ",", "79.11917314354963`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"3875.2357975375526`", ",", "104.94434456868754`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"2521.0600475969036`", ",", "135.11831819398816`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"879.3881439412426`", ",", "155.6706257443243`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"126.01081830538067`", ",", "153.7930534338392`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"20.422505990334997`", ",", "140.3517069417434`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"6.0549244258545265`", ",", "126.6031696051462`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"2.6276452836246635`", ",", "114.01950990703486`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"1.4709687076777709`", ",", "102.64751919907621`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0.9907339164262672`", ",", "92.39786640803484`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0.7688306573660203`", ",", "83.16723393723694`"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0.6675969261294398`", ",", "74.85690469542718`"}], "}"}]}], + "}"}]], "Output", + CellChangeTimes->{ + 3.5144326027095003`*^9, {3.514433080261643*^9, 3.514433089010504*^9}, { + 3.514433142898706*^9, 3.514433168909243*^9}, {3.514433202764488*^9, + 3.514433215153358*^9}, {3.514433245619088*^9, 3.514433264201297*^9}, { + 3.514433305303959*^9, 3.5144333293441133`*^9}, 3.514433370658637*^9, + 3.5144334380363503`*^9, {3.514433469655059*^9, + 3.51443349224201*^9}},ExpressionUUID->"88b0b3db-adf6-493b-8d2a-\ +ec64675522b4"] +}, Open ]], + +Cell["or plotting prey in red and predators in blue:", "Text", + CellChangeTimes->{{3.5144263221305637`*^9, 3.514426329021406*^9}, { + 3.514426565192073*^9, 3.5144265653575697`*^9}, {3.514432634174358*^9, + 3.514432637243886*^9}, {3.5144327125256863`*^9, 3.514432718011566*^9}, { + 3.514433391017737*^9, + 3.514433395311802*^9}},ExpressionUUID->"e2c4c24e-d9db-4fab-b50f-\ +3254ab48abc2"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "0.7", ",", "0.01", ",", "0.0001", ",", "0.1", ",", "900", ",", + "70", ",", "t"}], "]"}], ",", "1"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}], ",", + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "0.7", ",", "0.01", ",", "0.0001", ",", "0.1", ",", "900", ",", + "70", ",", "t"}], "]"}], ",", "2"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]}], "}"}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Red", ",", "Blue"}], "}"}]}], ",", + RowBox[{"PlotRange", "\[Rule]", "All"}]}], "]"}]], "Input", + CellChangeTimes->{{3.514432638805904*^9, 3.514432693910797*^9}, { + 3.514433413578724*^9, 3.5144334239940023`*^9}, {3.514433455050741*^9, + 3.5144335158256702`*^9}},ExpressionUUID->"58eda0db-0570-4b84-95fe-\ +1e162b7b6aa7"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {RGBColor[1, 0, 0], LineBox[CompressedData[" +1:eJxVlXtQVGUYxrfMRNHAgkBuopGiyE1YruI+LLAoN3eXZVnWGBUCEgSJQdwB +g5XLcIlbgEqBCeOiaDPExQKJMSRMywIdTBAIhosDRFwUiDSDMt7vj87Mzpnf +Pud3zvs955w5W0KOi8Ne5XA4Yf/+Xu5XtlnefzvjXNAf+D+rIfzlJmasifgp +9fGwRsZa8HI/1aDhm0esi3xXvzI9jXxiA3SbK2bS/2BsjGApt3vLswLirTh7 +eUP5p+mFxCYIWT+UWbnuE+JtqDoWHc1LZ2yK8VGucPox450oemu77maTIuJd +qA7q8Lhty9gCvLRYe6eNjK2gtpxxZKiR+dbIVpyo5Zsz3o17aQ8mHiaxeWyQ +1Nl0eFMYm9cWfeUpq+rb2Xq5CE49Hcm1Z33Y4WhNy3d2PTnE9ljrl8l1askm +dsDBCIOxrtksYkeMnSweeSOZsRMMggIyXD5g7IzI3ihhbh3jPeic0Zh8IWfn +c8GYjbf2pffZ9fbiubGZnsXPHxPzoHkoa1NiIZsXmDrj+DS/itajBLTmLVMe +/c3W64r7IRdmc5ypL6UrLAaG1/QkFFPOB2dPp35vUQnlfMQJ2h78EnWGcjfE +vXueL+0jVrrBffHu62qtLHdHfaO7ib8ay91RLND4cPEbdn4PaO5MbnyyRPdD +6QEVRr+6uJbNJ4DqXlvJkhX1rRRgyVlWGd/I+vHET/2j/TkDGZR7Yv31Zd3X +rqdRvg+p0ocG4fxUyvch8qC+cmP0acr3o6fv9l/fmhEr90P/1ilreQLLvVAd +ofjzjjfzvTA9XFOwu56d3xstttpjQV+z63sjYXj7LdNINp8P7H7X8egfovuj +9IHWCV7pYR22Pl+8+YWbw9xV1r8vfszN046pYP35YThiOf5cVynlfpgcCA23 +elZG+QFoPzcXbCv+nPIDaLvhuVAwd4FyITassYxHKDGEUAVNaS4kltPxQmT2 +hIvKC8+tcKsQIzGx9vIO9n6I4FGpmODZ0PMHERzyPppoTmJ9iRB+ZQR1swry +RTCUlJqdHIwjXwyVteeR+YYY8sWQhz4xvD8YSb4YYQ61YZPWR8kXQ7RO78VT +Y2KOPwy15aO/Keh4+CNLaR4qc40m3x9tTmd3TT6KJd8fN9UTL7cbxZMvwY6J +Vc2idpoPEgw2ffkrT5BCvgSqFveyCtN08iUYkEV5tIaz9ysA81uHzK4pqA8E +wKdFfHfIkfpSBkBgpCt2+Z76bw2APN/o0nF9FflSLN6RJL+TeoV8KazUs7lz +FTXkSyG6afaDdnUt+VJkxcY3KwSUcwLR+UrBDaP6i+QHwmGaO6mXxJ6nQDTN +8Xl1ykPkB0LWy5fvOGZLvgyjll36ex10yZfhKhZGIlevJl+GjKqOpLezF1e+ +C60yFHXzz+tcm1lhThCCi61b+Z+NrzCC0CAvcZp/7zHvH0tnxI0= + "]]}, + {RGBColor[0, 0, 1], LineBox[CompressedData[" +1:eJw9lAswXGcYhhdNSMRIx7UaSkZtLGMixD3xumxY1i679iZShDAxlahGRmJG +lqpIUzNSssRoSKNRl0ylQZtOwzYVGYSiW0okFRIz0mglVLVJqDT/1zNz5sxz +3vP85/u/78xx2H9YckCfw+EcWDtfXl8d84H/XdQxYDfg8fKQEhtB3+Wk5ZgT +8WYMSsXNrS+iGZtj/URbR+Y4sTWq280jizuJt+DowCFL9y+J7WGwQdwV2kS8 +FTNZ+X2ObcSOyOPWZ2j6iZ1w92Lz12cXibch3PDJioMz1cNDgalLpfFBYldU +RJZ4D7UQu8Gv8xv1hWfE2xHv9eyaJkTC2B1Z9oUCvwLiHUBJmpngCrEHVvUa +R8/2EXsieybXdKifeCeqUm+5rLQTe+FObJXxsWJib6wkT9Zp+MQ+SGtd1G1c +oHp8Mc4dsONriP1gkO+fMutJ7I974QYW2TrafwC0ade3bT5OvAsveLsHT/CI +dyOgef13e3VixoGY/KE3I/M4MaD69v71ZRFjNZDQnKd+W0V5ELbWzdvIaygP +wmW1+La3Ga0fjDibFKUsh7E6GG5j8d/f+/97CEH3iOEJ/xpWvzoEc6KKKa6U +9h8Kn8/f+cDEWMryULxVNDvbdZUxh48xB6uidJ9YlvPRPsh/bamIMWcP9ioq +74yUU74Hqgo7Z34S5WEoH/hF475I64fh5Ng/P4/H0frhSH+9NM2ijtWjDscD +z8SgtrvUbwGsu/fNJZlR/QKkdFo6ZYpofxEIfWozUOhK/YnABlfR4db7USyP +hL6Xn+9kt5DlkdDjnusxmolkuRA+4ctGQwLGaiFUAqtdxSsRLI/ChyW/Peea +UR6FxbDHHQ5V5IsQ/Gmw9ccNtL4IqU+GkutVIpaLUfyZZnU0geYjhpvd4urs +PO0vGg9va24OD7J+IBpzeVanygZl7PlobH+vX7OxWvGKtdGQV2+64fKjkvkx +uFam2P8TV8X8GAgNBs5xm1i+9h95t9Tu4EI5+TGIK3v8nMuTM1+C0wG/3zQ/ +z+YFCeo9w8IemdK8JND9PdUzUsrq1Uqw7sKmLX3O1H8pcjJcFCkdrN+Qwtn6 +SMXOVOqXFL9mrYtaEAqYL0Vnbrvh9PthzI/FjjGrP7on+MxfY4dSvamPQpm/ +xl88nHYsDGF+LCxcjy0NDQczXwZv4Zu1JsWMIYPtmRydrZaxWgbdwo3u2gby +ZWgx5tk2nWHv48hxJOhiWc1SOPPlsLucPex4ns1PLcdEUUpx7S3WD60cXY0e +jpkBccxX4FB7QEjPdCLzFYj+y64rOzuZ+QoERFReSfRlrFXA5JNHbkGnk5iv +hE6/JbbqUgLzlUjn5V4KzI9nvhL2D/YtZjaw+WqVeNrUWHf0DTZPjgpf9S// +ebWX5qdCQUNv0eja/+9fMEqz3g== + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{All, All}, + PlotRangeClipping->True, + PlotRangePadding->{Automatic, Automatic}]], "Output", + CellChangeTimes->{ + 3.514432694745741*^9, {3.5144334250151863`*^9, + 3.51443351633298*^9}},ExpressionUUID->"af794f0f-9f90-4517-834d-\ +e164ba5a68af"] +}, Open ]], + +Cell["\<\ +I purposely started this near the equilibrium (1000,70), otherwise it cycles \ +out so fast that it crashes and burns very quickly. Even here, the prey go \ +extinct by the end of this 100-generation simulation.\ +\>", "Text", + CellChangeTimes->{{3.514433545940539*^9, + 3.514433606886168*^9}},ExpressionUUID->"53242a9e-fb52-444b-8c41-\ +069bc627348e"], + +Cell["\<\ +I purposely started this near the equilibrium (1000,70), otherwise it cycles \ +out so fast that it crashes and burns very quickly. Even here, the prey go \ +extinct by the end of this 100-generation simulation. + +We can also present this graph as a phase-diagram, where the number of \ +predators (y-axis) is plotted against the number of prey (x-axis):\ +\>", "Text", + CellChangeTimes->{{3.514433545940539*^9, 3.514433606886168*^9}, { + 3.514544019091618*^9, + 3.5145440482866077`*^9}},ExpressionUUID->"da97b996-df39-49ee-a52f-\ +cde427c9581a"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "0.7", ",", "0.01", ",", "0.0001", ",", "0.1", ",", "900", ",", + "70", ",", "t"}], "]"}], ",", "2"}], "]"}], ",", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"predprey", "[", + RowBox[{ + "0.7", ",", "0.01", ",", "0.0001", ",", "0.1", ",", "900", ",", + "70", ",", "t"}], "]"}], ",", "1"}], "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Red", ",", "Blue"}], "}"}]}], ",", + RowBox[{"PlotRange", "\[Rule]", "All"}], ",", + RowBox[{"AxesOrigin", "\[Rule]", + RowBox[{"{", + RowBox[{"0", ",", "0"}], "}"}]}]}], "]"}]], "Input", + CellChangeTimes->{{3.514432638805904*^9, 3.514432693910797*^9}, { + 3.514433413578724*^9, 3.5144334239940023`*^9}, {3.514433455050741*^9, + 3.5144335158256702`*^9}, {3.51454405774715*^9, + 3.514544101838194*^9}},ExpressionUUID->"4075c550-69ae-409a-bee8-\ +92d534acc1fe"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {RGBColor[0, 0, 1], LineBox[CompressedData[" +1:eJxFlHs81IkCxStblFx1JSKz7NomppQiknaOYUhkfjMjzJSLMNYUWYudZa/3 +Y7znwZAUbkpoW6+orkVW2pJXWe+URw9JKVN6stp/9vv5nM/5nL/P+Ry9I8dZ +vsuWLFniu6jP/jfRTPztumnY+Rn2P3kZJWn9wCYmeJ9hpaGLzbhQ84lAyLTy +E9+6NKwYvtQQNEhgv83P1aoH0pFfu85B2Eggw8rppJZqBsI6Atcb/0qgb6vg +RfybDCisZLTYlBNwdzHt03uXiUfBMW36lwjISlTyT8SLEEkuCZC1EziyejSp +aJUY985cqMuWEzh7LCCAGi/GPsWX83oGTDyZMCWePxQjVpWSq+zPhESNrPml +vgQ5Dulm3RVMnOd00G+YSGDReDm66AMT1LggM4u1Ehze9eGKzJoFpYUEr9E6 +MYJ14+0tYllIFoRW0LaKgXQ/NftKFrrieiZ7I0RYWFrWl93GQkTnZc8NvpkI +fRSh2t3OwlB+lEJVSzryeDco87UsuMfG8E3N0jDknKf8k5AF/4v1v+/qT8G8 +94NiGZ2FlU5Jphb1yfCrkfesmmXikN/Gx3dnhBgkd5DoMiYe/ygd/1ekEAox +e3wmTZjYyDmYsPc7IUb2KaiH9hDgDx4l0iqFaPL7bfOacAKdL1SnPnKT8cnw +264oQwKPdzqon/NJgeWFFfWHehh4r0vRMmpPxYPfbwUEhTOwxkO4IVyUDs7V +0d/eOjEwnb37VcbZTHhciIz+hsPAOvm2qIFPInxVPKPlUsBA95GCmZQ9EvwS +zbhtpkbAaGRMsT9MCq6Wj9tBAYEllp3ag5IsGA0cvjayuIdg2+aeP49mo7VX +MWpPARPB35yiuQxlY9opZ4zMZsFmrm2FUlM2zM/+J05FmY2qOht9tlI2vkyc +nGypZkNqq/r93P+lGNDTSOSbO2ONYWTdy3kxarvoX7xJdEYxJi6dWSnCIdfc +od6sxdzVnDW/PQ2cHJIB3csZ83vcikLqhMjq6JcZy9m4PTwxnDKSgKSB938O +ctlYfWVB84srceCvFfmpF7MQ69K7kUeLxYSJp9Wle0zwD2lHrw2IgWar+7SX +GhP9Qzc+NFJi4NO4flOQEwHt6z8bc8NiYPNKqyN+CwPn/QRv/3CIxcotTsdr +Rg/g+djFzB1VcVi2y2L3g1ZH1JuoP+bUJmAp+cRNpUcOCBsjX9/MF8J831ul +bnsH7HqmQR8eTQXHXmOvcH4/1oVScz01REhIn/pIVnPAv8utzWfLJJDbPWvQ +y3PArbR09cDCbNBO0TTTSh0x5rcQknM3F7yX3d4lHCdMjXjztr87CeH/ZAt9 +HgTU32+13SQ9DSOSfGFyhonmBrvXmbMFeHhbdv1OFxsqittC4F2A6UiNZGnX +QRRzpte8Ds/H9u/bZavyXZHUz2Pmi3Lgkr+6mdLphvHAIDNuhxhXpK5H7pI5 +oBcJJqk7k+Go0HGCXO4G8/T/Tl6NiMExEcl/NssVvNJxVM4IwJU++0g2dIGO +cy7lx/vBSLV8fn3d6cX+jO285NWBKDGxs3uqygbX+6VO930+et6N3ewVMeFr +XuE7ZeyP5UWrN7YZEGCu0vr4StcfggCKq0/DAeiocyeeCvgw0AzJMeU5QBi9 +1dvNKgD3g5cfmHW0R7OFbMvUQBAaI2oVx3+wwzXl8JIWUgh2DGi8aB2mw2BS +4SqzRYAdeqKlYyk2uH/513tU2yjsOP9wXD/eGsX1NicLN8dDfctPb7rv0DDi +dpTexEuBmaN2oYqQBvlXo5QagRg6YkGPThMNjvWsttHdOeiZbW4tLLWGLUmT +tbf1NCqUDXXKxXRwM0jnjmsXI8TqjLTgzT7M/eEc+XVsKUi/hN7RP+2E7crJ +prOFFzGc6CMsvMEG8xrlpvr5CrSU7dQPsuRCGBRyVWB7EYG1ltY3xz3RuTSz +gVR1BsQcqSU01Bvmz02ntCJSYbk/t9Jztzcuz9KoldEeUJE8NbJK9YLbII1r +cMwEPcsqnPPOeWBi213tb801wTeMOEeNOYwyvB7nL18O3Ql3eVApBwlnOyLW +J89RX5WXFYdtcIWkj3ZKo+YFtar97evqW85wlxo30fKeUGNLbyX2Lf5fNTfL +Qn74IfUvqlzhdg== + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{All, All}, + PlotRangeClipping->True, + PlotRangePadding->{Automatic, Automatic}]], "Output", + CellChangeTimes->{ + 3.5146810649101152`*^9},ExpressionUUID->"eaf70f06-5e5f-45b8-94e8-\ +a1f9262f7ebf"] +}, Open ]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Accounting for randomness [EXTRA]", "Subsection", + CellChangeTimes->{{3.5139528882754917`*^9, 3.513952890146652*^9}, { + 3.514428463172866*^9, 3.514428464250293*^9}, {3.514432430011691*^9, + 3.514432431921852*^9}, {3.514680913441392*^9, + 3.51468092410325*^9}},ExpressionUUID->"f495cd23-1926-49f5-ac86-\ +08cda9e6d02e"], + +Cell["\<\ +In all of the above models, we've assumed that the state of the system can be \ +precisely predicted in the next time step. Such models are called \ +\"deterministic\". In natural systems, there is always a degree of \ +randomness or stochasticity to life. For example, even if the average number \ +of offspring per parent were 2.3, the actual number will be an integer \ +(0,1,2,3...). + +The offspring number might, for instance, represent a random draw of the \ +Poisson distribution with a certain mean (here 2.3):\ +\>", "Text", + CellChangeTimes->{{3.5144328332623262`*^9, 3.514432913107875*^9}, { + 3.514681088503398*^9, 3.5146811264845057`*^9}, {3.514681215089706*^9, + 3.5146813367371607`*^9}},ExpressionUUID->"07acc4e2-a81f-42a6-b6fe-\ +9556df280f78"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"RandomInteger", "[", + RowBox[{"PoissonDistribution", "[", "2.3", "]"}], "]"}]], "Input", + CellChangeTimes->{{3.5145680277538223`*^9, 3.514568029616096*^9}, { + 3.5146813385711927`*^9, + 3.514681338705735*^9}},ExpressionUUID->"af5aff32-a541-47f4-afaa-\ +c98e3d3cc6f4"], + +Cell[BoxData["0"], "Output", + CellChangeTimes->{{3.514681888326708*^9, 3.5146819493635902`*^9}, { + 3.620056480801937*^9, + 3.620056485167636*^9}},ExpressionUUID->"f5ecae08-b9cd-4c94-9103-\ +9fa4b08ef4ad"] +}, Open ]], + +Cell["\<\ +We can incorporate such randomness (called \"demographic stochasticity\") \ +into the above ecological models by having the number of offspring be drawn \ +from a Poisson:\ +\>", "Text", + CellChangeTimes->{{3.5146813454789953`*^9, + 3.514681419066923*^9}},ExpressionUUID->"f5ed53f9-438e-40e5-9a90-\ +770ffec1ea9d"], + +Cell[BoxData[{ + RowBox[{"Clear", "[", "hapdip", "]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a_", ",", "b_", ",", "h0_", ",", "d0_", ",", "t_"}], "]"}], ":=", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a", ",", "b", ",", "h0", ",", "d0", ",", "t"}], "]"}], "=", + "\[IndentingNewLine]", + RowBox[{"Block", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"h", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a", ",", "b", ",", "h0", ",", "d0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "1"}], "]"}]}], ",", + RowBox[{"d", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a", ",", "b", ",", "h0", ",", "d0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "2"}], "]"}]}]}], "}"}], + ",", "\[IndentingNewLine]", + RowBox[{ + RowBox[{"numhap", "=", + RowBox[{"If", "[", + RowBox[{ + RowBox[{ + RowBox[{"b", " ", "d"}], ">", "0"}], ",", + RowBox[{"RandomInteger", "[", + RowBox[{"PoissonDistribution", "[", + RowBox[{"b", " ", "d"}], "]"}], "]"}], ",", "0"}], "]"}]}], ";", + "\[IndentingNewLine]", + RowBox[{"numdip", "=", + RowBox[{"If", "[", + RowBox[{ + RowBox[{ + RowBox[{"a", " ", "h"}], " ", ">", "0"}], ",", + RowBox[{"RandomInteger", "[", + RowBox[{"PoissonDistribution", "[", + RowBox[{"a", " ", "h"}], "]"}], "]"}], ",", "0"}], "]"}]}], ";", + "\[IndentingNewLine]", + RowBox[{"{", + RowBox[{"numhap", ",", "numdip"}], "}"}]}]}], "\[IndentingNewLine]", + "\t", "]"}]}]}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"a_", ",", "b_", ",", "h0_", ",", "d0_", ",", "0"}], "]"}], ":=", + RowBox[{"{", + RowBox[{"h0", ",", "d0"}], "}"}]}]}], "Input", + CellChangeTimes->{{3.514424045707509*^9, 3.514424061967498*^9}, { + 3.5144255050950212`*^9, 3.514425607017445*^9}, {3.514425642488206*^9, + 3.514425669408059*^9}, {3.514425734177042*^9, 3.514425737442438*^9}, { + 3.514426238427285*^9, 3.5144262538256493`*^9}, {3.514426381804556*^9, + 3.514426383523755*^9}, 3.5144264576520653`*^9, {3.5144266314259853`*^9, + 3.5144266539839983`*^9}, {3.514427148128552*^9, 3.5144271570026703`*^9}, { + 3.514432474189856*^9, 3.514432582465474*^9}, {3.514568006098897*^9, + 3.514568067364029*^9}, {3.514681440031329*^9, 3.5146814782402697`*^9}, { + 3.514681583195634*^9, 3.5146816027804823`*^9}, {3.514681644663149*^9, + 3.51468164542367*^9}, {3.514681685292144*^9, 3.514681695436019*^9}, { + 3.6200398345517263`*^9, 3.62003986436403*^9}, {3.6200399373824778`*^9, + 3.6200400292644787`*^9}, {3.620040496906893*^9, + 3.62004049724343*^9}},ExpressionUUID->"130a8b2f-f4e7-485f-aa9b-\ +31f483f6c9ed"], + +Cell[TextData[{ + "Some notes: \n\t* Block keeps a set of calculations together, defining \ +local variables in the first {}. The output will be the last entry of the \ +Block.\n\t* := sets the left to the right-hand side only after being called \ +and remembers this value.\n\t* We have to set a starting point or else the \ +system will end up in an infinite loop going backwards in time.\n\t* The \ +Unprotect[...] statements were added so that if the population ever goes \ +extinct, the Poisson distribution can be evaluated even though the mean is \ +zero. We then know that all draws should return zero, but ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " doesn't actually know what to do when the mean is zero by default. By \ +unprotecting, defining, and reprotecting, we can \"force\" ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " to know something additional. " +}], "Text", + CellChangeTimes->{{3.514426408190782*^9, 3.51442655970971*^9}, { + 3.5145648346061983`*^9, 3.514564835211282*^9}, {3.514681662192986*^9, + 3.5146818424627533`*^9}},ExpressionUUID->"41a744b8-2fa5-41a9-85e8-\ +fe64b957afbb"], + +Cell["\<\ +We can then make a table of population sizes for {haploids, diploids}:\ +\>", "Text", + CellChangeTimes->{{3.514426311595162*^9, 3.514426337581416*^9}, { + 3.5144326128151073`*^9, + 3.514432625364406*^9}},ExpressionUUID->"7c06f4c4-1dce-4a35-ba8b-\ +08422a7e9acd"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"0.7", ",", "1.5", ",", "10", ",", "10", ",", "t"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.5144262691718893`*^9, 3.514426294228351*^9}, { + 3.5144263455531607`*^9, 3.5144263905959597`*^9}, {3.514426567695655*^9, + 3.514426611405775*^9}, {3.51442669599331*^9, 3.514426706329217*^9}, { + 3.514432589298902*^9, + 3.514432602070593*^9}},ExpressionUUID->"e0113959-d55e-40e8-816c-\ +00b677b61b77"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"10", ",", "10"}], "}"}], ",", + RowBox[{"{", + RowBox[{"11", ",", "8"}], "}"}], ",", + RowBox[{"{", + RowBox[{"16", ",", "14"}], "}"}], ",", + RowBox[{"{", + RowBox[{"18", ",", "9"}], "}"}], ",", + RowBox[{"{", + RowBox[{"16", ",", "11"}], "}"}], ",", + RowBox[{"{", + RowBox[{"23", ",", "10"}], "}"}], ",", + RowBox[{"{", + RowBox[{"17", ",", "7"}], "}"}], ",", + RowBox[{"{", + RowBox[{"13", ",", "13"}], "}"}], ",", + RowBox[{"{", + RowBox[{"21", ",", "7"}], "}"}], ",", + RowBox[{"{", + RowBox[{"6", ",", "17"}], "}"}], ",", + RowBox[{"{", + RowBox[{"32", ",", "2"}], "}"}], ",", + RowBox[{"{", + RowBox[{"2", ",", "16"}], "}"}], ",", + RowBox[{"{", + RowBox[{"21", ",", "2"}], "}"}], ",", + RowBox[{"{", + RowBox[{"3", ",", "18"}], "}"}], ",", + RowBox[{"{", + RowBox[{"19", ",", "2"}], "}"}], ",", + RowBox[{"{", + RowBox[{"3", ",", "12"}], "}"}], ",", + RowBox[{"{", + RowBox[{"15", ",", "3"}], "}"}], ",", + RowBox[{"{", + RowBox[{"6", ",", "11"}], "}"}], ",", + RowBox[{"{", + RowBox[{"14", ",", "8"}], "}"}], ",", + RowBox[{"{", + RowBox[{"9", ",", "11"}], "}"}], ",", + RowBox[{"{", + RowBox[{"24", ",", "8"}], "}"}], ",", + RowBox[{"{", + RowBox[{"6", ",", "17"}], "}"}], ",", + RowBox[{"{", + RowBox[{"28", ",", "6"}], "}"}], ",", + RowBox[{"{", + RowBox[{"11", ",", "16"}], "}"}], ",", + RowBox[{"{", + RowBox[{"21", ",", "6"}], "}"}], ",", + RowBox[{"{", + RowBox[{"11", ",", "17"}], "}"}], ",", + RowBox[{"{", + RowBox[{"23", ",", "7"}], "}"}], ",", + RowBox[{"{", + RowBox[{"10", ",", "19"}], "}"}], ",", + RowBox[{"{", + RowBox[{"23", ",", "6"}], "}"}], ",", + RowBox[{"{", + RowBox[{"14", ",", "19"}], "}"}], ",", + RowBox[{"{", + RowBox[{"41", ",", "10"}], "}"}], ",", + RowBox[{"{", + RowBox[{"16", ",", "22"}], "}"}], ",", + RowBox[{"{", + RowBox[{"33", ",", "8"}], "}"}], ",", + RowBox[{"{", + RowBox[{"8", ",", "13"}], "}"}], ",", + RowBox[{"{", + RowBox[{"24", ",", "9"}], "}"}], ",", + RowBox[{"{", + RowBox[{"10", ",", "18"}], "}"}], ",", + RowBox[{"{", + RowBox[{"36", ",", "9"}], "}"}], ",", + RowBox[{"{", + RowBox[{"14", ",", "19"}], "}"}], ",", + RowBox[{"{", + RowBox[{"34", ",", "9"}], "}"}], ",", + RowBox[{"{", + RowBox[{"11", ",", "29"}], "}"}], ",", + RowBox[{"{", + RowBox[{"48", ",", "8"}], "}"}], ",", + RowBox[{"{", + RowBox[{"10", ",", "37"}], "}"}], ",", + RowBox[{"{", + RowBox[{"63", ",", "4"}], "}"}], ",", + RowBox[{"{", + RowBox[{"7", ",", "57"}], "}"}], ",", + RowBox[{"{", + RowBox[{"98", ",", "3"}], "}"}], ",", + RowBox[{"{", + RowBox[{"4", ",", "58"}], "}"}], ",", + RowBox[{"{", + RowBox[{"94", ",", "6"}], "}"}], ",", + RowBox[{"{", + RowBox[{"8", ",", "64"}], "}"}], ",", + RowBox[{"{", + RowBox[{"98", ",", "3"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "76"}], "}"}], ",", + RowBox[{"{", + RowBox[{"122", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "73"}], "}"}], ",", + RowBox[{"{", + RowBox[{"110", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "72"}], "}"}], ",", + RowBox[{"{", + RowBox[{"101", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "76"}], "}"}], ",", + RowBox[{"{", + RowBox[{"118", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "72"}], "}"}], ",", + RowBox[{"{", + RowBox[{"121", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "77"}], "}"}], ",", + RowBox[{"{", + RowBox[{"118", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "77"}], "}"}], ",", + RowBox[{"{", + RowBox[{"117", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "79"}], "}"}], ",", + RowBox[{"{", + RowBox[{"119", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "93"}], "}"}], ",", + RowBox[{"{", + RowBox[{"131", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "117"}], "}"}], ",", + RowBox[{"{", + RowBox[{"189", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "149"}], "}"}], ",", + RowBox[{"{", + RowBox[{"199", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "136"}], "}"}], ",", + RowBox[{"{", + RowBox[{"208", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "152"}], "}"}], ",", + RowBox[{"{", + RowBox[{"231", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "162"}], "}"}], ",", + RowBox[{"{", + RowBox[{"254", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "184"}], "}"}], ",", + RowBox[{"{", + RowBox[{"278", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "202"}], "}"}], ",", + RowBox[{"{", + RowBox[{"317", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "229"}], "}"}], ",", + RowBox[{"{", + RowBox[{"336", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "248"}], "}"}], ",", + RowBox[{"{", + RowBox[{"346", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "236"}], "}"}], ",", + RowBox[{"{", + RowBox[{"367", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "223"}], "}"}], ",", + RowBox[{"{", + RowBox[{"314", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "226"}], "}"}], ",", + RowBox[{"{", + RowBox[{"335", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "246"}], "}"}], ",", + RowBox[{"{", + RowBox[{"357", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "269"}], "}"}], ",", + RowBox[{"{", + RowBox[{"403", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "280"}], "}"}], ",", + RowBox[{"{", + RowBox[{"421", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "277"}], "}"}], ",", + RowBox[{"{", + RowBox[{"400", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "267"}], "}"}], ",", + RowBox[{"{", + RowBox[{"419", ",", "0"}], "}"}]}], "}"}]], "Output", + CellChangeTimes->{{3.5146818884896307`*^9, 3.5146819497981987`*^9}, { + 3.620056480950532*^9, + 3.620056485285142*^9}},ExpressionUUID->"3cb66346-4a46-4413-acf6-\ +840ee7cf3197"] +}, Open ]], + +Cell["or plotting haploids in red and diploids in blue:", "Text", + CellChangeTimes->{{3.5144263221305637`*^9, 3.514426329021406*^9}, { + 3.514426565192073*^9, 3.5144265653575697`*^9}, {3.514432634174358*^9, + 3.514432637243886*^9}, {3.5144327125256863`*^9, + 3.514432718011566*^9}},ExpressionUUID->"0d49130b-62d4-4e30-b25a-\ +08e467c2d605"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"0.7", ",", "1.5", ",", "10", ",", "10", ",", "t"}], "]"}], + ",", "1"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}], ",", + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"hapdip", "[", + RowBox[{"0.7", ",", "1.5", ",", "10", ",", "10", ",", "t"}], "]"}], + ",", "2"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]}], "}"}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Red", ",", "Blue"}], "}"}]}]}], "]"}]], "Input", + CellChangeTimes->{{3.514432638805904*^9, 3.514432693910797*^9}, { + 3.514564949004417*^9, 3.514564951467107*^9}, {3.514568088301124*^9, + 3.514568089819323*^9}},ExpressionUUID->"7ab64719-62ec-4b2f-a883-\ +285fca7554a8"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {RGBColor[1, 0, 0], LineBox[CompressedData[" +1:eJx1kklKA1EURQtHDh04cOBARYKISGLf5xu72CUxNkkQJQhBESGIDZjRW0qW +8pfgErKELEEl5w3qggXhcu6t+/6rSk0+tKutoSRJWr+/Px1c/fxApwMGmkGH +0Sw6gi6go5KPoavoOJpDJ9BZdApdDuk9fI7vEdAZ2dPneH9O9p5HF2VPz3Ny +nz+Xn+89n7v0z95r6Ir0/T1syX3+XOsyZ0PyzX/m+HvalnxH9s0P1PZhf4+8 +BwtpTXZR/idz9r0L6fOtIP5e+nxz9jm+R0b2KqIHMh+2Mv4hyndlsNXxj1C+ +U4OtJuf48xWlf4xyGWz3+CeSw3aLfyo5HBr4Z5LDdod/Ljkc/PyS5CXplyWH +g+eVdB7gSG6SR7jZxL+QPtx9pC95hHtP+FXpOz/TlzzCvRf8S+nDsU1f8gg3 +X/GvpA9/v9GXPDp/oNfSh7vkJnmE+5/4N9KHu36+5BHuv+PX0nmAK8w3ySOc +/cKvp/MAVzr0JY/O3m+kc/+us53wA6R6glg= + "]]}, + {RGBColor[0, 0, 1], LineBox[CompressedData[" +1:eJxdkkdOA0EURFusWLJgwYIFWAghhBA5h8YmOmPyggVJCBEMN+ij+AgcwUfg +CByBIwCaV5amRrJKNa/r/99/PHrbbj30hRAe/n7/mj0/25mORV6gI2g/OoUO +oAV0EB1Hh2K+3rCp6k5aHXHlZq2u5ppAZ6yOuOacQ6eNK6c66qN7Kqe+8zb3 +gvFF40tWdxnVXlZsjlXja5ZfR7WfDZtr0/JbxrdR7TXm50zymn8HZa9JvoAW +UfaUisZL+f6pZHw3P3eSV/+9fN2E7/3v9nlfRfG973eA1uDy2s8h2oTLK3+E +nsDl9ZQzH1vwsvEKXrxivGr1q8Zrlq8Zr9Nf+brxhvGGce7dhcdmnid8vOCc +8XAMv0aPLY/v3JI3rnuFG/KtPE/yd+SNa2/xHj2xvPwjeePhlNwTemp5fOeF +vPFwhm+TP8vzhE+v5I2H88x/P5M/tzw+qr/xoO/yxrkLy+O/3jlnPFwy3wf5 +S8vjm/Cu8XCV+U/qx6se/wU3sHm+ + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{{0., 101.}, {0., 421.}}, + PlotRangeClipping->True, + PlotRangePadding->{ + Scaled[0.02], + Scaled[0.02]}]], "Output", + CellChangeTimes->{{3.514681888532123*^9, 3.514681949818688*^9}, { + 3.620056480984907*^9, + 3.62005648532218*^9}},ExpressionUUID->"bd7a2d8a-949b-4334-b532-\ +3f693bba10c6"] +}, Open ]], + +Cell["\<\ +Reenter this sub-directory a few times to see how the plots change due to \ +demographic stochasticity. Occassionally, you'll see the whole population go \ +extinct, despite the fact that we expect it to grow with a = 0.7 and b = 1.5. + +To learn more about probability theory and stochastic models (both analytical \ +and simulation-based methods), read Primer 3 and Chapters 13-15.\ +\>", "Text", + CellChangeTimes->{{3.514432739753072*^9, 3.5144328205024443`*^9}, { + 3.514681860480795*^9, 3.514681877814828*^9}, {3.5146819519607058`*^9, + 3.514682015319873*^9}},ExpressionUUID->"e5da17a1-b409-4435-917a-\ +6e4baadee48e"] +}, Closed]] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Part 6: Another example of building a model from scratch", "Section", + CellChangeTimes->{{3.5144319422285337`*^9, 3.5144319462583027`*^9}, { + 3.5146884564551907`*^9, + 3.514688456723851*^9}},ExpressionUUID->"53213a5b-792a-41e6-b05c-\ +74d43a033327"], + +Cell[TextData[{ + StyleBox["Scenario: ", + FontWeight->"Bold"], + "Consider two types of individuals that can help one another to raise a \ +brood (e.g., one type might be better at collecting food \ +\[OpenCurlyDoubleQuote]c\[CloseCurlyDoubleQuote] and the other type at \ +detecting predators \[OpenCurlyDoubleQuote]d\[CloseCurlyDoubleQuote]). \ +Assume that neither of the two types would be able to grow on their own, with \ +the number of offspring per parent, 1-rc and 1-rd, respectively, being less \ +than one. Through cooperation, however, the per capita growth of each type \ +rises linearly with the number of the other type, with slopes \[Rho]c and \ +\[Rho]d." +}], "Text", + CellChangeTimes->{{3.514512947327882*^9, 3.51451300566192*^9}, { + 3.5145130395300694`*^9, 3.514513149874734*^9}, {3.514513189390361*^9, + 3.514513203812648*^9}, {3.514513251193619*^9, 3.514513366083787*^9}, { + 3.514516385741205*^9, 3.514516386187703*^9}, {3.514565331869029*^9, + 3.514565449264834*^9}, {3.514688780875373*^9, 3.5146887811607933`*^9}, { + 3.5636679304486732`*^9, 3.563667937136087*^9}, {3.6204248342130957`*^9, + 3.620424840300754*^9}, {3.62042497466206*^9, + 3.6204250391240263`*^9}},ExpressionUUID->"881e1045-62f3-4f95-921c-\ +137acec255aa"], + +Cell["\<\ +\t nc[t + 1] = (1 - rc + \[Rho]c nd[t]) nc[t]\t\t\t\tDiscrete - time model +\t nd[t + 1] = (1 - rd + \[Rho]d nc[t]) nd[t]\t\t\t\t\ +\>", "Text", + CellChangeTimes->{{3.514512947327882*^9, 3.51451300566192*^9}, { + 3.5145130395300694`*^9, 3.514513149874734*^9}, {3.514513189390361*^9, + 3.514513203812648*^9}, {3.514513251193619*^9, 3.514513366083787*^9}, { + 3.563667972192665*^9, 3.563667976191773*^9}, {3.620424813477509*^9, + 3.620424840363353*^9}, {3.6204249747315903`*^9, + 3.620424988534522*^9}},ExpressionUUID->"9242ac77-9484-45de-8973-\ +e502b05d2b3a"], + +Cell["\<\ +Solving for the equilibrium points that cause nc[t]=nc[t+1] and nd[t]=nd[t+1] \ +simultaneously: +[CAUTION: When doing this by hand, make sure that you have a solution that \ +solves both of these requirements.]\ +\>", "Text", + CellChangeTimes->{{3.5146884902047443`*^9, 3.514688524908227*^9}, { + 3.620424813626739*^9, 3.620424821092431*^9}, {3.620425088810996*^9, + 3.6204251092340307`*^9}},ExpressionUUID->"a415af70-2efe-4cd2-9c17-\ +30c65db0cdbe"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"nc", "==", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "rc", "+", + RowBox[{"\[Rho]c", " ", "nd"}]}], ")"}], " ", "nc"}]}], ",", "\n", + RowBox[{"nd", "==", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "rd", "+", + RowBox[{"\[Rho]d", " ", "nc"}]}], ")"}], " ", "nd"}]}]}], "}"}], ",", + RowBox[{"{", + RowBox[{"nc", ",", "nd"}], "}"}]}], "]"}]], "Input", + CellChangeTimes->{{3.514513367659889*^9, 3.514513401913871*^9}, { + 3.5145146486955338`*^9, 3.5145146493089743`*^9}, {3.620424813718761*^9, + 3.62042484040551*^9}, {3.6204249747738037`*^9, + 3.620424988608227*^9}},ExpressionUUID->"dc24c4c8-8280-499b-b0a1-\ +ce20dd786f2f"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"nc", "\[Rule]", + FractionBox["rd", "\[Rho]d"]}], ",", + RowBox[{"nd", "\[Rule]", + FractionBox["rc", "\[Rho]c"]}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"nc", "\[Rule]", "0"}], ",", + RowBox[{"nd", "\[Rule]", "0"}]}], "}"}]}], "}"}]], "Output", + CellChangeTimes->{3.5145134025899982`*^9, 3.514688542159596*^9, + 3.6204250628028812`*^9},ExpressionUUID->"3e674a4c-7e23-4281-9a17-\ +143d56cf917b"] +}, Open ]], + +Cell["Developing the stability matrix:", "Text", + CellChangeTimes->{{3.51468854661584*^9, 3.514688551172599*^9}, { + 3.62042506605606*^9, + 3.620425067380691*^9}},ExpressionUUID->"390da005-5f56-4165-8aae-\ +ed0a40e614f8"], + +Cell[BoxData[{ + RowBox[{ + RowBox[{"eqnc", "=", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "rc", "+", + RowBox[{"\[Rho]c", " ", + RowBox[{"nd", "[", "t", "]"}]}]}], ")"}], " ", + RowBox[{"nc", "[", "t", "]"}]}]}], ";"}], "\n", + RowBox[{ + RowBox[{"eqnd", "=", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "rd", "+", + RowBox[{"\[Rho]d", " ", + RowBox[{"nc", "[", "t", "]"}]}]}], ")"}], " ", + RowBox[{"nd", "[", "t", "]"}]}]}], ";"}]}], "Input", + CellChangeTimes->{{3.51451343084625*^9, 3.514513442023988*^9}, { + 3.514513490481597*^9, 3.514513496303595*^9}, 3.5145135958378153`*^9, { + 3.51468931952798*^9, 3.5146893556455317`*^9}, {3.620424813883567*^9, + 3.620424840470953*^9}, {3.620424974381165*^9, + 3.620424987021496*^9}},ExpressionUUID->"c72a4d3a-7497-4753-9a46-\ +bef194f869ef"], + +Cell["\<\ +Using this stability matrix, we replace the numbers of each species, nc[t] \ +and nd[t], with their equilibrium values, first starting with the nc = nd = 0 \ +equilibrium:\ +\>", "Text", + CellChangeTimes->{{3.620424770180231*^9, 3.620424821443891*^9}, { + 3.620425077492154*^9, + 3.6204250866029873`*^9}},ExpressionUUID->"84d63635-3dc1-47e0-98b7-\ +67597a441955"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"matrixEXTINCT", "=", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"D", "[", + RowBox[{"eqnc", ",", + RowBox[{"nc", "[", "t", "]"}]}], "]"}], ",", + RowBox[{"D", "[", + RowBox[{"eqnc", ",", + RowBox[{"nd", "[", "t", "]"}]}], "]"}]}], "}"}], ",", + "\[IndentingNewLine]", + RowBox[{"{", + RowBox[{ + RowBox[{"D", "[", + RowBox[{"eqnd", ",", + RowBox[{"nc", "[", "t", "]"}]}], "]"}], ",", + RowBox[{"D", "[", + RowBox[{"eqnd", ",", + RowBox[{"nd", "[", "t", "]"}]}], "]"}]}], "}"}]}], "}"}], "/.", + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"nc", "[", "t", "]"}], "\[Rule]", "0"}], ",", + RowBox[{ + RowBox[{"nd", "[", "t", "]"}], "\[Rule]", "0"}]}], "}"}]}]}]], "Input", + CellChangeTimes->{{3.51442993198416*^9, 3.5144299850653954`*^9}, { + 3.5144300475033083`*^9, 3.514430056546912*^9}, {3.514431255563335*^9, + 3.5144312648468647`*^9}, {3.5144313318662977`*^9, 3.514431341037857*^9}, { + 3.514513465153736*^9, 3.514513465279723*^9}, {3.514513500029063*^9, + 3.51451351148452*^9}, {3.51468855632721*^9, 3.514688561391642*^9}, + 3.5146893289426537`*^9, {3.514693173379643*^9, 3.51469318546539*^9}, { + 3.620424814067342*^9, + 3.620424821631523*^9}},ExpressionUUID->"ca6abbe4-a86f-49af-b040-\ +ebe6af90a77d"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"1", "-", "rc"}], ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", + RowBox[{"1", "-", "rd"}]}], "}"}]}], "}"}]], "Output", + CellChangeTimes->{ + 3.514429985443801*^9, 3.51443004824973*^9, 3.514431265594489*^9, + 3.5144313028415747`*^9, 3.514431341570993*^9, 3.514513511918516*^9, + 3.514513597575721*^9, {3.5146885574357233`*^9, 3.514688561825218*^9}, { + 3.514693176326908*^9, 3.514693186074129*^9}, 3.620425075532835*^9, + 3.6204251130832167`*^9},ExpressionUUID->"191bd491-03d8-49f1-bef5-\ +adfcb4146094"] +}, Open ]], + +Cell["For the {0,0} equilibrium, the eigenvalues are:", "Text", + CellChangeTimes->{{3.51442999874765*^9, 3.514430033710093*^9}, { + 3.514431354718349*^9, 3.514431358603902*^9}, {3.514688568646791*^9, + 3.514688579292718*^9}},ExpressionUUID->"44aa97c0-0020-4f0c-aca5-\ +64082cce01e8"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Eigenvalues", "[", "%", "]"}]], "Input", + CellChangeTimes->{{3.514430075822959*^9, + 3.514430078517954*^9}},ExpressionUUID->"a4a00e90-04d1-41a7-950e-\ +a099dbac9574"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"1", "-", "rc"}], ",", + RowBox[{"1", "-", "rd"}]}], "}"}]], "Output", + CellChangeTimes->{3.514430079485057*^9, 3.514431346378005*^9, + 3.514513514991106*^9, 3.514513599428266*^9, + 3.62042511484976*^9},ExpressionUUID->"56de0aa6-d2a5-4d8c-92c3-08392fff5b39"] +}, Open ]], + +Cell["\<\ +As we've assumed that both 1-rc and 1-rd are less than one, but they \ +represent number of offspring per parent and cannot be negative, both \ +eigenvalues lie between 0 and 1: this equilibrium is stable.\ +\>", "Text", + CellChangeTimes->{{3.5146885837452374`*^9, 3.5146886656857*^9}, { + 3.620424834377783*^9, + 3.620424840562746*^9}},ExpressionUUID->"07290a94-5cc5-4b13-9777-\ +2b8ec8a032d5"], + +Cell[TextData[{ + "For the {", + Cell[BoxData[ + RowBox[{ + FractionBox["rc", "\[Rho]c"], ",", + FractionBox["rd", "\[Rho]d"]}]], + CellChangeTimes->{{3.51442993198416*^9, 3.5144299850653954`*^9}, { + 3.5144300475033083`*^9, 3.514430056546912*^9}, {3.514431255563335*^9, + 3.5144312648468647`*^9}, {3.5144313318662977`*^9, 3.514431341037857*^9}, { + 3.514513465153736*^9, 3.514513465279723*^9}, {3.514513500029063*^9, + 3.514513540895101*^9}},ExpressionUUID-> + "a5664de4-6d01-4741-8787-94a9a2618e25"], + "} equilibrium, the stability matrix becomes:" +}], "Text", + CellChangeTimes->{{3.51442999874765*^9, 3.514430033710093*^9}, { + 3.514431354718349*^9, 3.514431358603902*^9}, {3.514688568646791*^9, + 3.514688579292718*^9}, {3.5146886834037437`*^9, 3.514688700712574*^9}, { + 3.620424834398841*^9, 3.620424840605443*^9}, {3.62042497442067*^9, + 3.620424987074807*^9}, {3.6204251265157623`*^9, + 3.620425130697886*^9}},ExpressionUUID->"f395aaa3-2cdb-4d89-aace-\ +c08aecef9b5f"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"matrixPOLY", "=", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"D", "[", + RowBox[{"eqnc", ",", + RowBox[{"nc", "[", "t", "]"}]}], "]"}], ",", + RowBox[{"D", "[", + RowBox[{"eqnc", ",", + RowBox[{"nd", "[", "t", "]"}]}], "]"}]}], "}"}], ",", + "\[IndentingNewLine]", + RowBox[{"{", + RowBox[{ + RowBox[{"D", "[", + RowBox[{"eqnd", ",", + RowBox[{"nc", "[", "t", "]"}]}], "]"}], ",", + RowBox[{"D", "[", + RowBox[{"eqnd", ",", + RowBox[{"nd", "[", "t", "]"}]}], "]"}]}], "}"}]}], "}"}], "/.", + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"nc", "[", "t", "]"}], "\[Rule]", + FractionBox["rd", "\[Rho]d"]}], ",", + RowBox[{ + RowBox[{"nd", "[", "t", "]"}], "\[Rule]", + FractionBox["rc", "\[Rho]c"]}]}], "}"}]}]}]], "Input", + CellChangeTimes->{{3.51442993198416*^9, 3.5144299850653954`*^9}, { + 3.5144300475033083`*^9, 3.514430056546912*^9}, {3.514431255563335*^9, + 3.5144312648468647`*^9}, {3.5144313318662977`*^9, 3.514431341037857*^9}, { + 3.514513465153736*^9, 3.514513465279723*^9}, {3.514513500029063*^9, + 3.514513540895101*^9}, {3.51469247562967*^9, 3.514692478220492*^9}, { + 3.514693162900178*^9, 3.514693191329958*^9}, {3.6204248142507687`*^9, + 3.6204248406347218`*^9}, {3.6204249744346323`*^9, + 3.620424987110145*^9}},ExpressionUUID->"0b745602-e472-4031-bbd0-\ +a35fd19d3672"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"1", ",", + FractionBox[ + RowBox[{"rd", " ", "\[Rho]c"}], "\[Rho]d"]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + FractionBox[ + RowBox[{"rc", " ", "\[Rho]d"}], "\[Rho]c"], ",", "1"}], "}"}]}], + "}"}]], "Output", + CellChangeTimes->{ + 3.514429985443801*^9, 3.51443004824973*^9, 3.514431265594489*^9, + 3.5144313028415747`*^9, 3.514431341570993*^9, {3.514513511918516*^9, + 3.5145135413660297`*^9}, 3.5145136013312817`*^9, 3.514688689224587*^9, + 3.514692478700316*^9, {3.5146931516324177`*^9, 3.514693191850823*^9}, + 3.620425123584207*^9},ExpressionUUID->"421bd145-5748-4cec-94ca-\ +be9862509029"] +}, Open ]], + +Cell["The eigenvalues of which are:", "Text", + CellChangeTimes->{{3.51442999874765*^9, 3.514430033710093*^9}, { + 3.514431354718349*^9, + 3.514431358603902*^9}},ExpressionUUID->"18aa4e6b-a3f4-4818-bc57-\ +f79b931ab81b"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Eigenvalues", "[", "%", "]"}]], "Input", + CellChangeTimes->{{3.514430075822959*^9, + 3.514430078517954*^9}},ExpressionUUID->"c7fe8a58-9e45-4024-b000-\ +939b389ce282"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"1", "-", + RowBox[{ + SqrtBox["rc"], " ", + SqrtBox["rd"]}]}], ",", + RowBox[{"1", "+", + RowBox[{ + SqrtBox["rc"], " ", + SqrtBox["rd"]}]}]}], "}"}]], "Output", + CellChangeTimes->{ + 3.514430079485057*^9, 3.514431346378005*^9, {3.514513514991106*^9, + 3.514513544721499*^9}, 3.514513602831394*^9, 3.514688704300499*^9, + 3.5146931948396797`*^9, + 3.620425133740796*^9},ExpressionUUID->"833ffb50-eb7e-41e3-91d3-\ +a0322b8ca0ab"] +}, Open ]], + +Cell[TextData[{ + "As we've assumed that both rc and ", + "rd", + " are positive, one of these eigenvalues is always greater than one, \ +stretching the system away from {", + Cell[BoxData[ + RowBox[{ + FractionBox["rc", "\[Rho]c"], ",", + FractionBox["rd", "\[Rho]d"]}]], + CellChangeTimes->{{3.51442993198416*^9, 3.5144299850653954`*^9}, { + 3.5144300475033083`*^9, 3.514430056546912*^9}, {3.514431255563335*^9, + 3.5144312648468647`*^9}, {3.5144313318662977`*^9, 3.514431341037857*^9}, { + 3.514513465153736*^9, 3.514513465279723*^9}, {3.514513500029063*^9, + 3.514513540895101*^9}},ExpressionUUID-> + "2a88bd33-7650-4c11-97c1-3adaba0c5f16"], + "}." +}], "Text", + CellChangeTimes->{{3.514688710323403*^9, 3.514688762094459*^9}, { + 3.620424834457787*^9, 3.620424840787919*^9}, {3.620424974485269*^9, + 3.620424987191147*^9}},ExpressionUUID->"e788a95b-c09c-4aa1-9e7a-\ +5dcc6b917984"], + +Cell["Simulations:", "Text", + CellChangeTimes->{{3.514688771529039*^9, + 3.5146887749746933`*^9}},ExpressionUUID->"39b09d0a-8d3d-40d1-8287-\ +08b73e4a8fff"], + +Cell[BoxData[{ + RowBox[{"Clear", "[", "coop", "]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{ + RowBox[{"coop", "[", + RowBox[{ + "rc_", ",", "rd_", ",", "\[Rho]c_", ",", "\[Rho]d_", ",", "nc0_", ",", + "nd0_", ",", "t_"}], "]"}], ":=", + RowBox[{ + RowBox[{"coop", "[", + RowBox[{ + "rc", ",", "rd", ",", "\[Rho]c", ",", "\[Rho]d", ",", "nc0", ",", "nd0", + ",", "t"}], "]"}], "=", "\[IndentingNewLine]", + RowBox[{"Block", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"nc", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"coop", "[", + RowBox[{ + "rc", ",", "rd", ",", "\[Rho]c", ",", "\[Rho]d", ",", "nc0", ",", + "nd0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "1"}], "]"}]}], ",", + RowBox[{"nd", "=", + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"coop", "[", + RowBox[{ + "rc", ",", "rd", ",", "\[Rho]c", ",", "\[Rho]d", ",", "nc0", ",", + "nd0", ",", + RowBox[{"t", "-", "1"}]}], "]"}], ",", "2"}], "]"}]}]}], "}"}], + ",", "\[IndentingNewLine]", "\t", + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "rc", "+", + RowBox[{"\[Rho]c", " ", "nd"}]}], ")"}], " ", "nc"}], ",", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "rd", "+", + RowBox[{"\[Rho]d", " ", "nc"}]}], ")"}], " ", "nd"}]}], "}"}]}], + "\[IndentingNewLine]", "\t", "]"}]}]}], + "\[IndentingNewLine]"}], "\[IndentingNewLine]", + RowBox[{ + RowBox[{"coop", "[", + RowBox[{ + "rc_", ",", "rd_", ",", "\[Rho]c_", ",", "\[Rho]d_", ",", "nc0_", ",", + "nd0_", ",", "0"}], "]"}], ":=", + RowBox[{"{", + RowBox[{"nc0", ",", "nd0"}], "}"}]}]}], "Input", + CellChangeTimes->{{3.514424045707509*^9, 3.514424061967498*^9}, { + 3.5144255050950212`*^9, 3.514425607017445*^9}, {3.514425642488206*^9, + 3.514425669408059*^9}, {3.514425734177042*^9, 3.514425737442438*^9}, { + 3.514426238427285*^9, 3.5144262538256493`*^9}, {3.514426381804556*^9, + 3.514426383523755*^9}, 3.5144264576520653`*^9, {3.5144266314259853`*^9, + 3.5144266539839983`*^9}, {3.514427148128552*^9, 3.5144271570026703`*^9}, { + 3.514432474189856*^9, 3.514432582465474*^9}, {3.514513649366103*^9, + 3.514513744090983*^9}, {3.514513788624111*^9, 3.514513825085752*^9}, { + 3.514688812614731*^9, 3.514688814765031*^9}, {3.62042481443298*^9, + 3.620424841020681*^9}, {3.620424974502833*^9, + 3.620424987421406*^9}},ExpressionUUID->"0666236d-e7fd-4351-90e8-\ +5a6bf0b3a404"], + +Cell["\<\ +For example, consider starting near the equilibrium for the following \ +parameter set:\ +\>", "Text", + CellChangeTimes->{{3.514688878039145*^9, 3.514688883415462*^9}, { + 3.514688917104313*^9, + 3.5146889325283613`*^9}},ExpressionUUID->"d4735e35-4d8f-4a7e-af8b-\ +d6dd6d478987"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"nc", "[", "t", "]"}], "\[Rule]", + FractionBox["rd", "\[Rho]d"]}], ",", + RowBox[{ + RowBox[{"nd", "[", "t", "]"}], "\[Rule]", + FractionBox["rc", "\[Rho]c"]}]}], "}"}], "/.", + RowBox[{"rc", "->", "0.6"}]}], "/.", + RowBox[{"rd", "->", "0.3"}]}], "/.", + RowBox[{"\[Rho]c", "\[Rule]", "0.02"}]}], "/.", + RowBox[{"\[Rho]d", "\[Rule]", "0.03"}]}]], "Input", + CellChangeTimes->{{3.5146888884619503`*^9, 3.51468891472209*^9}, + 3.514692307355805*^9, {3.5146924864589443`*^9, 3.5146924928454447`*^9}, { + 3.620424814750471*^9, 3.620424841103732*^9}, {3.620424974584652*^9, + 3.6204249875088167`*^9}, {3.6204251678768044`*^9, + 3.620425197756302*^9}},ExpressionUUID->"88d67e5d-b0f3-4653-a493-\ +6811758cf31d"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"nc", "[", "t", "]"}], "\[Rule]", "10.`"}], ",", + RowBox[{ + RowBox[{"nd", "[", "t", "]"}], "\[Rule]", "30.`"}]}], "}"}]], "Output", + CellChangeTimes->{ + 3.514688915139407*^9, 3.514692307681885*^9, 3.5146923975991297`*^9, + 3.514692458183641*^9, 3.514692493227395*^9, 3.620425144357931*^9, { + 3.620425183442471*^9, + 3.6204251981946697`*^9}},ExpressionUUID->"10f0d594-1671-4246-8c60-\ +e8e1a83d4a0b"] +}, Open ]], + +Cell["\<\ +Starting slightly below the equilibrium (collecting species in red and \ +detecting species in blue):\ +\>", "Text", + CellChangeTimes->{{3.5144263221305637`*^9, 3.514426329021406*^9}, { + 3.514426565192073*^9, 3.5144265653575697`*^9}, {3.514432634174358*^9, + 3.514432637243886*^9}, {3.5144327125256863`*^9, 3.514432718011566*^9}, { + 3.514688822889842*^9, 3.5146888251432343`*^9}, {3.514688937048484*^9, + 3.51468895431277*^9}, {3.620425293161131*^9, + 3.6204253003886623`*^9}},ExpressionUUID->"a4d3e6be-7f17-4eb6-abc7-\ +c9a199713c0c"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"coop", "[", + RowBox[{ + "0.6", ",", "0.3", ",", "0.02", ",", "0.03", ",", "5", ",", "15", + ",", "t"}], "]"}], ",", "1"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}], ",", + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"coop", "[", + RowBox[{ + "0.6", ",", "0.3", ",", "0.02", ",", "0.03", ",", "5", ",", "15", + ",", "t"}], "]"}], ",", "2"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "100"}], "}"}]}], "]"}]}], "}"}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Red", ",", "Blue"}], "}"}]}], ",", + RowBox[{"PlotRange", "\[Rule]", "All"}]}], "]"}]], "Input", + CellChangeTimes->{{3.514432638805904*^9, 3.514432693910797*^9}, { + 3.514513746079535*^9, 3.5145137803745813`*^9}, {3.5145138494995947`*^9, + 3.5145139018855143`*^9}, {3.514513938677546*^9, 3.514513982882133*^9}, { + 3.5146888464207172`*^9, 3.514688863786605*^9}, {3.514692311116877*^9, + 3.514692345287362*^9}, {3.514692390058289*^9, 3.514692392319495*^9}, { + 3.514692497525675*^9, 3.5146925149304934`*^9}, {3.620425211483399*^9, + 3.620425264529928*^9}},ExpressionUUID->"f478a417-bc6f-4923-951f-\ +887da363b68e"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {RGBColor[1, 0, 0], LineBox[CompressedData[" +1:eJw9ywlMUwccx/GiOKAw7SLKcDqxToVugsiNHD+glGIPSlsoVRSt4qSuQRQU +dBwDzZgIFFDX4HQHaFAR0BjAgzAcRTCbbkMumaDxgIlKh9qC2ciO989e8vLP +533fb4kmVZ48g8ViJf/z/nuZxxTKXEfQB7oOdG3RV7UzmK2aQebgUtnY6SNe +5v93V7o53s3to+R3UfnERdr+1QB5IS58LsnSdHeSXZAUbeKp7jaSuRg1u2f9 +GVBN/gCVOZrTz7eUkZfjC+WtRKkwm+yK4a9H+12jt5N5GDxzfEXJcwX5IwQb +t4WdDwTZHekGEddXxCOvgmhn2MNd/vPInpA+GwrvdLQir0aaW9nw+V1jIYy9 +0HeiwyHhrV6yN24OXdIG1LSRfWCfafXlXFEt2Rf6Pek9mTXHyH7ghRbwW5fm +k/1xxD692minIwcgalmuNzdYRQ7EGYdh6xxDOHkNOvtqjy66vpIchL5TtVlB +t53IwejJy5113GEmOQQ72jzm2e1/Ecw4FM7si6UNmn4y8MjcGyPO/4FxHpAk +3pbB9qunHob2qg/PPps0UA/DSFOQ09Y3BdTD8cvLUuE8Syr1cHQc5dbllqup +R2DRX8/1fhl86hFQ71he3blhFXU+qgLcFGc9FlDnw1Z7QGiasKYeCfMr1bV1 +101BTI+EachqdfnPdxmzBMjeMnW5ZreRugArWpqdlW4XqEfhgmmkSZFxnHoU +phOnk/ZYDlIXosJD6mssT6MuRPZm+7227ydSj0b9a3aILkdAPRqVn8b2tEx7 +Ul+LkX2Vm7puLqS+Fk6y7S7f2tpQF+FG4jtNEt3EGqaLsC5XUFq//x5jlhjZ +89NmLz92g7oYxnHDwIGhi9QleHyjVX9n1UnqEjzacCSds6KQuhSHDj/R75bv +pi6Fk+uLz+RPN1KPwYY6a5+Mq0LqMbDpseh5XV7UZZjPlb/Hr1nMGDK4Hi6u +T1HY0f8yDKY+nrgS/irwP38vw4J9E+s1PvcZs2Jh0ao7Zo53MUYsCjaL/X1b +LzHOi8UnJx1WThq+oX0sMu80PFCXHKK9HLx2V2ldSAbt5ZjSL+n/Y3oT7eUQ +TqW8zPcU0V6OhorCUp82H9orcM6gc9j48RLaKyBQRu871m9PewWODgd2DgnM +AcxegQqtplv06wPGLCX6krUHawt+ZAwl1m8t9Gu53cg4T4k5Jd3lN0O/o70S +S8ebm+6tLqZ9HIqS3pQ/Wr+X9nE43Og+52m9hvZxYL/OFkU8kdA+Dm4VnnYp +Y360j0dvRJvuCncp7eNRaTNjvuXEbNrHQ6K7xU/KmfRn9vFwLrL3ExseMmap +MHwusmjuutuMoYKHSZv6m+Nlxnkq/K7mqhs41bRXYZZw9L76bT3tE3Bt4LS3 +uS6L9gk45biYN1m0lfYJKOaIr06lymifgLE8gfG6OJD2apT8dFLrw15GezUG +2bmFljsc/78BSGq9zA== + "]]}, + {RGBColor[0, 0, 1], LineBox[CompressedData[" +1:eJw9jw84FGYcx7ke+ZcRFUvnv+oQQpZwvs7/OOHOOcTQTPPkWu3Yn2LSVplh +fx42eUJb8siIHg5P4kLIhOvZnFjsNhNCk6ehmWfbc7/tfZ73+T2f9/N+nud9 +zZNORiQzVFRUkv/Z/07l+t1LOe1BB8qZzSLWgPzbtz21LloR66Favo/xa6Ep +8TaUNm3p8D1uSGwEvZaYXbcX9Ih3YU51KCPQWIPYDPW6ovDBTarEFnCo9Xsr +fXaF3mEFmwfN5f7d/71rN0YN1yILM58Q78WPnanGfad/JraBZN1pSq4uJ7bD +y577TqGmw///SzyzpTb6ix5iR0ypMPM7SzqI90N1z2+bxkwkxE5IsJobU1mt +I3aG2dzoxuXaSmIXuKR8qfVOdBnxAdTsjhVfYRcRu2J7yGKjbns+8WsIyDk3 +LJd9RHwQTLcoaa91JrEbzL8SqXuliIkPQfzQ61TeZyeI3VEmLGH0bRwj9oB2 +7oxr8EYssSc291Q9SvmaR8yG6XZ+/4oomNgL78lFYwYuPsQAWza4P+eXQ0rO +BgRGvrl3ZU7kvdHgbCcdF9qQ98bTFyYVb56yIM+BV0G8wR+yV8lzsPRXgc6a +vj55Hywf+1O/i6tJ3gdBazeXRRJV8r6YYHUtugysspXeFwuuFlXtsUtKVvFD +zrQDk82dIe+HvYvqdRMMBXl/HNypHSMblpP3R/499Y57NcPkA/C6QqtSIegl +H4DCVL40VSAlH4g++wwkTUrIB6LDrLWnm1FPPgiVL4du+qdeJx+E6XgBqzix +nPxhpHFyJTkrReQP43uW1GlOWkA+GOOSVoHWxY/JB2NgYHhSbJlFPgSdLyaG +ZEbp5EPAyStrs85NI89FgP03Vx589wZ5LhyrzlbPLx0lH4qrr1zLeM7hkw/F +B9tCHrXGhZA/Aovx0OAD4z7kjyBp4IehzAF38mHYWljnm5furGSEwbBoTwKL +bUv3wxA3E9o1u9VSydIwGOtr1NTe2kl9OCa9TOP96/WpD4facjxznaVFfTjO +6x1VFIcxqA8H07BRtPnamqeyj4C9XhZX9nxJyYiATmZ9ebvZrJKzI/Dsjv3I +02KFkqURaBqpWt1RMUo9D1lBHMVPHjLqedhxmaXBsOijnofqFola6ZSUeh7m +j5dcPX29mXo+Rh1atJgF9dTzkVg9OB67r4p6PuJ8bkxHu1VQz4ex7W3dBkkx +9ZH49OSJs58PFFIfiTONRvJkzgXqIzHp0NZzl/Uh9ZFo4jO1RcPp1AvgqMeq +dv5ERL0A5kLXrjsJydQLkHjm1rsjC3HUC9Dddp8XtMynPgp+Go3jJXwu9VHo +V9sIUbvkS30UzokcH6a1e1AfhRjupfenTVyoF8LQzfoGx9aOeiG6xNmPFc2W +1AvxWPMJQ7PUmHohGnnuTfMRBtRHY937Qn+Djjb10ejvtRGvP2N4/g1jIb2h + + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{All, All}, + PlotRangeClipping->True, + PlotRangePadding->{Automatic, Automatic}]], "Output", + CellChangeTimes->{ + 3.514432694745741*^9, {3.514513786083666*^9, 3.5145139023460703`*^9}, { + 3.514513941993559*^9, 3.5145139832730093`*^9}, {3.5146888285392723`*^9, + 3.514688864391961*^9}, 3.514692312657728*^9, 3.514692345785509*^9, + 3.514692392794902*^9, 3.514692459758971*^9, {3.5146925081723127`*^9, + 3.514692515382484*^9}, 3.620425200614881*^9, {3.620425258209724*^9, + 3.620425264993034*^9}},ExpressionUUID->"f4e55749-f176-46c3-a1d5-\ +7ea519728010"] +}, Open ]], + +Cell["\<\ +Starting one species slight above the equilibrium and the other below \ +(collecting species in red and detecting species in blue): +[THIS IS SENSITIVE TO THE EXACT CHOICES MADE, HERE THERE AREN\ +\[CloseCurlyQuote]T QUITE ENOUGH OF BOTH TO GET THE SYSTEM OFF THE GROUND]\ +\>", "Text", + CellChangeTimes->{{3.5144263221305637`*^9, 3.514426329021406*^9}, { + 3.514426565192073*^9, 3.5144265653575697`*^9}, {3.514432634174358*^9, + 3.514432637243886*^9}, {3.5144327125256863`*^9, 3.514432718011566*^9}, { + 3.514688822889842*^9, 3.5146888251432343`*^9}, {3.514688937048484*^9, + 3.514688960776795*^9}, {3.6204252932103567`*^9, 3.620425300445283*^9}, { + 3.620425363662524*^9, + 3.6204254190753098`*^9}},ExpressionUUID->"b0ef7e07-d8af-4b9e-a0b1-\ +6b04f5ec6187"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"coop", "[", + RowBox[{ + "0.6", ",", "0.3", ",", "0.02", ",", "0.03", ",", "15", ",", "15", + ",", "t"}], "]"}], ",", "1"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "50"}], "}"}]}], "]"}], ",", + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"coop", "[", + RowBox[{ + "0.6", ",", "0.3", ",", "0.02", ",", "0.03", ",", "15", ",", "15", + ",", "t"}], "]"}], ",", "2"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "50"}], "}"}]}], "]"}]}], "}"}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Red", ",", "Blue"}], "}"}]}], ",", + RowBox[{"PlotRange", "\[Rule]", "All"}]}], "]"}]], "Input", + CellChangeTimes->{{3.514432638805904*^9, 3.514432693910797*^9}, { + 3.514513746079535*^9, 3.5145137803745813`*^9}, {3.5145138494995947`*^9, + 3.5145139018855143`*^9}, {3.514513938677546*^9, 3.514513982882133*^9}, { + 3.5146888464207172`*^9, 3.514688848426044*^9}, {3.514692297794484*^9, + 3.514692325066819*^9}, {3.514692368754171*^9, 3.5146923708400583`*^9}, { + 3.5146924288677588`*^9, 3.514692434482533*^9}, {3.514692520157613*^9, + 3.5146925602909517`*^9}, {3.6204253137085857`*^9, 3.620425343305471*^9}, { + 3.6204253906230917`*^9, + 3.620425401165922*^9}},ExpressionUUID->"b2475597-da31-46ea-9461-\ +541534144837"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {RGBColor[1, 0, 0], LineBox[CompressedData[" +1:eJw9z2tIk2EYxvFlmlZb2VIqXJhzSctY6jZttrlrunkoJBtDA5uItQzBFsuC +VeTCwg4LWym1CDNnmZZoDKzcklwfOrm0LIJqQiuVxappQRAuKt6bHni5+L3/ +Dw9PUpVRa4hgsVjiv9+/ZU5IyawI9IN2NW0M2G8cexWbEsmxiOdoQ3HmZeQ4 +ePQuUzV3CXk5HrctPnXeFE3mIamtubviU5juWYWyRclP6q3TZD6U1rfFXtZH +sgD7RvekVQvGyCko1Zz0NQs95DWIGOvmZJv6yGtxe+jhvRjPZfI6TAS+d9mP +nvj/rlcfHswRW+rIafDd0iZ+DlaS01HewCoP924mZ0DC7hzW1WeSxVDzDvo4 +GXyyBJd6fFWppRyyFFz2t9D+iz9zGGdi0qmqtc34yVkQ3XhmqTA8J2+Ac+Z1 +Scv2u2QZZMk8SX+Dg5yNWXfnOz2ayBvRqO+Qbos0k+WoXGoPDkbtJCuQKvLq +xqNKyDlwXxEk1HTIyEronOXVumMCMuBVr2jaUhPL2AKsLOP3ZKh/KZiugnWh +otExd4KxRYVux6BsfGSUei6mvwzv0E8OUM9FeuDMQNrxa9TzsP7H7+LdWTbq +eRBKa6YCpw9RVyPo8T46O38XdTVqbe0tmqtbqWvgWvC0TyWVU9fAfeH6gUhb +CvV85BjuBFo5XOr5aHe9H7H7Z+VML0DQ3FrWmzDF2FKAOsOg33r4JfVCDPUb +i+Ob71MvhLHSPu9mVyf1Igijne38r+eoFyE3HFK9KDoi/wN0n9a+ + "]]}, + {RGBColor[0, 0, 1], LineBox[CompressedData[" +1:eJw9z11I01EYx3EJk+jfdOaopEVzyHpBc+bMLDd/25xuebVBZJSYSra8aBbN +apHolMi2IkoyfMkoxVjTXtQMpoazJZWW5aCbZQhpczJduNkoGhV76sDh4XO+ +N+dJKNFpjq6IiIhI+3P/zvDxZYfnDtBDeCKVvAqrP96rEBv/mY0j3QqmolBI +5mATe/HaPmsSeQM6QqILa4a2kLmwv1dvi+3jk3m4PfbQdFHFJfOR3NDsPmDj +kBOR/5Y1WTLCIgugaLOm+uJXkrfi0Ot0Qe+zX/Tv7TDoSm3DLj85CXVShh0j +8f7fqx/6Hq/hC1mIvtrGDmuXi5wKx+YU8504J3knUClZO7hxjJyGzuIEzfqu +EbIIjPOqMGiykdMxsdS4XKrsIe9C8GtktD9kIWfgkb9I/WDmLnk3AuUsz8Dp +JnImbjFJ/Z666+Q9wPJ0u9JbT96LllapPF5gJGdh3it7Wa89Rxaj8Llekvzq +JFmCgHju8qlZLTkbk21zP7gnislA+bi6KFBWEHY1oDyzGJjiqKlLMX/J8y3S +k0ddik7G5Do+COoy6L12UYMug7oMNs1+U+8xIXU5Wh5bDt/8LqAuR9UTC+tp +HI96Dsw/Fz6HatZRz0HVaE3mG2MMdQXcTLR+ODqKugITbINYPx2ShHsu3jG6 +2A+tgbCrc7FU2Zx/UL5APQ9no3juxJQZ6nmQZd2YKrv/iboSo/ImbbfdSV0J +laPdcYU9Tl2Fap9ZXFrwgroKs7VB/tD5Aclvkr7ebA== + "]]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{All, All}, + PlotRangeClipping->True, + PlotRangePadding->{Automatic, Automatic}]], "Output", + CellChangeTimes->{ + 3.514432694745741*^9, {3.514513786083666*^9, 3.5145139023460703`*^9}, { + 3.514513941993559*^9, 3.5145139832730093`*^9}, {3.5146888285392723`*^9, + 3.514688848948966*^9}, {3.514692300541842*^9, 3.5146923255000677`*^9}, { + 3.5146923628762283`*^9, 3.514692371357717*^9}, {3.51469241209544*^9, + 3.514692435030794*^9}, {3.514692526537298*^9, 3.514692546516489*^9}, { + 3.620425341044446*^9, 3.620425343554329*^9}, {3.620425394844013*^9, + 3.6204254016781588`*^9}},ExpressionUUID->"469ee891-e1ab-4e63-bc89-\ +55eb0b4660f2"] +}, Open ]], + +Cell["\<\ +Starting slightly above the equilibrium (collecting species in red and \ +detecting species in blue):\ +\>", "Text", + CellChangeTimes->{{3.5144263221305637`*^9, 3.514426329021406*^9}, { + 3.514426565192073*^9, 3.5144265653575697`*^9}, {3.514432634174358*^9, + 3.514432637243886*^9}, {3.5144327125256863`*^9, 3.514432718011566*^9}, { + 3.514688822889842*^9, 3.5146888251432343`*^9}, {3.514688937048484*^9, + 3.514688960776795*^9}, {3.6204252932103567`*^9, + 3.620425300445283*^9}},ExpressionUUID->"9c37b07f-3093-424b-bb94-\ +3b4bbfebf5fa"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"coop", "[", + RowBox[{ + "0.6", ",", "0.3", ",", "0.02", ",", "0.03", ",", "15", ",", "45", + ",", "t"}], "]"}], ",", "1"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "50"}], "}"}]}], "]"}], ",", + RowBox[{"Table", "[", + RowBox[{ + RowBox[{"Part", "[", + RowBox[{ + RowBox[{"coop", "[", + RowBox[{ + "0.6", ",", "0.3", ",", "0.02", ",", "0.03", ",", "15", ",", "45", + ",", "t"}], "]"}], ",", "2"}], "]"}], ",", + RowBox[{"{", + RowBox[{"t", ",", "0", ",", "50"}], "}"}]}], "]"}]}], "}"}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Red", ",", "Blue"}], "}"}]}]}], "]"}]], "Input", + CellChangeTimes->{{3.514432638805904*^9, 3.514432693910797*^9}, { + 3.514513746079535*^9, 3.5145137803745813`*^9}, {3.5145138494995947`*^9, + 3.5145139018855143`*^9}, {3.514513938677546*^9, 3.514513982882133*^9}, { + 3.5146888464207172`*^9, 3.514688848426044*^9}, {3.514692297794484*^9, + 3.514692325066819*^9}, {3.514692368754171*^9, 3.5146923708400583`*^9}, { + 3.5146924288677588`*^9, 3.514692434482533*^9}, {3.514692520157613*^9, + 3.5146925602909517`*^9}, {3.6204253137085857`*^9, + 3.620425343305471*^9}},ExpressionUUID->"80b44baa-03c8-485b-b350-\ +8993b88d764c"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {RGBColor[1, 0, 0], + LineBox[{{1., 15.}, {2., 19.5}, {3., 27.9825}, {4., 48.40902543749999}, { + 5., 118.47931136196483`}, {6., 569.493951416262}, {7., + 10904.5298185454}, {8., 3.640208969716443*^6}, {9., + 3.979083758511716*^11}, {10., 4.74994533212345*^21}, {11., + 6.76859419761851*^41}, {11., 2.5382228241069413`*^42}}]}, + {RGBColor[0, 0, 1], + LineBox[{{1., 45.}, {2., 51.74999999999999}, {3., 66.49874999999999}, {4., + 102.37316315624997`}, {5., 220.3347659898222}, {6., + 937.3876765000896}, {7., 16671.269730518405`}, {8., + 5.4654406254949*^6}, {9., 5.968642054598134*^11}, {10., + 7.124917998364234*^21}, {11., 1.0152891296427764`*^42}, {11., + 2.5382228241069413`*^42}}]}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{{0., 13.}, {0., 2.5382228241069413`*^42}}, + PlotRangeClipping->True, + PlotRangePadding->{ + Scaled[0.02], + Scaled[0.02]}]], "Output", + CellChangeTimes->{ + 3.514432694745741*^9, {3.514513786083666*^9, 3.5145139023460703`*^9}, { + 3.514513941993559*^9, 3.5145139832730093`*^9}, {3.5146888285392723`*^9, + 3.514688848948966*^9}, {3.514692300541842*^9, 3.5146923255000677`*^9}, { + 3.5146923628762283`*^9, 3.514692371357717*^9}, {3.51469241209544*^9, + 3.514692435030794*^9}, {3.514692526537298*^9, 3.514692546516489*^9}, { + 3.620425341044446*^9, + 3.620425343554329*^9}},ExpressionUUID->"b02a563d-25ca-429f-961d-\ +a237e7029e6d"] +}, Open ]], + +Cell["\<\ +This system displays a two-species \"Allee\" effect, where growth cannot \ +occur when either species is rare. Instead, both species must be reasonably \ +common for there to be enough cooperation present in the system for the \ +populations to take off.\ +\>", "Text", + CellChangeTimes->{{3.514688976472577*^9, + 3.514689147930705*^9}},ExpressionUUID->"52d499a3-b1bf-4c58-95d8-\ +8596556acd19"], + +Cell[TextData[{ + "We can also plot vector fields. How to do this has changed between \ +versions of ", + StyleBox["Mathematica", + FontSlant->"Italic"], + ".\n\nIf you have version 8, check out:" +}], "Text", + CellChangeTimes->{{3.5146903501374397`*^9, + 3.514690379733974*^9}},ExpressionUUID->"a05fce4c-d804-4196-b5f3-\ +9f7877e5ef08"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"?", "VectorPlot"}]], "Input", + CellChangeTimes->{{3.5146903998891983`*^9, + 3.514690403511883*^9}},ExpressionUUID->"48d98892-a54a-4f26-b5e3-\ +aac946bb3de1"], + +Cell[BoxData[ + RowBox[{ + StyleBox["\<\"\\!\\(\\*RowBox[{\\\"VectorPlot\\\", \\\"[\\\", \ +RowBox[{RowBox[{\\\"{\\\", RowBox[{SubscriptBox[StyleBox[\\\"v\\\", \ +\\\"TI\\\"], StyleBox[\\\"x\\\", \\\"TI\\\"]], \\\",\\\", \ +SubscriptBox[StyleBox[\\\"v\\\", \\\"TI\\\"], StyleBox[\\\"y\\\", \ +\\\"TI\\\"]]}], \\\"}\\\"}], \\\",\\\", RowBox[{\\\"{\\\", \ +RowBox[{StyleBox[\\\"x\\\", \\\"TI\\\"], \\\",\\\", \ +SubscriptBox[StyleBox[\\\"x\\\", \\\"TI\\\"], StyleBox[\\\"min\\\", \ +\\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"x\\\", \\\"TI\\\"], \ +StyleBox[\\\"max\\\", \\\"TI\\\"]]}], \\\"}\\\"}], \\\",\\\", RowBox[{\\\"{\\\ +\", RowBox[{StyleBox[\\\"y\\\", \\\"TI\\\"], \\\",\\\", \ +SubscriptBox[StyleBox[\\\"y\\\", \\\"TI\\\"], StyleBox[\\\"min\\\", \ +\\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"y\\\", \\\"TI\\\"], \ +StyleBox[\\\"max\\\", \\\"TI\\\"]]}], \\\"}\\\"}]}], \\\"]\\\"}]\\) generates \ +a vector plot of the vector field \\!\\(\\*RowBox[{\\\"{\\\", \ +RowBox[{SubscriptBox[StyleBox[\\\"v\\\", \\\"TI\\\"], StyleBox[\\\"x\\\", \ +\\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"v\\\", \\\"TI\\\"], \ +StyleBox[\\\"y\\\", \\\"TI\\\"]]}], \\\"}\\\"}]\\) as a function of \ +\\!\\(\\*StyleBox[\\\"x\\\", \\\"TI\\\"]\\) and \\!\\(\\*StyleBox[\\\"y\\\", \ +\\\"TI\\\"]\\). \\n\\!\\(\\*RowBox[{\\\"VectorPlot\\\", \\\"[\\\", \ +RowBox[{RowBox[{\\\"{\\\", RowBox[{RowBox[{\\\"{\\\", \ +RowBox[{SubscriptBox[StyleBox[\\\"v\\\", \\\"TI\\\"], StyleBox[\\\"x\\\", \ +\\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"v\\\", \\\"TI\\\"], \ +StyleBox[\\\"y\\\", \\\"TI\\\"]]}], \\\"}\\\"}], \\\",\\\", \ +RowBox[{\\\"{\\\", RowBox[{SubscriptBox[StyleBox[\\\"w\\\", \\\"TI\\\"], \ +StyleBox[\\\"x\\\", \\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"w\\\", \ +\\\"TI\\\"], StyleBox[\\\"y\\\", \\\"TI\\\"]]}], \\\"}\\\"}], \\\",\\\", \ +StyleBox[\\\"\[Ellipsis]\\\", \\\"TR\\\"]}], \\\"}\\\"}], \\\",\\\", RowBox[{\ +\\\"{\\\", RowBox[{StyleBox[\\\"x\\\", \\\"TI\\\"], \\\",\\\", \ +SubscriptBox[StyleBox[\\\"x\\\", \\\"TI\\\"], StyleBox[\\\"min\\\", \ +\\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"x\\\", \\\"TI\\\"], \ +StyleBox[\\\"max\\\", \\\"TI\\\"]]}], \\\"}\\\"}], \\\",\\\", RowBox[{\\\"{\\\ +\", RowBox[{StyleBox[\\\"y\\\", \\\"TI\\\"], \\\",\\\", \ +SubscriptBox[StyleBox[\\\"y\\\", \\\"TI\\\"], StyleBox[\\\"min\\\", \ +\\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"y\\\", \\\"TI\\\"], \ +StyleBox[\\\"max\\\", \\\"TI\\\"]]}], \\\"}\\\"}]}], \\\"]\\\"}]\\) plots \ +several vector fields. \"\>", "MSG"], "\[NonBreakingSpace]", + ButtonBox[ + StyleBox["\[RightSkeleton]", "SR"], + Active->True, + BaseStyle->"Link", + ButtonData->"paclet:ref/VectorPlot"]}]], "Print", "PrintUsage", + CellChangeTimes->{3.5146904043272943`*^9}, + CellTags-> + "Info3514665203-3164126",ExpressionUUID->"cf242f76-0f13-470e-8415-\ +d864fa3ca790"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"VectorPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"eqnc", "-", + RowBox[{"nc", "[", "t", "]"}]}], "/.", + RowBox[{"rc", "\[Rule]", "0.6"}]}], "/.", + RowBox[{"rd", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"\[Rho]c", "\[Rule]", "0.02"}]}], "/.", + RowBox[{"\[Rho]d", "\[Rule]", "0.03"}]}], ")"}], ",", + RowBox[{"(", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"eqnd", "-", + RowBox[{"nd", "[", "t", "]"}]}], "/.", + RowBox[{"rc", "\[Rule]", "0.1"}]}], "/.", + RowBox[{"rc", "\[Rule]", "0.6"}]}], "/.", + RowBox[{"rd", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"\[Rho]c", "\[Rule]", "0.02"}]}], "/.", + RowBox[{"\[Rho]d", "\[Rule]", "0.03"}]}], ")"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"nc", "[", "t", "]"}], ",", "0", ",", "50"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"nd", "[", "t", "]"}], ",", "0", ",", "50"}], "}"}]}], + "]"}]], "Input", + CellChangeTimes->{ + 3.514689733772607*^9, 3.5146902218045073`*^9, {3.514690289592782*^9, + 3.514690290589498*^9}, {3.514690448604793*^9, 3.514690601795931*^9}, { + 3.514690687423132*^9, 3.5146907150782433`*^9}, 3.514691258502099*^9, + 3.514691333024849*^9, {3.514692292490211*^9, 3.514692293682804*^9}, { + 3.620424814816428*^9, 3.620424841187956*^9}, {3.620424974586873*^9, + 3.620424987589387*^9}, {3.620425428022326*^9, + 3.620425487772934*^9}},ExpressionUUID->"8f7d9e28-4f5b-44d3-ace9-\ +b4e9dddbc194"], + +Cell[BoxData[ + GraphicsBox[{{}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.0007771356965619124, 1.}}], + ArrowBox[{{0., 3.614210484263389}, {0., 3.528646658593754}}]}, + {Arrowheads[{{0.0015542713931238248`, 1.}}], + ArrowBox[{{0., 7.228420968526778}, {0., 7.057293317187508}}]}, + {Arrowheads[{{0.0023314070896857412`, 1.}}], + ArrowBox[{{0., 10.842631452790167`}, {0., 10.585939975781262`}}]}, + {Arrowheads[{{0.0031085427862476496`, 1.}}], + ArrowBox[{{0., 14.456841937053555`}, {0., 14.114586634375016`}}]}, + {Arrowheads[{{0.003885678482809574, 1.}}], + ArrowBox[{{0., 18.071052421316946`}, {0., 17.64323329296877}}]}, + {Arrowheads[{{0.0046628141793714824`, 1.}}], + ArrowBox[{{0., 21.685262905580334`}, {0., 21.171879951562524`}}]}, + {Arrowheads[{{0.005439949875933391, 1.}}], + ArrowBox[{{0., 25.299473389843726`}, {0., 24.70052661015628}}]}, + {Arrowheads[{{0.006217085572495299, 1.}}], + ArrowBox[{{0., 28.913683874107114`}, {0., 28.229173268750035`}}]}, + {Arrowheads[{{0.006994221269057208, 1.}}], + ArrowBox[{{0., 32.5278943583705}, {0., 31.75781992734379}}]}, + {Arrowheads[{{0.007771356965619148, 1.}}], + ArrowBox[{{0., 36.14210484263389}, {0., 35.28646658593754}}]}, + {Arrowheads[{{0.008548492662181025, 1.}}], + ArrowBox[{{0., 39.75631532689728}, {0., 38.8151132445313}}]}, + {Arrowheads[{{0.009325628358742965, 1.}}], + ArrowBox[{{0., 43.37052581116066}, {0., 42.34375990312504}}]}, + {Arrowheads[{{0.01010276405530484, 1.}}], + ArrowBox[{{0., 46.98473629542405}, {0., 45.8724065617188}}]}, + {Arrowheads[{{0.010879899751866783`, 1.}}], + ArrowBox[{{0., 50.59894677968744}, {0., 49.40105322031255}}]}, + {Arrowheads[{{0.0015542713931238248`, 1.}}], + ArrowBox[{{3.6569923970982066`, 0.}, {3.4858647457589367`, 0.}}]}, + {Arrowheads[{{0.001457533215463639, 1.}}], + ArrowBox[{{3.646806227375631, 3.5989312296795255`}, {3.4960509154815123`, + 3.5439259131776173`}}]}, + {Arrowheads[{{0.0015494177303640787`, 1.}}], + ArrowBox[{{3.6366200576530554`, 7.197862459359051}, {3.506237085204088, + 7.087851826355235}}]}, + {Arrowheads[{{0.0018012873869661826`, 1.}}], + ArrowBox[{{3.62643388793048, 10.796793689038578`}, {3.5164232549266634`, + 10.631777739532854`}}]}, + {Arrowheads[{{0.0021578289821045753`, 1.}}], + ArrowBox[{{3.6162477182079042`, 14.395724918718102`}, {3.526609424649239, + 14.17570365271047}}]}, + {Arrowheads[{{0.0025759394984873974`, 1.}}], + ArrowBox[{{3.6060615484853287`, 17.994656148397628`}, { + 3.5367955943718146`, 17.719629565888088`}}]}, + {Arrowheads[{{0.0030302394958178986`, 1.}}], + ArrowBox[{{3.595875378762753, 21.593587378077157`}, {3.54698176409439, + 21.263555479065708`}}]}, + {Arrowheads[{{0.0035066917775093995`, 1.}}], + ArrowBox[{{3.5856892090401775`, 25.192518607756682`}, { + 3.5571679338169657`, 24.807481392243325`}}]}, + {Arrowheads[{{0.003997383114135979, 1.}}], + ArrowBox[{{3.575503039317602, 28.791449837436208`}, {3.5673541035395417`, + 28.351407305420942`}}]}, + {Arrowheads[{{0.004497655502391994, 1.}}], + ArrowBox[{{3.5653168695950264`, 32.39038106711573}, {3.577540273262117, + 31.89533321859856}}]}, + {Arrowheads[{{0.005004636549591219, 1.}}], + ArrowBox[{{3.555130699872451, 35.989312296795255`}, {3.5877264429846925`, + 35.439259131776176`}}]}, + {Arrowheads[{{0.005516476927088734, 1.}}], + ArrowBox[{{3.544944530149875, 39.58824352647478}, {3.597912612707268, + 38.983185044953785`}}]}, + {Arrowheads[{{0.00603193974596811, 1.}}], + ArrowBox[{{3.5347583604272996`, 43.187174756154306`}, { + 3.6080987824298436`, 42.52711095813141}}]}, + {Arrowheads[{{0.006550169862619392, 1.}}], + ArrowBox[{{3.524572190704724, 46.78610598583383}, {3.618284952152419, + 46.071036871309026`}}]}, + {Arrowheads[{{0.007070558823575107, 1.}}], + ArrowBox[{{3.5143860209821485`, 50.38503721551335}, {3.6284711218749948`, + 49.614962784486636`}}]}, + {Arrowheads[{{0.0031085427862476496`, 1.}}], + ArrowBox[{{7.313984794196413, 0.}, {6.971729491517873, 0.}}]}, + {Arrowheads[{{0.0027474649946412997`, 1.}}], + ArrowBox[{{7.293612454751262, 3.583651975095662}, {6.9921018309630245`, + 3.5592051677614807`}}]}, + {Arrowheads[{{0.0024096862063154967`, 1.}}], + ArrowBox[{{7.273240115306111, 7.167303950191324}, {7.012474170408176, + 7.118410335522961}}]}, + {Arrowheads[{{0.0021064447304203985`, 1.}}], + ArrowBox[{{7.25286777586096, 10.750955925286988`}, {7.032846509853327, + 10.677615503284443`}}]}, + {Arrowheads[{{0.0018547585462818025`, 1.}}], + ArrowBox[{{7.2324954364158085`, 14.334607900382649`}, {7.053218849298478, + 14.236820671045923`}}]}, + {Arrowheads[{{0.0016779890348198763`, 1.}}], + ArrowBox[{{7.212123096970657, 17.918259875478313`}, {7.073591188743629, + 17.796025838807406`}}]}, + {Arrowheads[{{0.0016011443439699533`, 1.}}], + ArrowBox[{{7.191750757525506, 21.501911850573975`}, {7.09396352818878, + 21.355231006568886`}}]}, + {Arrowheads[{{0.0016383459014380785`, 1.}}], + ArrowBox[{{7.171378418080355, 25.085563825669638`}, {7.114335867633931, + 24.91443617433037}}]}, + {Arrowheads[{{0.0017824672363249375`, 1.}}], + ArrowBox[{{7.151006078635204, 28.6692158007653}, {7.1347082070790835`, + 28.47364134209185}}]}, + {Arrowheads[{{0.002010646581989391, 1.}}], + ArrowBox[{{7.130633739190053, 32.25286777586096}, {7.155080546524234, + 32.03284650985333}}]}, + {Arrowheads[{{0.0022979791078336824`, 1.}}], + ArrowBox[{{7.110261399744902, 35.836519750956626`}, {7.175452885969385, + 35.59205167761481}}]}, + {Arrowheads[{{0.002625112255827428, 1.}}], + ArrowBox[{{7.08988906029975, 39.42017172605228}, {7.195825225414536, + 39.15125684537629}}]}, + {Arrowheads[{{0.00297896270614988, 1.}}], + ArrowBox[{{7.069516720854599, 43.003823701147944`}, {7.216197564859687, + 42.710462013137764`}}]}, + {Arrowheads[{{0.0033510776366489576`, 1.}}], + ArrowBox[{{7.049144381409448, 46.5874756762436}, {7.236569904304838, + 46.26966718089924}}]}, + {Arrowheads[{{0.0037360034692631825`, 1.}}], + ArrowBox[{{7.028772041964297, 50.17112765133926}, {7.2569422437499895`, + 49.828872348660724`}}]}, + {Arrowheads[{{0.004662814179371467, 1.}}], + ArrowBox[{{10.97097719129462, 0.}, {10.457594237276812`, 0.}}]}, + {Arrowheads[{{0.0041080923016248464`, 1.}}], + ArrowBox[{{10.940418682126893`, 3.5683727205117988`}, { + 10.488152746444538`, 3.574484422345344}}]}, + {Arrowheads[{{0.0035543545817355937`, 1.}}], + ArrowBox[{{10.909860172959167`, 7.1367454410235975`}, { + 10.518711255612265`, 7.148968844690688}}]}, + {Arrowheads[{{0.0030021456449436357`, 1.}}], + ArrowBox[{{10.87930166379144, 10.705118161535397`}, {10.549269764779991`, + 10.723453267036033`}}]}, + {Arrowheads[{{0.0024524983793913126`, 1.}}], + ArrowBox[{{10.848743154623714`, 14.273490882047195`}, { + 10.579828273947719`, 14.297937689381376`}}]}, + {Arrowheads[{{0.0019076283639885786`, 1.}}], + ArrowBox[{{10.818184645455986`, 17.841863602558995`}, { + 10.610386783115445`, 17.87242211172672}}]}, + {Arrowheads[{{0.001373233955298305, 1.}}], + ArrowBox[{{10.78762613628826, 21.410236323070794`}, {10.640945292283172`, + 21.446906534072067`}}]}, + {Arrowheads[{{0.0008688641226270456, 1.}}], + ArrowBox[{{10.757067627120533`, 24.978609043582594`}, { + 10.671503801450898`, 25.021390956417413`}}]}, + {Arrowheads[{{0.0004964937843583025, 1.}}], + ArrowBox[{{10.726509117952807`, 28.546981764094394`}, { + 10.702062310618626`, 28.595875378762756`}}]}, + {Arrowheads[{{0.0006004291289887068, 1.}}], + ArrowBox[{{10.695950608785079`, 32.11535448460619}, {10.732620819786352`, + 32.1703598011081}}]}, + {Arrowheads[{{0.0010473547854875284`, 1.}}], + ArrowBox[{{10.665392099617353`, 35.68372720511799}, {10.76317932895408, + 35.74484422345344}}]}, + {Arrowheads[{{0.00156710459164118, 1.}}], + ArrowBox[{{10.634833590449626`, 39.252099925629786`}, { + 10.793737838121805`, 39.319328645798784`}}]}, + {Arrowheads[{{0.0021064447304203985`, 1.}}], + ArrowBox[{{10.6042750812819, 42.82047264614158}, {10.824296347289533`, + 42.89381306814413}}]}, + {Arrowheads[{{0.0026534562084576815`, 1.}}], + ArrowBox[{{10.573716572114172`, 46.38884536665338}, {10.854854856457258`, + 46.46829749048947}}]}, + {Arrowheads[{{0.0032042125623627273`, 1.}}], + ArrowBox[{{10.543158062946446`, 49.957218087165174`}, { + 10.885413365624986`, 50.04278191283481}}]}, + {Arrowheads[{{0.006217085572495299, 1.}}], + ArrowBox[{{14.627969588392826`, 0.}, {13.943458983035747`, 0.}}]}, + {Arrowheads[{{0.005487073761108923, 1.}}], + ArrowBox[{{14.587224909502524`, 3.5530934659279354`}, { + 13.984203661926049`, 3.5897636769292074`}}]}, + {Arrowheads[{{0.00478343411604672, 1.}}], + ArrowBox[{{14.546480230612222`, 7.106186931855871}, {14.024948340816351`, + 7.179527353858415}}]}, + {Arrowheads[{{0.004119701865894927, 1.}}], + ArrowBox[{{14.50573555172192, 10.659280397783807`}, {14.065693019706654`, + 10.769291030787622`}}]}, + {Arrowheads[{{0.003518534215230182, 1.}}], + ArrowBox[{{14.464990872831617`, 14.212373863711742`}, { + 14.106437698596956`, 14.35905470771683}}]}, + {Arrowheads[{{0.003017558718935159, 1.}}], + ArrowBox[{{14.424246193941315`, 17.765467329639677`}, { + 14.147182377487258`, 17.948818384646035`}}]}, + {Arrowheads[{{0.0026737008544873916`, 1.}}], + ArrowBox[{{14.383501515051012`, 21.318560795567613`}, {14.18792705637756, + 21.538582061575244`}}]}, + {Arrowheads[{{0.0025512996560460048`, 1.}}], + ArrowBox[{{14.34275683616071, 24.87165426149555}, {14.228671735267863`, + 25.128345738504454`}}]}, + {Arrowheads[{{0.0026808621093191553`, 1.}}], + ArrowBox[{{14.302012157270408`, 28.424747727423487`}, { + 14.269416414158167`, 28.718109415433663`}}]}, + {Arrowheads[{{0.003030239495817962, 1.}}], + ArrowBox[{{14.261267478380105`, 31.97784119335142}, {14.310161093048468`, + 32.307873092362875`}}]}, + {Arrowheads[{{0.0035348435882561068`, 1.}}], + ArrowBox[{{14.220522799489803`, 35.53093465927935}, {14.35090577193877, + 35.89763676929208}}]}, + {Arrowheads[{{0.004138275609894064, 1.}}], + ArrowBox[{{14.1797781205995, 39.08402812520729}, {14.391650450829072`, + 39.48740044622128}}]}, + {Arrowheads[{{0.004803433031909806, 1.}}], + ArrowBox[{{14.139033441709199`, 42.63712159113522}, {14.432395129719376`, + 43.07716412315048}}]}, + {Arrowheads[{{0.005507998801672804, 1.}}], + ArrowBox[{{14.098288762818896`, 46.190215057063156`}, { + 14.473139808609677`, 46.66692780007969}}]}, + {Arrowheads[{{0.00623863532713724, 1.}}], + ArrowBox[{{14.057544083928594`, 49.743308522991086`}, { + 14.513884487499979`, 50.25669147700889}}]}, + {Arrowheads[{{0.007771356965619116, 1.}}], + ArrowBox[{{18.284961985491034`, 0.}, {17.429323728794685`, 0.}}]}, + {Arrowheads[{{0.006873371239815352, 1.}}], + ArrowBox[{{18.234031136878155`, 3.537814211344072}, {17.480254577407564`, + 3.6050429315130708`}}]}, + {Arrowheads[{{0.0060456599277888155`, 1.}}], + ArrowBox[{{18.183100288265276`, 7.075628422688144}, {17.53118542602044, + 7.2100858630261415`}}]}, + {Arrowheads[{{0.005321118714474255, 1.}}], + ArrowBox[{{18.132169439652397`, 10.613442634032218`}, { + 17.582116274633314`, 10.815128794539214`}}]}, + {Arrowheads[{{0.004747223760630056, 1.}}], + ArrowBox[{{18.08123859103952, 14.151256845376288`}, {17.633047123246193`, + 14.420171726052283`}}]}, + {Arrowheads[{{0.004383547780321239, 1.}}], + ArrowBox[{{18.030307742426643`, 17.689071056720362`}, { + 17.683977971859075`, 18.025214657565357`}}]}, + {Arrowheads[{{0.00428396749522381, 1.}}], + ArrowBox[{{17.979376893813765`, 21.226885268064436`}, {17.73490882047195, + 21.63025758907843}}]}, + {Arrowheads[{{0.004466183214649285, 1.}}], + ArrowBox[{{17.928446045200886`, 24.764699479408506`}, {17.78583966908483, + 25.235300520591498`}}]}, + {Arrowheads[{{0.004898850493983466, 1.}}], + ArrowBox[{{17.877515196588007`, 28.30251369075258}, {17.836770517697705`, + 28.84034345210457}}]}, + {Arrowheads[{{0.005523423618272986, 1.}}], + ArrowBox[{{17.826584347975132`, 31.84032790209665}, {17.887701366310587`, + 32.445386383617645`}}]}, + {Arrowheads[{{0.006282930002816735, 1.}}], + ArrowBox[{{17.775653499362253`, 35.378142113440724`}, { + 17.938632214923462`, 36.050429315130714`}}]}, + {Arrowheads[{{0.007134405302658374, 1.}}], + ArrowBox[{{17.724722650749374`, 38.915956324784794`}, { + 17.989563063536337`, 39.65547224664378}}]}, + {Arrowheads[{{0.008048714013667737, 1.}}], + ArrowBox[{{17.673791802136495`, 42.453770536128864`}, { + 18.040493912149216`, 43.26051517815685}}]}, + {Arrowheads[{{0.009006741040683292, 1.}}], + ArrowBox[{{17.62286095352362, 45.991584747472935`}, {18.091424760762095`, + 46.86555810966992}}]}, + {Arrowheads[{{0.009995924155522215, 1.}}], + ArrowBox[{{17.57193010491074, 49.529398958817}, {18.142355609374974`, + 50.47060104118298}}]}, + {Arrowheads[{{0.009325628358742934, 1.}}], + ArrowBox[{{21.94195438258924, 0.}, {20.915188474553624`, 0.}}]}, + {Arrowheads[{{0.008263303430231917, 1.}}], + ArrowBox[{{21.880837364253786`, 3.5225349567602087`}, { + 20.976305492889075`, 3.620322186096934}}]}, + {Arrowheads[{{0.0073239144282576316`, 1.}}], + ArrowBox[{{21.819720345918334`, 7.045069913520417}, {21.03742251122453, + 7.240644372193868}}]}, + {Arrowheads[{{0.006560484829832592, 1.}}], + ArrowBox[{{21.75860332758288, 10.567604870280627`}, {21.098539529559982`, + 10.860966558290803`}}]}, + {Arrowheads[{{0.006040107576041374, 1.}}], + ArrowBox[{{21.697486309247427`, 14.090139827040835`}, { + 21.159656547895437`, 14.481288744387737`}}]}, + {Arrowheads[{{0.005828253386350562, 1.}}], + ArrowBox[{{21.636369290911972`, 17.612674783801044`}, {21.22077356623089, + 18.10161093048467}}]}, + {Arrowheads[{{0.0059579254122997015`, 1.}}], + ArrowBox[{{21.57525227257652, 21.135209740561255`}, {21.281890584566344`, + 21.721933116581607`}}]}, + {Arrowheads[{{0.006408425124725438, 1.}}], + ArrowBox[{{21.514135254241065`, 24.657744697321466`}, { + 21.343007602901796`, 25.342255302678545`}}]}, + {Arrowheads[{{0.00711910455166681, 1.}}], + ArrowBox[{{21.453018235905613`, 28.180279654081673`}, {21.40412462123725, + 28.962577488775477`}}]}, + {Arrowheads[{{0.008021102563462237, 1.}}], + ArrowBox[{{21.391901217570158`, 31.70281461084188}, {21.465241639572703`, + 32.582899674872415`}}]}, + {Arrowheads[{{0.00905744018623705, 1.}}], + ArrowBox[{{21.330784199234706`, 35.22534956760209}, {21.52635865790816, + 36.20322186096934}}]}, + {Arrowheads[{{0.010187200734186464`, 1.}}], + ArrowBox[{{21.26966718089925, 38.74788452436229}, {21.58747567624361, + 39.82354404706627}}]}, + {Arrowheads[{{0.011382600517791271`, 1.}}], + ArrowBox[{{21.2085501625638, 42.2704194811225}, {21.648592694579065`, + 43.443866233163206`}}]}, + {Arrowheads[{{0.012625008117791528`, 1.}}], + ArrowBox[{{21.147433144228344`, 45.792954437882706`}, { + 21.709709712914517`, 47.06418841926014}}]}, + {Arrowheads[{{0.013901825962032686`, 1.}}], + ArrowBox[{{21.086316125892893`, 49.31548939464292}, {21.770826731249972`, + 50.684510605357076`}}]}, + {Arrowheads[{{0.01087989975186675, 1.}}], + ArrowBox[{{25.59894677968745, 0.}, {24.401053220312562`, 0.}}]}, + {Arrowheads[{{0.009655300751355959, 1.}}], + ArrowBox[{{25.527643591629417`, 3.5072557021763453`}, { + 24.472356408370587`, 3.6356014406807975`}}]}, + {Arrowheads[{{0.008611062519368108, 1.}}], + ArrowBox[{{25.45634040357139, 7.014511404352691}, {24.54365959642862, + 7.271202881361595}}]}, + {Arrowheads[{{0.007819777103643382, 1.}}], + ArrowBox[{{25.38503721551336, 10.521767106529037`}, {24.614962784486647`, + 10.906804322042394`}}]}, + {Arrowheads[{{0.007363449009379432, 1.}}], + ArrowBox[{{25.313734027455332`, 14.029022808705381`}, {24.68626597254468, + 14.54240576272319}}]}, + {Arrowheads[{{0.007305121477543282, 1.}}], + ArrowBox[{{25.2424308393973, 17.536278510881726`}, {24.757569160602703`, + 18.178007203403986`}}]}, + {Arrowheads[{{0.007653898968138031, 1.}}], + ArrowBox[{{25.171127651339273`, 21.043534213058074`}, { + 24.828872348660735`, 21.813608644084788`}}]}, + {Arrowheads[{{0.008358976621102137, 1.}}], + ArrowBox[{{25.099824463281244`, 24.55078991523442}, {24.900175536718763`, + 25.44921008476559}}]}, + {Arrowheads[{{0.00934000867315798, 1.}}], + ArrowBox[{{25.028521275223216`, 28.058045617410766`}, { + 24.971478724776794`, 29.084811525446383`}}]}, + {Arrowheads[{{0.010520075332528231`, 1.}}], + ArrowBox[{{24.957218087165185`, 31.56530131958711}, {25.04278191283482, + 32.720412966127185`}}]}, + {Arrowheads[{{0.011839812461113423`, 1.}}], + ArrowBox[{{24.885914899107156`, 35.07255702176345}, {25.11408510089285, + 36.35601440680797}}]}, + {Arrowheads[{{0.013257574602900554`, 1.}}], + ArrowBox[{{24.814611711049128`, 38.579812723939796`}, {25.18538828895088, + 39.991615847488774`}}]}, + {Arrowheads[{{0.014745113112942763`, 1.}}], + ArrowBox[{{24.7433085229911, 42.08706842611614}, {25.25669147700891, + 43.62721728816957}}]}, + {Arrowheads[{{0.016283316253157595`, 1.}}], + ArrowBox[{{24.67200533493307, 45.594324128292484`}, {25.327994665066935`, + 47.26281872885036}}]}, + {Arrowheads[{{0.017859097592322095`, 1.}}], + ArrowBox[{{24.60070214687504, 49.10157983046883}, {25.399297853124963`, + 50.898420169531164`}}]}, + {Arrowheads[{{0.012434171144990598`, 1.}}], + ArrowBox[{{29.255939176785656`, 0.}, {27.886917966071497`, 0.}}]}, + {Arrowheads[{{0.011048582680935951`, 1.}}], + ArrowBox[{{29.17444981900505, 3.491976447592482}, {27.9684073238521, + 3.650880695264661}}]}, + {Arrowheads[{{0.009903637182497642, 1.}}], + ArrowBox[{{29.092960461224447`, 6.983952895184964}, {28.049896681632706`, + 7.301761390529322}}]}, + {Arrowheads[{{0.009090718487453719, 1.}}], + ArrowBox[{{29.011471103443842`, 10.475929342777446`}, {28.13138603941331, + 10.952642085793984`}}]}, + {Arrowheads[{{0.00870336594566876, 1.}}], + ArrowBox[{{28.929981745663238`, 13.967905790369928`}, { + 28.212875397193915`, 14.603522781058643`}}]}, + {Arrowheads[{{0.008797970103429073, 1.}}], + ArrowBox[{{28.848492387882633`, 17.45988223796241}, {28.29436475497452, + 18.254403476323308`}}]}, + {Arrowheads[{{0.009359928423227803, 1.}}], + ArrowBox[{{28.76700303010203, 20.951858685554893`}, {28.375854112755125`, + 21.90528417158797}}]}, + {Arrowheads[{{0.010313123931456168`, 1.}}], + ArrowBox[{{28.685513672321424`, 24.443835133147378`}, {28.45734347053573, + 25.55616486685263}}]}, + {Arrowheads[{{0.011561188232777478`, 1.}}], + ArrowBox[{{28.60402431454082, 27.93581158073986}, {28.538832828316334`, + 29.207045562117294`}}]}, + {Arrowheads[{{0.013019596939704378`, 1.}}], + ArrowBox[{{28.522534956760214`, 31.42778802833234}, {28.62032218609694, + 32.85792625738195}}]}, + {Arrowheads[{{0.014625560453586763`, 1.}}], + ArrowBox[{{28.44104559897961, 34.91976447592482}, {28.701811543877543`, + 36.508806952646616`}}]}, + {Arrowheads[{{0.01633561800732347, 1.}}], + ArrowBox[{{28.359556241199005`, 38.4117409235173}, {28.783300901658148`, + 40.15968764791127}}]}, + {Arrowheads[{{0.018120322728124114`, 1.}}], + ArrowBox[{{28.2780668834184, 41.90371737110978}, {28.864790259438752`, + 43.81056834317592}}]}, + {Arrowheads[{{0.019959660790005114`, 1.}}], + ArrowBox[{{28.196577525637796`, 45.395693818702256`}, { + 28.946279617219357`, 47.46144903844059}}]}, + {Arrowheads[{{0.02183983298753146, 1.}}], + ArrowBox[{{28.11508816785719, 48.88767026629474}, {29.02776897499996, + 51.112329733705245`}}]}, + {Arrowheads[{{0.013988442538114416`, 1.}}], + ArrowBox[{{32.91293157388386, 0.}, {31.372782711830432`, 0.}}]}, + {Arrowheads[{{0.012442717691690643`, 1.}}], + ArrowBox[{{32.82125604638068, 3.4766971930086186`}, {31.464458239333613`, + 3.6661599498485242`}}]}, + {Arrowheads[{{0.011199759718078328`, 1.}}], + ArrowBox[{{32.7295805188775, 6.953394386017237}, {31.55613376683679, + 7.3323198996970484`}}]}, + {Arrowheads[{{0.010369026338324424`, 1.}}], + ArrowBox[{{32.63790499137432, 10.430091579025857`}, {31.647809294339975`, + 10.998479849545575`}}]}, + {Arrowheads[{{0.01005323290994684, 1.}}], + ArrowBox[{{32.546229463871136`, 13.906788772034474`}, { + 31.739484821843153`, 14.664639799394097`}}]}, + {Arrowheads[{{0.010299853006378708`, 1.}}], + ArrowBox[{{32.45455393636796, 17.383485965043093`}, {31.831160349346334`, + 18.330799749242622`}}]}, + {Arrowheads[{{0.01107136609633046, 1.}}], + ArrowBox[{{32.36287840886478, 20.860183158051715`}, {31.92283587684951, + 21.99695969909115}}]}, + {Arrowheads[{{0.01226914902507662, 1.}}], + ArrowBox[{{32.271202881361596`, 24.336880351060334`}, { + 32.014511404352696`, 25.663119648939674`}}]}, + {Arrowheads[{{0.01378251006292755, 1.}}], + ArrowBox[{{32.17952735385842, 27.813577544068952`}, {32.10618693185587, + 29.329279598788197`}}]}, + {Arrowheads[{{0.015519402203192478`, 1.}}], + ArrowBox[{{32.08785182635524, 31.29027473707757}, {32.19786245935906, + 32.99543954863672}}]}, + {Arrowheads[{{0.017413064093628437`, 1.}}], + ArrowBox[{{31.996176298852056`, 34.766971930086186`}, { + 32.289537986862236`, 36.661599498485245`}}]}, + {Arrowheads[{{0.01941768402224533, 1.}}], + ArrowBox[{{31.90450077134888, 38.243669123094804`}, {32.38121351436541, + 40.327759448333765`}}]}, + {Arrowheads[{{0.02150225103846829, 1.}}], + ArrowBox[{{31.812825243845698`, 41.72036631610342}, {32.47288904186859, + 43.99391939818229}}]}, + {Arrowheads[{{0.023645630503952624`, 1.}}], + ArrowBox[{{31.721149716342516`, 45.197063509112034`}, { + 32.564564569371775`, 47.660079348030806`}}]}, + {Arrowheads[{{0.025833187558104383`, 1.}}], + ArrowBox[{{31.629474188839335`, 48.67376070212065}, {32.65624009687496, + 51.32623929787933}}]}, + {Arrowheads[{{0.015542713931238232`, 1.}}], + ArrowBox[{{36.56992397098207, 0.}, {34.85864745758937, 0.}}]}, + {Arrowheads[{{0.01383744793999362, 1.}}], + ArrowBox[{{36.46806227375631, 3.461417938424755}, {34.96050915481513, + 3.6814392044323876`}}]}, + {Arrowheads[{{0.012498326392477, 1.}}], + ArrowBox[{{36.36620057653055, 6.92283587684951}, {35.06237085204088, + 7.362878408864775}}]}, + {Arrowheads[{{0.011652276503364657`, 1.}}], + ArrowBox[{{36.264338879304795`, 10.384253815274267`}, { + 35.164232549266636`, 11.044317613297164`}}]}, + {Arrowheads[{{0.011409518867418008`, 1.}}], + ArrowBox[{{36.16247718207904, 13.84567175369902}, {35.266094246492386`, + 14.72575681772955}}]}, + {Arrowheads[{{0.011807323229174153`, 1.}}], + ArrowBox[{{36.06061548485329, 17.307089692123775`}, {35.36795594371815, + 18.40719602216194}}]}, + {Arrowheads[{{0.01278604046871227, 1.}}], + ArrowBox[{{35.95875378762753, 20.768507630548534`}, {35.4698176409439, + 22.088635226594327`}}]}, + {Arrowheads[{{0.014226277372314449`, 1.}}], + ArrowBox[{{35.85689209040177, 24.22992556897329}, {35.57167933816966, + 25.770074431026718`}}]}, + {Arrowheads[{{0.016003914922844, 1.}}], + ArrowBox[{{35.755030393176014`, 27.691343507398045`}, {35.67354103539541, + 29.451513635459104`}}]}, + {Arrowheads[{{0.018019373069514802`, 1.}}], + ArrowBox[{{35.653168695950264`, 31.1527614458228}, {35.775402732621174`, + 33.13295283989149}}]}, + {Arrowheads[{{0.020201596638786012`, 1.}}], + ArrowBox[{{35.551306998724506`, 34.61417938424756}, {35.877264429846925`, + 36.81439204432388}}]}, + {Arrowheads[{{0.022502119803947118`, 1.}}], + ArrowBox[{{35.44944530149875, 38.07559732267231}, {35.979126127072675`, + 40.49583124875627}}]}, + {Arrowheads[{{0.02488815928435226, 1.}}], + ArrowBox[{{35.347583604273, 41.53701526109706}, {36.08098782429843, + 44.17727045318865}}]}, + {Arrowheads[{{0.027337332302778176`, 1.}}], + ArrowBox[{{35.24572190704724, 44.99843319952181}, {36.18284952152419, + 47.858709657621034`}}]}, + {Arrowheads[{{0.029834094426995337`, 1.}}], + ArrowBox[{{35.14386020982148, 48.459851137946565`}, {36.28471121874995, + 51.54014886205342}}]}, + {Arrowheads[{{0.01709698532436205, 1.}}], + ArrowBox[{{40.22691636808027, 0.}, {38.3445122033483, 0.}}]}, + {Arrowheads[{{0.015232609923064697`, 1.}}], + ArrowBox[{{40.11486850113194, 3.446138683840892}, {38.45656007029663, + 3.696718459016251}}]}, + {Arrowheads[{{0.013798647181993685`, 1.}}], + ArrowBox[{{40.00282063418361, 6.892277367681784}, {38.56860793724496, + 7.393436918032502}}]}, + {Arrowheads[{{0.012938998575474423`, 1.}}], + ArrowBox[{{39.890772767235276`, 10.338416051522676`}, {38.6806558041933, + 11.090155377048754`}}]}, + {Arrowheads[{{0.012770178750401774`, 1.}}], + ArrowBox[{{39.778724900286946`, 13.784554735363567`}, {38.79270367114163, + 14.786873836065004`}}]}, + {Arrowheads[{{0.013318483682326302`, 1.}}], + ArrowBox[{{39.66667703333861, 17.23069341920446}, {38.904751538089954`, + 18.483592295081255`}}]}, + {Arrowheads[{{0.014502803555646288`, 1.}}], + ArrowBox[{{39.55462916639028, 20.676832103045353`}, {39.016799405038284`, + 22.18031075409751}}]}, + {Arrowheads[{{0.016184108731994985`, 1.}}], + ArrowBox[{{39.44258129944195, 24.122970786886246`}, {39.12884727198662, + 25.87702921311376}}]}, + {Arrowheads[{{0.018225372452229906`, 1.}}], + ArrowBox[{{39.33053343249362, 27.56910947072714}, {39.24089513893495, + 29.57374767213001}}]}, + {Arrowheads[{{0.02051944901048902, 1.}}], + ArrowBox[{{39.218485565545286`, 31.01524815456803}, {39.35294300588328, + 33.27046613114626}}]}, + {Arrowheads[{{0.022990783707036094`, 1.}}], + ArrowBox[{{39.106437698596956`, 34.46138683840892}, {39.46499087283161, + 36.96718459016251}}]}, + {Arrowheads[{{0.025588068397819096`, 1.}}], + ArrowBox[{{38.994389831648625`, 37.907525522249806`}, {39.57703873977995, + 40.66390304917876}}]}, + {Arrowheads[{{0.028276617801592106`, 1.}}], + ArrowBox[{{38.882341964700295`, 41.3536642060907}, {39.68908660672828, + 44.36062150819501}}]}, + {Arrowheads[{{0.03103272056010007, 1.}}], + ArrowBox[{{38.77029409775196, 44.79980288993159}, {39.801134473676605`, + 48.05733996721126}}]}, + {Arrowheads[{{0.0338398749631746, 1.}}], + ArrowBox[{{38.65824623080363, 48.24594157377248}, {39.913182340624935`, + 51.7540584262275}}]}, + {Arrowheads[{{0.018651256717485867`, 1.}}], + ArrowBox[{{43.883908765178475`, 0.}, {41.83037694910724, 0.}}]}, + {Arrowheads[{{0.016628094968569103`, 1.}}], + ArrowBox[{{43.761674728507565`, 3.430859429257029}, {41.95261098577814, + 3.7119977136001143`}}]}, + {Arrowheads[{{0.01510026894010344, 1.}}], + ArrowBox[{{43.63944069183666, 6.861718858514057}, {42.074845022449054`, + 7.423995427200229}}]}, + {Arrowheads[{{0.014228250647239104`, 1.}}], + ArrowBox[{{43.51720665516575, 10.292578287771086`}, {42.19707905911996, + 11.135993140800343`}}]}, + {Arrowheads[{{0.014133949396236538`, 1.}}], + ArrowBox[{{43.39497261849485, 13.723437717028114`}, {42.31931309579087, + 14.847990854400457`}}]}, + {Arrowheads[{{0.014832206485469313`, 1.}}], + ArrowBox[{{43.27273858182394, 17.154297146285142`}, {42.44154713246177, + 18.55998856800057}}]}, + {Arrowheads[{{0.016220992187820353`, 1.}}], + ArrowBox[{{43.150504545153034`, 20.58515657554217}, {42.56378116913268, + 22.271986281600686`}}]}, + {Arrowheads[{{0.01814241550964391, 1.}}], + ArrowBox[{{43.02827050848212, 24.0160160047992}, {42.686015205803585`, + 25.983983995200802`}}]}, + {Arrowheads[{{0.02044686548420845, 1.}}], + ArrowBox[{{42.90603647181122, 27.44687543405623}, {42.808249242474496`, + 29.695981708800918`}}]}, + {Arrowheads[{{0.02301959579079459, 1.}}], + ArrowBox[{{42.78380243514031, 30.877734863313258`}, {42.9304832791454, + 33.40797942240103}}]}, + {Arrowheads[{{0.025780412860373872`, 1.}}], + ArrowBox[{{42.661568398469406`, 34.308594292570284`}, {43.05271731581631, + 37.11997713600114}}]}, + {Arrowheads[{{0.028675041390878595`, 1.}}], + ArrowBox[{{42.539334361798495`, 37.73945372182731}, {43.17495135248721, + 40.83197484960125}}]}, + {Arrowheads[{{0.03166680793707157, 1.}}], + ArrowBox[{{42.41710032512759, 41.170313151084336`}, {43.29718538915812, + 44.543972563201365`}}]}, + {Arrowheads[{{0.03473061856223792, 1.}}], + ArrowBox[{{42.29486628845668, 44.60117258034136}, {43.41941942582903, + 48.25597027680148}}]}, + {Arrowheads[{{0.03784898177158085, 1.}}], + ArrowBox[{{42.17263225178578, 48.03203200959839}, {43.54165346249994, + 51.96796799040159}}]}, + {Arrowheads[{{0.02020552811060968, 1.}}], + ArrowBox[{{47.540901162276676`, 0.}, {45.31624169486617, 0.}}]}, + {Arrowheads[{{0.018023828037865598`, 1.}}], + ArrowBox[{{47.40848095588319, 3.415580174673165}, {45.44866190125965, + 3.7272769681839777`}}]}, + {Arrowheads[{{0.016402881961528042`, 1.}}], + ArrowBox[{{47.27606074948971, 6.83116034934633}, {45.58108210765313, + 7.454553936367955}}]}, + {Arrowheads[{{0.015519402203192518`, 1.}}], + ArrowBox[{{47.143640543096225`, 10.246740524019497`}, { + 45.713502314046615`, 11.181830904551935`}}]}, + {Arrowheads[{{0.01550000972388258, 1.}}], + ArrowBox[{{47.01122033670275, 13.66232069869266}, {45.845922520440105`, + 14.909107872735913`}}]}, + {Arrowheads[{{0.016347779871646657`, 1.}}], + ArrowBox[{{46.878800130309266`, 17.077900873365827`}, {45.97834272683358, + 18.63638484091989}}]}, + {Arrowheads[{{0.017940196783160937`, 1.}}], + ArrowBox[{{46.74637992391578, 20.493481048038994`}, {46.110762933227065`, + 22.36366180910387}}]}, + {Arrowheads[{{0.02010105875571292, 1.}}], + ArrowBox[{{46.6139597175223, 23.90906122271216}, {46.24318313962055, + 26.09093877728785}}]}, + {Arrowheads[{{0.02266838358106001, 1.}}], + ArrowBox[{{46.481539511128815`, 27.324641397385324`}, {46.37560334601403, + 29.818215745471825`}}]}, + {Arrowheads[{{0.025519792590279464`, 1.}}], + ArrowBox[{{46.34911930473533, 30.740221572058488`}, {46.50802355240751, + 33.545492713655804`}}]}, + {Arrowheads[{{0.0285703546026131, 1.}}], + ArrowBox[{{46.21669909834185, 34.155801746731655`}, {46.64044375880099, + 37.27276968183978}}]}, + {Arrowheads[{{0.03176274010507581, 1.}}], + ArrowBox[{{46.08427889194837, 37.571381921404814`}, {46.77286396519448, + 41.000046650023755`}}]}, + {Arrowheads[{{0.035058227343114326`, 1.}}], + ArrowBox[{{45.95185868555489, 40.98696209607798}, {46.905284171587965`, + 44.727323618207734`}}]}, + {Arrowheads[{{0.038430301826758384`, 1.}}], + ArrowBox[{{45.819438479161406`, 44.40254227075114}, {47.03770437798144, + 48.454600586391706`}}]}, + {Arrowheads[{{0.04186045916070883, 1.}}], + ArrowBox[{{45.68701827276792, 47.81812244542431}, {47.170124584374925`, + 52.181877554575685`}}]}, + {Arrowheads[{{0.0217597995037335, 1.}}], + ArrowBox[{{51.19789355937488, 0.}, {48.80210644062511, 0.}}]}, + {Arrowheads[{{0.019419755653268016`, 1.}}], + ArrowBox[{{51.05528718325882, 3.4003009200893017`}, {48.94471281674116, + 3.742556222767841}}]}, + {Arrowheads[{{0.01770626747211976, 1.}}], + ArrowBox[{{50.91268080714276, 6.800601840178604}, {49.08731919285722, + 7.485112445535682}}]}, + {Arrowheads[{{0.01681201561168438, 1.}}], + ArrowBox[{{50.77007443102671, 10.200902760267907`}, {49.22992556897328, + 11.227668668303524`}}]}, + {Arrowheads[{{0.01686780344420843, 1.}}], + ArrowBox[{{50.62746805491065, 13.601203680357209`}, {49.37253194508934, + 14.970224891071366`}}]}, + {Arrowheads[{{0.017864732858597167`, 1.}}], + ArrowBox[{{50.48486167879459, 17.00150460044651}, {49.51513832120539, + 18.712781113839206`}}]}, + {Arrowheads[{{0.019660150817256982`, 1.}}], + ArrowBox[{{50.34225530267853, 20.401805520535813`}, {49.657744697321455`, + 22.455337336607048`}}]}, + {Arrowheads[{{0.022059948848018686`, 1.}}], + ArrowBox[{{50.199648926562475`, 23.802106440625117`}, {49.80035107343751, + 26.197893559374894`}}]}, + {Arrowheads[{{0.02488992003138558, 1.}}], + ArrowBox[{{50.05704255044642, 27.202407360714417`}, {49.942957449553575`, + 29.940449782142732`}}]}, + {Arrowheads[{{0.028020026019473974`, 1.}}], + ArrowBox[{{49.914436174330355`, 30.602708280803718`}, { + 50.085563825669624`, 33.683006004910574`}}]}, + {Arrowheads[{{0.03136052550686748, 1.}}], + ArrowBox[{{49.7718297982143, 34.00300920089302}, {50.22817020178569, + 37.42556222767841}}]}, + {Arrowheads[{{0.034850971650349026`, 1.}}], + ArrowBox[{{49.62922342209824, 37.40331012098232}, {50.370776577901744`, + 41.16811845044625}}]}, + {Arrowheads[{{0.03845055074835259, 1.}}], + ArrowBox[{{49.486617045982186`, 40.80361104107162}, {50.51338295401781, + 44.91067467321409}}]}, + {Arrowheads[{{0.0421313000476072, 1.}}], + ArrowBox[{{49.34401066986612, 44.20391196116092}, {50.655989330133856`, + 48.653230895981935`}}]}, + {Arrowheads[{{0.04587368524026637, 1.}}], + ArrowBox[{{49.201404293750066`, 47.60421288125022}, {50.79859570624992, + 52.39578711874977}}]}}}, + AspectRatio->1, + Frame->True, + Method->{"TransparentPolygonMesh" -> True}, + PlotRange->{{-2.525381361380527, 52.525381361380525`}, {-2.525381361380527, + 52.525381361380525`}}, + PlotRangeClipping->True, + PlotRangePadding->{ + Scaled[0.02], + Scaled[0.02]}]], "Output", + CellChangeTimes->{{3.514689734268895*^9, 3.514689750969233*^9}, + 3.514690222263288*^9, {3.5146902854170923`*^9, 3.5146902918855658`*^9}, { + 3.51469045235388*^9, 3.514690506014859*^9}, {3.514690538352872*^9, + 3.514690602405677*^9}, {3.514690688589283*^9, 3.514690715784206*^9}, + 3.5146907645273867`*^9, 3.51469125913673*^9, 3.514691333960888*^9, + 3.514692575456017*^9, {3.62042545734803*^9, + 3.620425488048668*^9}},ExpressionUUID->"939ba5b0-2eaa-4107-8b40-\ +5a23f632e8ab"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"?", "StreamPlot"}]], "Input", + CellChangeTimes->{{3.5146903846806192`*^9, + 3.514690385006886*^9}},ExpressionUUID->"d4a15bb4-aa7a-4d78-bbb4-\ +a5de2425508f"], + +Cell[BoxData[ + RowBox[{ + StyleBox["\<\"\!\(\*RowBox[{\\\"StreamPlot\\\", \\\"[\\\", RowBox[{RowBox[{\ +\\\"{\\\", RowBox[{SubscriptBox[StyleBox[\\\"v\\\", \\\"TI\\\"], \ +StyleBox[\\\"x\\\", \\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"v\\\", \ +\\\"TI\\\"], StyleBox[\\\"y\\\", \\\"TI\\\"]]}], \\\"}\\\"}], \\\",\\\", \ +RowBox[{\\\"{\\\", RowBox[{StyleBox[\\\"x\\\", \\\"TI\\\"], \\\",\\\", \ +SubscriptBox[StyleBox[\\\"x\\\", \\\"TI\\\"], StyleBox[\\\"min\\\", \ +\\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"x\\\", \\\"TI\\\"], \ +StyleBox[\\\"max\\\", \\\"TI\\\"]]}], \\\"}\\\"}], \\\",\\\", RowBox[{\\\"{\\\ +\", RowBox[{StyleBox[\\\"y\\\", \\\"TI\\\"], \\\",\\\", \ +SubscriptBox[StyleBox[\\\"y\\\", \\\"TI\\\"], StyleBox[\\\"min\\\", \ +\\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"y\\\", \\\"TI\\\"], \ +StyleBox[\\\"max\\\", \\\"TI\\\"]]}], \\\"}\\\"}]}], \\\"]\\\"}]\) generates \ +a stream plot of the vector field \!\(\*RowBox[{\\\"{\\\", \ +RowBox[{SubscriptBox[StyleBox[\\\"v\\\", \\\"TI\\\"], StyleBox[\\\"x\\\", \ +\\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"v\\\", \\\"TI\\\"], \ +StyleBox[\\\"y\\\", \\\"TI\\\"]]}], \\\"}\\\"}]\) as a function of \ +\!\(\*StyleBox[\\\"x\\\", \\\"TI\\\"]\) and \!\(\*StyleBox[\\\"y\\\", \ +\\\"TI\\\"]\). \\n\!\(\*RowBox[{\\\"StreamPlot\\\", \\\"[\\\", \ +RowBox[{RowBox[{\\\"{\\\", RowBox[{RowBox[{\\\"{\\\", \ +RowBox[{SubscriptBox[StyleBox[\\\"v\\\", \\\"TI\\\"], StyleBox[\\\"x\\\", \ +\\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"v\\\", \\\"TI\\\"], \ +StyleBox[\\\"y\\\", \\\"TI\\\"]]}], \\\"}\\\"}], \\\",\\\", \ +RowBox[{\\\"{\\\", RowBox[{SubscriptBox[StyleBox[\\\"w\\\", \\\"TI\\\"], \ +StyleBox[\\\"x\\\", \\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"w\\\", \ +\\\"TI\\\"], StyleBox[\\\"y\\\", \\\"TI\\\"]]}], \\\"}\\\"}], \\\",\\\", \ +StyleBox[\\\"\[Ellipsis]\\\", \\\"TR\\\"]}], \\\"}\\\"}], \\\",\\\", RowBox[{\ +\\\"{\\\", RowBox[{StyleBox[\\\"x\\\", \\\"TI\\\"], \\\",\\\", \ +SubscriptBox[StyleBox[\\\"x\\\", \\\"TI\\\"], StyleBox[\\\"min\\\", \ +\\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"x\\\", \\\"TI\\\"], \ +StyleBox[\\\"max\\\", \\\"TI\\\"]]}], \\\"}\\\"}], \\\",\\\", RowBox[{\\\"{\\\ +\", RowBox[{StyleBox[\\\"y\\\", \\\"TI\\\"], \\\",\\\", \ +SubscriptBox[StyleBox[\\\"y\\\", \\\"TI\\\"], StyleBox[\\\"min\\\", \ +\\\"TI\\\"]], \\\",\\\", SubscriptBox[StyleBox[\\\"y\\\", \\\"TI\\\"], \ +StyleBox[\\\"max\\\", \\\"TI\\\"]]}], \\\"}\\\"}]}], \\\"]\\\"}]\) generates \ +plots of several vector fields. \"\>", "MSG"], "\[NonBreakingSpace]", + ButtonBox[ + StyleBox["\[RightSkeleton]", "SR"], + Active->True, + BaseStyle->"Link", + ButtonData->"paclet:ref/StreamPlot"]}]], "Print", "PrintUsage", + CellChangeTimes->{3.514692575680358*^9}, + CellTags-> + "Info3514667375-7328529",ExpressionUUID->"b34c0a8d-db2f-40c0-b644-\ +c27d30afdb23"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"plot2", "=", + RowBox[{"StreamPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"eqnc", "-", + RowBox[{"nc", "[", "t", "]"}]}], "/.", + RowBox[{"rc", "\[Rule]", "0.6"}]}], "/.", + RowBox[{"rd", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"\[Rho]c", "\[Rule]", "0.02"}]}], "/.", + RowBox[{"\[Rho]d", "\[Rule]", "0.03"}]}], ")"}], ",", + RowBox[{"(", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"eqnd", "-", + RowBox[{"nd", "[", "t", "]"}]}], "/.", + RowBox[{"rc", "\[Rule]", "0.6"}]}], "/.", + RowBox[{"rd", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"\[Rho]c", "\[Rule]", "0.02"}]}], "/.", + RowBox[{"\[Rho]d", "\[Rule]", "0.03"}]}], ")"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"nc", "[", "t", "]"}], ",", "0", ",", "50"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"nd", "[", "t", "]"}], ",", "0", ",", "50"}], "}"}]}], + "]"}]}]], "Input", + CellChangeTimes->{ + 3.514689733772607*^9, 3.5146902218045073`*^9, {3.514690289592782*^9, + 3.514690290589498*^9}, {3.514690448604793*^9, 3.514690496489251*^9}, { + 3.5146910304760017`*^9, 3.514691031274037*^9}, 3.514691255180695*^9, + 3.514691327257372*^9, {3.5146922879068937`*^9, 3.5146922901946363`*^9}, { + 3.620424814931625*^9, 3.620424841270275*^9}, {3.620424974589233*^9, + 3.620424987674798*^9}, {3.6204254997513943`*^9, + 3.6204255091323347`*^9}},ExpressionUUID->"5db764b6-b0ba-401a-a5b9-\ +626464d50d35"], + +Cell[BoxData[ + GraphicsBox[{{}, { + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{50., 5.255627689465548}, {49.07164643991514, + 5.49929454502681}, {48.101654752431905`, 5.768012892194103}, { + 47.16122726915955, 6.042593697561616}, {46.24934810020415, + 6.322803191864825}, {45.98853990724681, 6.407032564076382}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{45.889238795161646`, 6.43910237843306}, {45.36500135567175, + 6.608407605839203}, {44.58598393311282, 6.871537687447511}, { + 43.826982442039586`, 7.138509574582958}, {43.08753418321806, + 7.4092143791227985`}, {42.36717645741425, 7.683543212944289}, { + 41.95989638425604, 7.844802289610991}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{41.86287349110899, 7.88321767792867}, {41.66544656539418, + 7.9613871879246805`}, {40.981881807923834`, 8.242637415941228}, { + 40.316019485769246`, 8.527185008871188}, {39.70688056766348, + 8.824212865066134}, {39.089918510465075`, 9.118531091403003}, { + 38.489733490114446`, 9.415928906407792}, {38.0742600869078, + 9.62991358440455}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{37.9814901997972, 9.677693621027696}, {37.90632550661159, + 9.716406310080501}, {37.3396945599565, 10.019963302421127`}, { + 36.78984065014919, 10.32659988342967}, {36.25676377718965, + 10.636316053106134`}, {35.740463941077884`, 10.949111811450518`}, { + 35.2409411418139, 11.264987158462816`}, {34.75670439677487, + 11.583629558431436`}, {34.40465234828942, 11.823920403928765`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{34.31846359879082, 11.882747976665446`}, {34.286262723338, + 11.904726475644786`}, {33.829616121503285`, 12.228277910102857`}, { + 33.38676459127073, 12.554283861805654`}, {32.54244674561208, + 13.213659316945424`}, {31.75330918636206, 13.882852841064095`}, { + 31.21003027705684, 14.377806997593897`}, {31.077247248736626`, + 14.506056736923023`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{31.00218964042387, 14.578551835299333`}, { + 30.692638150616993`, 14.877535059126219`}, {29.975257805378966`, + 15.62215230541692}, {29.309812325343447`, 16.37682786720651}, { + 28.69413730331939, 17.141603879322957`}, {28.26741617616755, + 17.723705972626668`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{28.205721092727792`, 17.807865942526753`}, { + 28.12606833211576, 17.916522476594224`}, {27.618068132766822`, + 18.67887970316737}, {27.150334054790395`, 19.452211247189897`}, { + 26.722866098186476`, 20.236517108661797`}, {26.33566426295506, + 21.031797287583075`}, {26.160672214451445`, 21.43732678808643}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{26.119328106854564`, 21.533138314643725`}, { + 25.986887720780615`, 21.840057880820073`}, {25.674695643347604`, + 22.66330498523914}, {25.399088030656024`, 23.501538600840274`}, { + 25.160064882705875`, 24.354758727623476`}, {25.077623137676905`, + 24.67623029415256}, {25.000130980593386`, 25.000173926194417`}, { + 24.90713673871171, 25.517801018623775`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{24.888684934653096`, 25.620507955006886`}, { + 24.849004956355706`, 25.841375735399907`}, {24.729767986718073`, + 26.70365873558932}, {24.630530483798537`, 27.542736266356243`}, { + 24.56160354012163, 28.405466030731965`}, {24.52298715568735, + 29.291848028716487`}, {24.518592434839327`, 29.77335905473906}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{24.517640067189014`, 29.877705961018453`}, { + 24.514681330495694`, 30.2018822603098}, {24.538789509441692`, + 31.141564545156765`}, {24.597415137420363`, 32.11689070290223}, { + 24.690558214431714`, 33.12786073354619}, {24.80165046951396, + 34.0386410847478}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{24.814285052363417`, 34.14222463156119}, { + 24.818218740475743`, 34.17447463708866}, {24.97467432311375, + 35.24437486775083}, {25.07876922741073, 35.820598892969294`}, { + 25.19235185283169, 36.40758751827921}, {25.315708318998553`, + 37.0059586209695}, {25.44912474553326, 37.61633007832912}, { + 25.59288725205775, 38.239319767647004`}, {25.59330124435526, + 38.241025736631784`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{25.617910209544327`, 38.34243373772906}, { + 25.747281958193952`, 38.87554556621209}, {25.940101598568962`, + 39.628438210109316`}, {26.150846742815112`, 40.406028023594665`}, { + 26.380551777227023`, 41.210330103819174`}, {26.630251088099318`, + 42.04335954793386}, {26.730898099824202`, 42.36447915704206}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{26.76210739782475, 42.46405407141579}, {26.900979061726613`, + 42.90713145308976}, {27.193770084403532`, 43.803660916437906`}, { + 27.50965854242469, 44.73496303512932}, {27.849678822084716`, + 45.70305290631504}, {28.108387715178683`, 46.414587587559254`}}]}, + {Arrowheads[{{0.017918567746579475`, 1.}}], + ArrowBox[{{28.144045259149596`, 46.51265757997378}, { + 28.216935285765725`, 46.71312916498169}, {28.412055705910014`, + 47.23601123263495}, {28.61516921156907, 47.77136999621915}, { + 28.826524522727077`, 48.319641008522545`}, {29.046370359368215`, + 48.881259822333355`}, {29.27495544147667, 49.45666199043983}, { + 29.493879886714133`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{50., 3.046754492416481}, {49.30691551877229, + 3.1421248170699143`}, {48.549210363966736`, 3.249990429378931}, { + 47.80628351324313, 3.359339012067691}, {47.07786923727012, + 3.4701203299368584`}, {46.36370180671632, 3.582284147787095}, { + 45.87167489311794, 3.662029101277047}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{45.76866777190582, 3.678723915855624}, {45.6633042957297, + 3.695800635187409}, {44.9762365082879, 3.8106364130514456`}, { + 44.30228780980407, 3.9267359231968193`}, {43.641247565691394`, + 4.044043607441145}, {42.99290514136307, 4.162503907602034}, { + 42.35704990223227, 4.282061265497096}, {41.73347121371217, + 4.4026601229439475`}, {41.66063423036925, 4.417142028088762}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{41.55828637224961, 4.437491470158391}, {41.12195844121596, + 4.524244921760202}, {40.522300950156804`, 4.646760103763471}, { + 39.934288105947914`, 4.770150110771365}, {39.35770927400245, + 4.8943593846015}, {38.792353819733584`, 5.019332367071488}, { + 38.23801110855452, 5.145013499998943}, {37.694470505878414`, + 5.271347225201477}, {37.479558112687755`, 5.323145855371648}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{37.37811185657169, 5.3475966421536025`}, { + 36.638953087687874`, 5.525750219702228}, {35.62389307929084, + 5.782090005760034}, {34.64746323451677, 6.039917740144682}, { + 33.708100336221975`, 6.2987927097723135`}, {33.34043127306272, + 6.404343795902534}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{33.240131355765655`, 6.433138073883139}, { + 32.804241167262745`, 6.558274201559078}, {31.93432251049537, + 6.817921502421122}, {31.096781148776145`, 7.077293899274592}, { + 30.290053864961354`, 7.335950679035637}, {29.512577441907304`, + 7.593451128620401}, {29.25733037242637, 7.680680108899937}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.158586035090803`, 7.714425326314875}, { + 28.511300778753974`, 7.9356307371157095`}, {27.5533564203355, + 8.273029929405732}, {26.636332618351013`, 8.605011992601364}, { + 25.783542939708855`, 8.937731817963966}, {25.240519622252435`, + 9.151871130418568}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{25.143443822445573`, 9.190152626550253}, { + 24.960820950146804`, 9.262169306231199}, {24.174196020417014`, + 9.579916239625828}, {23.42366815051949, 9.890972618147854}, { + 22.709237340454223`, 10.195338441797277`}, {22.02708273344312, + 10.492132512118648`}, {21.373383472708078`, 10.780473630656516`}, { + 21.298560537511758`, 10.813967845760393`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{21.203316680414655`, 10.85660341236257}, { + 20.748139558249093`, 11.060361797410883`}, {20.151350990066174`, + 11.331797012381745`}, {19.474857884757967`, 11.643480355238204`}, { + 18.831665723816883`, 11.941936884140334`}, {17.889821661434798`, + 12.37886126421555}, {17.410684364456777`, 12.599672002780904`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{17.315912879115317`, 12.643347504156335`}, { + 17.015519686801376`, 12.781783904480829`}, {16.20218071411488, + 13.150189024441007`}, {15.44322565757358, 13.483560843600925`}, { + 14.54590587797527, 13.85748882834175}, {13.717912173088807`, + 14.174718438279013`}, {13.58614702264218, 14.222698900770094`}, { + 13.470835248789541`, 14.263855968418307`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{13.371651504542532`, 14.296265258562856`}, {13.017694469461, + 14.410053144819937`}, {12.596846456225402`, 14.532352313975206`}, { + 11.859950820294307`, 14.723971973931429`}, {11.173288862944805`, + 14.855946636067003`}, {10.531131397563858`, 14.930933414451436`}, { + 9.92774923753843, 14.951589423154232`}, {9.35975694271045, + 14.920495792063443`}, {9.276367203284325, 14.908390923012659`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{9.173098293260882, 14.893400390107127`}, {8.821060720795387, + 14.842298554977567`}, {8.066659539361678, 14.637970703786886`}, { + 7.366263444900198, 14.344221402127282`}, {6.711521814512744, + 13.973892822186267`}, {6.100322506916809, 13.537647643011448`}, { + 5.529251860062621, 13.0468851667233}, {5.514332818344818, + 13.031918620930668`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{5.4406627207951255`, 12.958013948674845`}, { + 4.996713931940981, 12.512651571945206`}, {4.500855089220485, + 11.945702274813412`}, {4.0404728672678, 11.35632536722847}, { + 3.670711747917073, 10.836353765561283`}, {3.325970938073047, + 10.311000265948131`}, {3.0055039585738204`, 9.785939084975231}, { + 2.9247666496529856`, 9.64479825776259}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{2.872952616238303, 9.55421961902517}, {2.708564330257488, + 9.266844439228795}, {2.4343708708490444`, 8.756721478898363}, { + 2.18212256772314, 8.257050173375378}, {1.9510431961923551`, + 7.771216968048902}, {1.7403565315692708`, 7.302608308308005}, { + 1.3754465083471559`, 6.4199885973137185`}, {1.1337458433457925`, + 5.765980003531753}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{1.0975722251644244`, 5.668099192328073}, { + 1.0779628686587033`, 5.615038983854077}, {0.8387603087711567, + 4.891910419754798}, {0.648172892642414, 4.247745960293024}, { + 0.49777222254129183`, 3.6795828400670922`}, {0.38010712289285203`, + 3.1808485247222476`}, {0.21821852342122994`, 2.3670752012957825`}, { + 0.12319313918665568`, 1.7547993248906482`}, {0.10716134137378217`, + 1.6211922973337174`}}]}, + {Arrowheads[{{0.006901193386245247, 1.}}], + ArrowBox[{{0.09472918763697008, 1.5175842599636071`}, { + 0.07030775321242456, 1.3140590346442143`}, {0.03980150451054112, + 0.982829355931863}, {0.022364466090688092`, 0.7345808087588179}, { + 0.012475050897473553`, 0.5488158092569115}, {0.0070971341252142545`, + 0.41482425570352494`}, {0.004042384116633057, 0.31351763341181166`}, { + 0.002296973446982666, 0.23693643132798137`}, {0.0012989393312688657`, + 0.1790536109198805}, {0.000576397485540716, 0.12064568500470597`}, { + 0.000215303600311363, 0.08121294442028855}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{50., 9.467092475873057}, {49.807348435733154`, + 9.57162462921928}, {49.0682298090966, 9.998001889687844}, { + 48.35637340268402, 10.434920491978248`}, {47.67177921649541, + 10.882380436090495`}, {47.111981052667645`, 11.271838386982596`}, { + 46.57021741408454, 11.669178906329964`}, {46.49514432783939, + 11.726867108256133`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{46.41240090003064, 11.790449409320821`}, {46.09485542211006, + 12.034459993769223`}, {45.63372685980081, 12.406100191279108`}, { + 45.18671336128773, 12.784203076096052`}, {44.753696560701755`, + 13.168872225456479`}, {44.33455809217379, 13.560211216596821`}, { + 43.92917958983478, 13.958323626753511`}, {43.53744268781565, + 14.363313033162978`}, {43.32671368808493, 14.592850009817711`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{43.25614274523294, 14.669719547862398`}, { + 43.159229020247324`, 14.77528301306165}, {42.79423229500632, + 15.193942246371215`}, {42.44221455678894, 15.619143012036906`}, { + 42.103159944955785`, 16.051204285830465`}, {41.77705259886748, + 16.49044504352364}, {41.463876657884605`, 16.937184260888166`}, { + 41.163616261367785`, 17.391740913695795`}, {40.87625554867761, + 17.854433977718266`}, {40.779597110659154`, 18.020351310255176`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{40.72706890854821, 18.110517666714856`}, { + 40.601778659174705`, 18.325582428727333`}, {40.221572001861695`, + 19.033996670486225`}, {39.868795929002914`, 19.762457386972137`}, { + 39.543577668418564`, 20.511926077563757`}, {39.24468735117998, + 21.273108248267175`}, {39.02431433389426, 21.913258616073758`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{38.99034756293841, 22.011926961175188`}, {38.97392737140676, + 22.059625140280357`}, {38.73097965954838, 22.8690730051566}, { + 38.51584421560486, 23.701451842895906`}, {38.328521039576174`, + 24.556761653498278`}, {38.169912156873075`, 25.437861075016585`}, { + 38.07895536317184, 26.07935333348483}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{38.06430598757423, 26.182671190841734`}, {38.04091959290628, + 26.3476087455037}, {37.94154334767579, 27.28600466495962}, { + 37.87178342118161, 28.25304883338435}, {37.83923092998787, + 28.834394700560594`}, {37.817533088819154`, 29.42701002563941}, { + 37.82903198982552, 30.345931668700178`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{37.831161711623764`, 30.450252390569048`}, {37.8730242934231, + 31.452433909680416`}, {37.92994341213175, 32.463528122199165`}, { + 38.01781164150515, 33.51246227009787}, {38.07335167269113, + 34.0511193198147}, {38.136628981543296`, 34.599236353376526`}, { + 38.13819831135887, 34.61155807882468}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{38.15138228174712, 34.715073134633116`}, {38.20764356806165, + 35.15681337078334}, {38.286395432246195`, 35.723850372035145`}, { + 38.373748505041405`, 36.30197529694237}, {38.47056671739176, + 36.892816085315474`}, {38.576850069297265`, 37.496372737154445`}, { + 38.69259856075791, 38.11264525245929}, {38.8178121917737, + 38.741633631229995`}, {38.836633570134346`, 38.831311895202624`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{38.85806749072204, 38.93343814502343}, {38.95249096234463, + 39.38333787346657}, {39.096634872470716`, 40.03775797916902}, { + 39.250243922151945`, 40.704893948337336`}, {39.39441174651897, + 41.351147680618716`}, {39.57874532800328, 42.0646746932398}, { + 39.7732552602604, 42.79218144770993}, {39.828514777014036`, + 42.9921850001184}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{39.85630504749751, 43.09276772587525}, {39.97829714889914, + 43.53429988322069}, {40.19422659952834, 44.29166193896368}, { + 40.42139921775683, 45.064899554130484`}, {40.66017060919343, + 45.85464466791269}, {40.91089637944697, 46.66152921950189}, { + 41.04903944587308, 47.0924503155271}}]}, + {Arrowheads[{{0.014192803458930205`, 1.}}], + ArrowBox[{{41.08089511278807, 47.19182033283425}, {41.23672796035694, + 47.67792262669803}, {41.408047187287615`, 48.1986055906829}, { + 41.585193469766295`, 48.72799998297205}, {41.76833538121613, + 49.26639624460025}, {41.95764149506027, 49.814084816602296`}, { + 42.02290995321195, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{4.319580651254556, 50.}, {4.327294726395148, + 49.961050346695416`}, {4.508291058260853, 49.090026080138}, { + 4.688673087110341, 48.26216167065276}, {4.868220134920151, + 47.475773065346814`}, {5.046400967307639, 46.728234957370844`}, { + 5.222797279475323, 46.01726431404149}, {5.245261065603621, + 45.930326289162316`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{5.271366838167764, 45.82929326241833}, {5.397357787777473, + 45.34169049371491}, {5.570031208568362, 44.70034285474721}, { + 5.74076625820226, 44.09205075549455}, {5.909511653033442, + 43.51564355431306}, {6.076216109416176, 42.96995060955888}, { + 6.240828343704737, 42.453801279588134`}, {6.452787708843304, + 41.82718241251142}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.48622434252224, 41.72833315665968}, {6.56264038219542, + 41.502423194270456`}, {6.8743513734954655`, 40.65153862457891}, { + 7.176667803504246, 39.89541568114387}, {7.470296158121136, + 39.22832247459571}, {7.754946766863427, 38.64214477799765}, { + 8.031126884354078, 38.130674234466646`}, {8.170608497690745, + 37.91923976141991}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{8.228070877858805, 37.83213488945718}, {8.565683139811934, + 37.320362269449696`}, {9.03648788685305, 36.814490656654584`}, { + 9.504124087901678, 36.509899769853384`}, {9.980663685682348, + 36.40305888896133}, {10.226230151583158`, 36.42459116611594}, { + 10.479717559965424`, 36.497822658764164`}, {10.849610640874653`, + 36.68974939129246}, {11.247205725572076`, 36.99443201211079}, { + 11.519955477592566`, 37.28075142271622}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{11.591930796959485`, 37.3563076088048}, {11.950943499452919`, + 37.73318166502781}, {12.008786234130866`, 37.80229313541391}, { + 12.06742837982083, 37.87358400008452}, {12.334747992595185`, + 38.226164684386646`}, {12.621569486823308`, 38.62619322141192}, { + 12.919844979548898`, 39.05283114060843}, {13.241028469269423`, + 39.53268782414744}, {13.588734824614159`, 40.071956126263174`}, { + 13.966578914212386`, 40.67682890118988}, {14.010013795312366`, + 40.74825387626535}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{14.064233388003805`, 40.83741339411172}, { + 14.378813248186738`, 41.354713271624746`}, {14.833092344757956`, + 42.118942058422704`}, {15.246751280600575`, 42.82692717567917}, { + 15.698379505284956`, 43.61029155354303}, {16.171574819420517`, + 44.44022392736655}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{16.22310245881298, 44.53096566157733}, {16.45845409577451, + 44.94664303451333}, {16.736462380053844`, 45.43967246921526}, { + 17.02894101591767, 45.960222537391246`}, {17.337924369326622`, + 46.51182656960474}, {17.664553437361693`, 47.09646996590635}, { + 18.009969217103894`, 47.71613812634668}, {18.263697901959542`, + 48.172196966622565`}}]}, + {Arrowheads[{{0.009516783655673752, 1.}}], + ArrowBox[{{18.31443075234337, 48.26338557197518}, {18.37531270563422, + 48.372816450976316`}, {18.761724900033666`, 49.06849033984588}, { + 19.170346797383242`, 49.80514519300596}, {19.278311967134666`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{48.70808172879087, 4.093956838965128}, {48.015600704368715`, + 4.2266725384361745`}, {47.33631377568077, 4.361166718624578}, { + 46.67001711655772, 4.497388816191737}, {46.01650690083028, + 4.635288267799045}, {45.375579302329086`, 4.774814510107904}, { + 44.747030494884804`, 4.915916979779714}, {44.62195400884334, + 4.9448595216944895`}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{44.520289107875335`, 4.968384652201853}, {44.13065665232814, + 5.058545113475872}, {43.526253948489796`, 5.202648347857767}, { + 42.933618557200425`, 5.348176119586805}, {42.35254665229069, + 5.495077865324387}, {41.782834407591295`, 5.643303021731904}, { + 41.224277996932926`, 5.792801025470751}, {40.67667359414625, + 5.94352131320233}, {40.47622268155968, 6.000234620228982}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{40.37581290252111, 6.028643423928659}, {40.139817373061945`, + 6.095413321588043}, {39.459911962069974`, 6.293701864208629}, { + 38.796572043056074`, 6.4936692636423645`}, {38.14948481624552, + 6.695223355905408}, {37.51833748186357, 6.898271977013918}, { + 36.902817240135484`, 7.1027229629840525`}, {36.393520684589326`, + 7.277318806173719}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{36.29483513929001, 7.311234473907843}, {35.717406835542015`, + 7.515463373573829}, {35.146891073127144`, 7.723568470225793}, { + 34.59075120426723, 7.93270727580401}, {34.048674429187514`, + 8.142787626324644}, {33.520347948113276`, 8.353717357803855}, { + 33.00545896126979, 8.565404306257795}, {32.405245970933784`, + 8.823052852566216}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{32.309356023355036`, 8.864214750087669}, { + 32.014742271176104`, 8.990681198154508}, {31.07402196070858, + 9.417880990144054}, {30.17918584270716, 9.845633102427938}, { + 29.326707107816212`, 10.272797234454115`}, {28.552052516926214`, + 10.67950785752588}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{28.460229845761305`, 10.729074097524581`}, { + 27.742324461400884`, 11.123793985729197`}, {27.007171886894103`, + 11.546842818976005`}, {26.30787936953296, 11.967736099960934`}, { + 25.64282257782625, 12.386081935682936`}, {25.010377180282784`, + 12.801488433140966`}, {24.888128885413025`, 12.885001004092336`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{24.80196403156696, 12.94386357127988}, {24.407850358601106`, + 13.213097969285446`}, {23.83293783513804, 13.620222277448084`}, { + 23.28459808938979, 14.022723499199762`}, {22.761789600852552`, + 14.420463776111358`}, {22.26347084902251, 14.813305249753759`}, { + 21.788600313395868`, 15.201110061697849`}, {21.477426391746473`, + 15.464257208364062`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{21.39774665257445, 15.531639127449974`}, { + 21.336136473468812`, 15.583740353514509`}, {20.905037808737546`, + 15.96105826677462}, {20.49376146727513, 16.332634273150287`}, { + 20.100946899490324`, 16.69814490609498}, {19.367630816952396`, + 17.41105498866324}, {18.6989450251215, 18.099958388422962`}, { + 18.39686698830514, 18.42919797856758}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{18.326319375369238`, 18.506088928381377`}, { + 18.088744987995376`, 18.76502497931771}, {17.602254806405167`, + 19.320908039731595`}, {17.15298803393434, 19.85857246085529}, { + 16.73682398254914, 20.378456172700123`}, {16.3514733811197, + 20.88080246971684}, {15.994684674556558`, 21.366052562182006`}, { + 15.71693624414, 21.759880316442757`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{15.65700704782492, 21.84530396883594}, {15.358596897028146`, + 22.287009177393045`}, {15.075570069813962`, 22.723859013899304`}, { + 14.594829123835861`, 23.509699672907118`}, {14.179832089842215`, + 24.24642089136489}, {13.823430137262502`, 24.938746513129637`}, { + 13.580018479139605`, 25.459686307046468`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{13.535844191913988`, 25.554226331387117`}, { + 13.518474435526207`, 25.591400382058378`}, {13.480966901733915`, + 25.67640279313711}, {13.444284613175178`, 25.760778393771126`}, { + 13.275610911300683`, 26.189621036069482`}, {13.127021215791121`, + 26.60550237872598}, {12.867586708200312`, 27.414259588961812`}, { + 12.680065344170375`, 28.1846094265204}, {12.558712089105702`, + 28.93201935880526}, {12.513830615561275`, 29.576719947463232`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{12.506583638809852`, 29.680819251890238`}, { + 12.49834548964454, 29.799156267074707`}, {12.523880352172746`, + 30.686027996236586`}, {12.63837034246668, 31.627799152088937`}, { + 12.852545111510091`, 32.661841593843}, {13.001451961853148`, + 33.22796485133233}, {13.166744083068592`, 33.78194477868995}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{13.197795621150187`, 33.88155821706151}, { + 13.402221224260959`, 34.5018913934377}, {13.659722031857633`, + 35.22418999059383}, {13.964043211601997`, 36.0216307440609}, { + 14.325835946904315`, 36.91495736287581}, {14.53050014474458, + 37.4021432279129}, {14.691507637219605`, 37.777359731358345`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{14.7326568788365, 37.87325511064523}, {14.752191427700177`, + 37.91877898663597}, {14.991796194513057`, 38.466690781494705`}, { + 15.250200843925166`, 39.047704754938785`}, {15.63541493674554, + 39.89663309831635}, {16.070615644046338`, 40.83445138669106}, { + 16.30887934079907, 41.340249155511934`}, {16.46576757537701, + 41.67024458702501}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{16.510572904798224`, 41.76448717988874}, {16.56194172637851, + 41.87253528489361}, {16.83057014585352, 42.43273173293991}, { + 17.115531944292986`, 43.02226045775469}, {17.36145691760367, + 43.527251190701676`}, {17.621609851328984`, 44.05767042414354}, { + 17.896896837752735`, 44.6151339978141}, {18.18822396915872, + 45.20125775144718}, {18.344606891439625`, 45.513949043146454`}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{18.39128309078776, 45.607279189769265`}, { + 18.496497337830743`, 45.81765752477659}, {18.822623036052608`, + 46.46594915753615}, {19.167507156108115`, 47.14774848945969}, { + 19.532055790281067`, 47.864671360281}, {19.839183610360138`, + 48.46567286019579}, {20.162741532737172`, 49.09575387135}, { + 20.28266629551243, 49.32818672560848}}]}, + {Arrowheads[{{0.003123479124210378, 1.}}], + ArrowBox[{{20.330513472909036`, 49.42092200190289}, { + 20.503760459119256`, 49.75670162376452}, {20.629867991294255`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{50., 1.7511359116089673`}, {49.960134284961434`, + 1.7540651154278804`}, {49.22221194306671, 1.8099221158901446`}, { + 48.49665648317355, 1.866465206294774}, {47.783278664612, + 1.923666206718645}, {47.08188924671209, 1.9814969372386337`}, { + 46.392298988803866`, 2.039929217931617}, {45.839598440772846`, + 2.0880315798393907`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{45.73564016087489, 2.0970792256591313`}, {45.71431865021737, + 2.098934868874471}, {45.04775899028265, 2.158485710144072}, { + 44.392430768329746`, 2.2185535618172976`}, {43.74799858866116, + 2.2791138280660452`}, {43.11415247384506, 2.340141289741341}, { + 42.49074131060996, 2.401606831938752}, {41.87761398568441, + 2.463481339753843}, {41.58055902877077, 2.494149882712226}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{41.476759504917254`, 2.5048663514405587`}, { + 41.27461938579694, 2.5257356982821815`}, {40.68160639767606, + 2.588340792619332}, {40.098423908050314`, 2.651267507860863}, { + 39.52492080364824, 2.7144867291023376`}, {38.96094597119837, + 2.7779693414393227`}, {38.406348297429226`, 2.841686229967386}, { + 37.86097666906934, 2.9056082797820912`}, {37.32867005149847, + 2.9692294824105367`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{37.22509711996872, 2.9819506099958533`}, {36.27870692373057, + 3.098314247901725}, {35.26722024390743, 3.2272769265000725`}, { + 34.28892882092955, 3.3563449767732725`}, {33.34257143554012, + 3.4852749694533856`}, {33.086097904959004`, 3.5212893298954975`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{32.98276049097098, 3.535800109491692}, {32.426984021354585`, + 3.613842993904198}, {31.54100251198838, 3.741825139489496}, { + 30.68346284105696, 3.8689974955730637`}, {29.85320094217578, + 3.9951361515186856`}, {29.04905274896027, 4.120017196690148}, { + 28.854330464681183`, 4.150854827258613}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{28.75126367556069, 4.167177230102966}, {28.269854195025882`, + 4.243416720451237}, {27.20679901243413, 4.414611358620885}, { + 26.18584056161639, 4.581255495348989}, {25.20487771691266, + 4.742993054384105}, {24.63227596365705, 4.84267479744279}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{24.529470880009804`, 4.860571686292651}, {24.28422135970308, + 4.903266106156867}, {23.39410554313743, 5.057030237105138}, { + 22.539783081365762`, 5.205175637857531}, {21.72125397438806, + 5.347702308414046}, {20.93851822220433, 5.484610248774683}, { + 20.41711286864374, 5.57555160246802}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{20.314313525703067`, 5.593481436410019}, { + 20.188212975061155`, 5.615475370109662}, {19.466975383205117`, + 5.739873583589205}, {18.774805446636215`, 5.857804889213312}, { + 18.11170316535444, 5.969269286981984}, {17.511607102258267`, + 6.068314585996544}, {16.93367662775631, 6.161354991358417}, { + 16.331925585807774`, 6.255110053401209}, {16.196421903476818`, + 6.275379995241686}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{16.093218951584223`, 6.2908180836880145`}, { + 15.752588791268925`, 6.34177281362546}, {15.195666244139757`, + 6.421343272031169}, {14.66115794442027, 6.493821428618338}, { + 13.651403335580103`, 6.6179793006386465`}, {12.715344213118183`, + 6.71472489398798}, {11.948538853035643`, 6.775970877649539}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{11.844518869704418`, 6.784279121867986}, { + 11.762456164560819`, 6.7908336027833345`}, {10.883040045659525`, + 6.836382153963504}, {10.736207864590448`, 6.841656261576708}, { + 10.591389697545472`, 6.846056752660993}, {10.23713261896957, + 6.849706550621802}, {9.894701809328478, 6.848097646452643}, { + 9.117360737405736, 6.830890765822442}, {8.400166188720421, + 6.786857363461106}, {7.738128133578678, 6.718574564403359}, { + 7.677794488865157, 6.709704537825551}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{7.5745529916176455`, 6.694526359400124}, {7.126256542286653, + 6.6286194936839244`}, {6.561285704708233, 6.51910031378486}, { + 6.037337342598416, 6.3938117171738655`}, {5.30157012415421, + 6.167715962877219}, {4.649703319574725, 5.915600277989436}, { + 4.070293411341426, 5.6461960322187}, {3.632676908492608, + 5.40620584902936}}]}, + {Arrowheads[{{0.009018488526614476, 1.}}], + ArrowBox[{{3.5420743658215295`, 5.354565090028833}, {2.704278109852364, + 4.788692615883016}, {2.0432355837584906`, 4.221255216724478}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{6.520942316078481, 38.929339855472676`}, {6.747524110405924, + 38.14081512371605}, {6.961001825179257, 37.41764365197272}, { + 7.161375460398483, 36.75982544024268}, {7.349055095733886, + 36.1569686465526}, {7.5244508108557495`, 35.598681428929154`}, { + 7.736023597766242, 34.93630054198494}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{7.767774354128731, 34.83689695389763}, {7.838390480458867, + 34.61581572188215}, {8.016510119192894, 34.06190121194002}, { + 8.17713297780455, 33.55444364059277}, {8.445888354660749, + 32.678899313682955`}, {8.651342670652985, 31.94788438137426}, { + 8.800181985406788, 31.320100483888233`}, {8.884484583035121, + 30.819696170423114`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{8.901820243325743, 30.716794961797998`}, {8.906353824221085, + 30.689884480990816`}, {8.950274465078182, 30.11185991349578}, { + 8.933361050030085, 29.552482820019254`}, {8.857030721128801, + 28.97820923917736}, {8.719082795565011, 28.360662271193995`}, { + 8.5173165905294, 27.67146501629304}, {8.305589859238136, + 27.049375368300986`}, {8.16008913796415, 26.655289079102204`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{8.123946331127387, 26.557396886521886`}, {8.04838929278722, + 26.352751901936166`}, {7.744418339148343, 25.57122665446563}, { + 7.5747323371208175`, 25.146220186483145`}, {7.393337350207783, + 24.69723191209402}, {7.004260226696846, 23.74466442495637}, { + 6.794018153296074, 23.23298003055406}, {6.573963473675769, + 22.697986476192686`}, {6.568319785750554, 22.684272491493292`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{6.528609454919318, 22.587772369871306`}, {6.513581441497226, + 22.551249580272515`}, {6.266531700514734, 21.949324744657638`}, { + 6.011151532141602, 21.32452646794287}, {5.615226128836256, + 20.350135622059245`}, {5.412497157698578, 19.84697224659695}, { + 5.206590673570895, 19.33316356945433}, {4.998904656112411, + 18.811128860566395`}, {4.962474019194867, 18.71870887957374}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{4.924206026373197, 18.621627755869785`}, {4.790837084982328, + 18.28328738986814}, {4.582387960180644, 17.749639157359567`}, { + 4.3735572817073605`, 17.210184163040676`}, {4.162525160380449, + 16.661346305394304`}, {3.9596043015647355`, 16.12339015968438}, { + 3.7577578004230445`, 15.582488133377872`}, {3.557713612628187, + 15.040070667081643`}, {3.4416454168170247`, 14.719900787821603`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{3.4060807892399114`, 14.621797061493174`}, { + 3.2274111848916682`, 14.128943483027241`}, {2.909215559479851, + 13.229542311586256`}, {2.6070886820923276`, 12.350413885049615`}, { + 2.3249924984286907`, 11.500104935708245`}, {2.147390147086162, + 10.947112548534534`}, {2.060833320365299, 10.67086336691861}}]}, + {Arrowheads[{{0.0034302695058375954`, 1.}}], + ArrowBox[{{2.0296327720313254`, 10.57128571060013}, { + 1.9787952509239446`, 10.409035959386559`}, {1.8193978369665709`, + 9.886948464805657}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{50., 6.874827243658772}, {49.203620389034064`, + 7.163263041922101}, {48.333322841780536`, 7.49686322046547}, { + 47.49223374284091, 7.8382770728481885`}, {46.68035309221518, + 8.187504599070254}, {46.13094238141069, 8.437118439378569}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{46.035936794583485`, 8.480282340104056}, {45.89518917003137, + 8.544228226829274}, {45.1342502564175, 8.908130383822861}, { + 44.39753635137357, 9.27921107005101}, {43.685047454899575`, + 9.657470285513723}, {42.996783566995525`, 10.042908030211}, { + 42.34638784663161, 10.427457718877667`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{42.25769063850247, 10.482422660339001`}, {41.69293081689724, + 10.835319107309243`}, {41.077341954703, 11.242292439710209`}, { + 40.48403073301128, 11.65633346288698}, {39.911049783754635`, + 12.077331338380796`}, {39.35839910693308, 12.50528606619166}, { + 38.86537331414647, 12.90809351978114}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{38.785493966967316`, 12.975223933688156`}, {38.3140885705952, + 13.382066078764527`}, {37.82242871107889, 13.83089136352653}, { + 37.351099123997656`, 14.286673500605577`}, {36.90009980935151, + 14.74941249000167}, {36.427632965334816`, 15.268065437920663`}, { + 35.977437968591566`, 15.79550532888168}, {35.85931988760107, + 15.942778373419962`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{35.79403123560978, 16.024182155736156`}, {35.52930710200576, + 16.35424787295483}, {35.10448668176217, 16.922698621587035`}, { + 34.70266314735557, 17.50114935904269}, {34.323522938280746`, + 18.089891869586193`}, {33.96657014313624, 18.688693750370863`}, { + 33.63145473123757, 19.297741948238876`}, {33.52122594952762, + 19.515902511305697`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{33.474166806511974`, 19.609040156288028`}, { + 33.31808196315501, 19.917957271987934`}, {33.026357099458814`, + 20.55026053041572}, {32.73390691361097, 21.25154698730158}, { + 32.46655059539791, 21.96949424418804}, {32.22438463830975, + 22.705098267695945`}, {32.00647627194189, 23.44873138049053}, { + 31.992763310045042`, 23.503343362304825`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{31.967349832051884`, 23.604552744234137`}, { + 31.81419248740453, 24.21450310970032}, {31.64729205097233, + 24.999923538773224`}, {31.505774962645294`, 25.804992667709243`}, { + 31.38964122242342, 26.629710496508377`}, {31.299789965554968`, + 27.47707453405408}, {31.282618054763265`, 27.716284647706317`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{31.275146334243594`, 27.820368062555648`}, { + 31.23712032728819, 28.350082289229803`}, {31.201632307623083`, + 29.248733762035556`}, {31.193325906559647`, 30.17302895247133}, { + 31.196237980568633`, 30.68944518677864}, {31.207823904826466`, + 31.214772490868395`}, {31.261258053382626`, 31.99034278318651}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{31.268430496134407`, 32.09444724956137}, { + 31.280624910293685`, 32.27144315217633}, {31.3392793354549, + 32.82572313182294}, {31.389032191645075`, 33.3696252518725}, { + 31.49698521092545, 34.33338576344629}, {31.634158226167248`, + 35.33350954852206}, {31.779002991315153`, 36.23576934593132}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{31.795543296346978`, 36.338801390284885`}, { + 31.80055123737047, 36.36999660709981}, {31.89470524145762, + 36.90187636395193}, {31.996164244535123`, 37.44284693917954}, { + 32.10586027333454, 37.9946721297735}, {32.22472535458742, + 38.55911573272466}, {32.35275948829376, 39.136177748033035`}, { + 32.48996267445358, 39.725858175698605`}, {32.636334913066854`, + 40.32815701572138}, {32.65990111511854, 40.42132368622584}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{32.685490481910925`, 40.52248874027805}, { + 32.791876204133594`, 40.94307426810136}, {32.95658654765381, + 41.57060993283855}, {33.13046594362748, 42.21076400993294}, { + 33.29267330664639, 42.8263650157106}, {33.49789198619859, + 43.51494439793041}, {33.71306370887791, 44.21754049283371}, { + 33.81448092796259, 44.54012309646097}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{33.84577779000505, 44.639670523753274`}, {33.93858047002119, + 44.93485245058366}, {34.17483426496527, 45.66757942134339}, { + 34.422217089046974`, 46.41642055527606}, {34.68112093760313, + 47.18207500254481}, {34.95193780597058, 47.96524191331279}, { + 35.17564521405926, 48.595935001149904`}}]}, + {Arrowheads[{{0.006656836429678303, 1.}}], + ArrowBox[{{35.210529262610564`, 48.694282787148836`}, { + 35.29346894313344, 48.928112697656154`}, {35.6569807278478, + 49.92446064885173}, {35.68510583913165, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{50., 14.317042278784916`}, {49.79846536476008, + 14.537376612102017`}, {49.40644030887509, 14.990385375837368`}, { + 49.028918643930055`, 15.452469502978406`}, {48.665968349402526`, + 15.924071796750399`}, {48.31765740477005, 16.405635060378618`}, { + 47.98405378951019, 16.897602097088335`}, {47.665225483100485`, + 17.40041571010482}, {47.51229945365775, 17.659045986922834`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{47.45918741805998, 17.7488696782792}, {47.36124046501849, + 17.914518702653346`}, {46.974658029572694`, 18.62681614545136}, { + 46.61517531489776, 19.361681432778937`}, {46.28306297024403, + 20.120135742567584`}, {45.97570471952488, 20.892307688146037`}, { + 45.747425333746826`, 21.54770412339392}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{45.71310149216061, 21.64624882265769}, {45.696934760453466`, + 21.692663956877354`}, {45.446076469903936`, 22.518651603932764`}, { + 45.2231298478763, 23.370270629312262`}, {45.02809489437055, + 24.247521033015854`}, {44.86210358164024, 25.153329884018632`}, { + 44.78154217075229, 25.709302108225703`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{44.76657776427871, 25.81257480739211}, {44.72628788193894, + 26.090624251295694`}, {44.620647795266635`, 27.059404134847036`}, { + 44.545183321623334`, 28.059669534672665`}, {44.50654835123847, + 28.70981216361135}, {44.480885425224315`, 29.374275143590665`}, { + 44.48709091384877, 29.973461198971894`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{44.48817157281706, 30.077806855471895`}, {44.49117162165552, + 30.367483871780426`}, {44.530404031511395`, 31.395478307774827`}, { + 44.58594872962269, 32.4513471914469}, {44.625734967197104`, + 32.99441429266528}, {44.67353046378401, 33.547569833471904`}, { + 44.72933521938342, 34.110813813866756`}, {44.74399742622041, + 34.24254535558632}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{44.75554082311682, 34.34625617393385}, {44.79314923399534, + 34.684146233849845`}, {44.864972507619754`, 35.267567093421164`}, { + 44.944805040256675`, 35.86107639258071}, {45.03351531846789, + 36.46626178265941}, {45.13197182881522, 37.08471091498816}, { + 45.24017457129864, 37.71642378956696}, {45.35812354591816, + 38.36140040639582}, {45.37962828448109, 38.472252545588915`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{45.39950138644366, 38.57469396139623}, {45.48581875267378, + 39.01964076547473}, {45.62326019156551, 39.691144866803704`}, { + 45.77044786259332, 40.37591271038272}, {45.92738176575725, + 41.0739442962118}, {46.07566535677869, 41.75314698560655}, { + 46.26356793835725, 42.497726228657335`}, {46.30310678749583, + 42.649041366727204`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{46.32948814192834, 42.75000278506376}, {46.46190878508551, + 43.256776460554455`}, {46.6710339134703, 44.03090130459605}, { + 46.891289340018425`, 44.82070438408026}, {47.12302108123667, + 45.62678932230521}, {47.366575153631864`, 46.44975974256904}, { + 47.463059792993334`, 46.76686699581841}}]}, + {Arrowheads[{{0.015764013498501508`, 1.}}], + ArrowBox[{{47.49343530465901, 46.866699416130004`}, {47.62229757371081, + 47.29021926816991}, {47.78953620961886, 47.82755288342334}, { + 47.96255904674318, 48.3734357558464}, {48.14153700647821, + 48.92815846373074}, {48.32664101021842, 49.49201158536796}, { + 48.49624482199345, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{36.66146237085959, 8.263914813368329}, {35.71546705206069, + 8.667343199075988}, {34.81159710940318, 9.075345179120824}, { + 33.948178062770246`, 9.487460304503008}, {33.1232031285105, + 9.902981563513073}, {32.88160788488025, 10.03116467702101}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{32.7894276842507, 10.080072697489191`}, {32.33478636062148, + 10.321291603608696`}, {31.58143453545975, 10.742064464540771`}, { + 30.86165442938186, 11.16497418606019}, {30.173952818744354`, + 11.589694807917848`}, {29.516836479903773`, 12.015900369864646`}, { + 29.21082587198215, 12.224137670834732`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.12455473587262, 12.282844356387516`}, { + 28.888812189216672`, 12.443264911651475`}, {28.288386723039608`, + 12.871462473029224`}, {27.812745077771755`, 13.224225683822695`}, { + 27.352560046544344`, 13.57668358637938}, {26.907364449599033`, + 13.928775227887105`}, {26.476691107177487`, 14.280439655533701`}, { + 25.82647979178595, 14.837166637098147`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{25.7472144643065, 14.905035567499304`}, {25.65704246687232, + 14.982243057994816`}, {24.929742693607217`, 15.686807477903953`}, { + 24.241844748103517`, 16.387224929881725`}, {23.60269222552805, + 17.084714470171555`}, {23.0122851258808, 17.77927609877344}, { + 22.886893790914343`, 17.939385035401497`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{22.822553033364425`, 18.02154007646487}, { + 22.470623449161778`, 18.470909815687385`}, {21.972560967103952`, + 19.159892670674193`}, {21.512951451440298`, 19.846501713494664`}, { + 21.091794902170815`, 20.5307369441488}, {20.709091319295503`, + 21.212598362636598`}, {20.554650334885732`, 21.517176239641298`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{20.507457695744282`, 21.61024631359145}, {20.32860457317984, + 21.96296812881766}, {19.988119739213047`, 22.712820832827653`}, { + 19.600813081410717`, 23.69184470726316}, {19.275231798499632`, + 24.675144345818538`}, {19.050793405472263`, 25.511958598471697`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{19.023761188874364`, 25.612747700660506`}, { + 19.009247426095087`, 25.666861987389716`}, {18.800731499812372`, + 26.671139870872633`}, {18.698038643681045`, 27.317662178776402`}, { + 18.61813103801594, 27.974673710954345`}, {18.561008682817057`, + 28.642174467406463`}, {18.526671578084397`, 29.320164448132747`}, { + 18.51893932036319, 29.550413556907138`}, {18.514604880965038`, + 29.74703412180877}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{18.515577538831486`, 29.851354677503736`}, { + 18.53292501704715, 30.5365847327041}, {18.57995578282932, + 31.314368299999444`}, {18.641662638120913`, 32.10582057800698}, { + 18.732721672431342`, 32.9246102774389}, {18.85477093563476, + 33.77497554349018}, {18.89476965370882, 34.00413630365761}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{18.912712308706062`, 34.106933409579284`}, { + 19.00944847760532, 34.66115452135578}, {19.198793648023983`, + 35.587749330379765`}, {19.426477276316493`, 36.5630437853814}, { + 19.561173517589673`, 37.09353545256812}, {19.70778272716713, + 37.640010445114925`}, {19.857486575610498`, 38.17035049938011}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{19.886672783363053`, 38.27053518143277}, { + 20.039153109372382`, 38.78594490575548}, {20.225120811068916`, + 39.387921623582564`}, {20.425414539207225`, 40.01091616623641}, { + 20.64063755832167, 40.6561871585837}, {20.87139313294664, + 41.32499322549109}, {21.119496113481485`, 42.020505826927334`}, { + 21.19765531514149, 42.232515873047646`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{21.23375052915746, 42.33042562424416}, {21.387134145976336`, + 42.74648498750797}, {21.675469688441716`, 43.50507217906986}, { + 21.985665198888142`, 44.298408873449866`}, {22.318883135326143`, + 45.12863654248485}, {22.676285955766232`, 45.99789665801166}, { + 22.766502945160617`, 46.21249256321073}}]}, + {Arrowheads[{{0.019295018806835394`, 1.}}], + ArrowBox[{{22.806944177921398`, 46.308688667846056`}, { + 23.059036118218938`, 46.908330691867164`}, {23.468296080694778`, + 47.86208011588822}, {23.79270785106708, 48.604754647815916`}, { + 24.136415647290978`, 49.379289607909726`}, {24.41602856885353, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{6.065923617017819, 50.}, {6.337651605127494, + 49.366768500200685`}, {6.632376243683451, 48.748239313220616`}, { + 6.931135104593402, 48.18860224396082}, {7.233928187857343, + 47.687857292421306`}, {7.505392647270676, 47.29312017236674}, { + 7.780932135147687, 46.942191372141174`}, {8.188857130920077, + 46.5107445524898}, {8.236416266572492, 46.472146956181426`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{8.317441576773264, 46.40638919647893}, {8.607999853016935, + 46.170580641578525`}, {9.489390127522537, 45.768827737528376`}, { + 10.52700470705095, 45.7723042368643}, {10.627875123563744`, + 45.79428797065904}, {10.72985404873297, 45.82049177984651}, { + 11.118168251342006`, 45.98874585596824}, {11.526542968550174`, + 46.2196702284124}, {12.101508577216016`, 46.595917698652755`}, { + 12.10584355132604, 46.59944102174456}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{12.186821443903355`, 46.66525716541736}, { + 12.721666394581243`, 47.09996139142419}, {13.39746264217288, + 47.74841523623559}, {13.760142510376234`, 48.133026189222115`}, { + 14.139343541517947`, 48.55789316259586}, {14.529824353417094`, + 49.01433124179023}, {14.961286111765588`, 49.551554942682586`}, { + 15.059447679183357`, 49.67842662765621}}]}, + {Arrowheads[{{0.001448163833233887, 1.}}], + ArrowBox[{{15.123303631271027`, 49.76095905302466}, { + 15.308251391971183`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{2.4920982917921206`, 50.}, {2.492355221430933, + 49.99707541494844}, {2.5697093403475773`, 49.12990136806211}, { + 2.6458802042681198`, 48.28654893619036}, {2.72075093018016, + 47.46617217705798}, {2.794204635071296, 46.66792514838975}, { + 2.8661244359291285`, 45.89096190791045}, {2.8705657177562873`, + 45.8431464867968}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{2.880216724716865, 45.7392424834145}, {2.9363934497412556`, + 45.13443651334489}, {3.0048947934952763`, 44.39750302241782}, { + 3.0715115841787903`, 43.67931549285405}, {3.1706826577739724`, + 42.599660168163545`}, {3.2629039954457433`, 41.582773909551236`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{3.2721605233403093`, 41.47883405465382}, {3.353360181769914, + 40.56288082598207}, {3.4361716109979366`, 39.60003085896253}, { + 3.5129928471190572`, 38.67130155462539}, {3.583601326155475, + 37.77446876693039}, {3.6173802773864705`, 37.319128942476624`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{3.625100262211921, 37.21506364716394}, {3.6478796264146296`, + 36.907998113178024`}, {3.705654291879761, 36.069401945963776`}, { + 3.755235599296461, 35.28186548132726}, {3.798540740025106, + 34.515700512460796`}, {3.8355697140656977`, 33.77090703936439}, { + 3.86629213494708, 33.0481998664068}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{3.869929695191671, 32.94391205481668}, {3.890861572824205, + 32.3428937370531}, {3.9092492790250954`, 31.65459222098092}, { + 3.921485640020906, 30.982580513821492`}, {3.927570655811637, + 30.326858615574814`}, {3.92837020934439, 30.154803638546454`}, { + 3.928748941428379, 29.983747315327125`}, {3.9216617408297934`, + 29.296417945809083`}, {3.9108605450049225`, 28.77076132233014}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{3.908716787294552, 28.66643209269098}, {3.9078315846436262`, + 28.623352359286947`}, {3.8907521865259196`, 27.95698378751941}, { + 3.867174304545133, 27.30400924526106}, {3.8373572233377327`, + 26.663594477765482`}, {3.8015602275401847`, 26.034905230286256`}, { + 3.7600248719971905`, 25.417397198317364`}, {3.7131859554292124`, + 24.810090633747972`}, {3.6850732969684383`, 24.49921494158346}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{3.67567510576252, 24.395287765848337`}, {3.62500256903564, + 23.834940193217292`}, {3.5244561774069973`, 22.885828473935085`}, { + 3.413141763048003, 21.96012894071209}, {3.2926543084633773`, + 21.055215058359032`}, {3.1762412267695304`, 20.251880951377164`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{3.1610406659772488`, 20.148643747354644`}, { + 3.030094523850258, 19.307924827513055`}, {2.8909753887887213`, + 18.46597272970803}, {2.7486453140336957`, 17.644318943897805`}, { + 2.60436795946291, 16.84338830972699}, {2.4592654096800084`, + 16.06420430367305}, {2.4537240531095224`, 16.03519411433671}}]}, + {Arrowheads[{{0.013483247334737701`, 1.}}], + ArrowBox[{{2.434145463922294, 15.932696003624075`}, {2.31463671838124, + 15.307042106172382`}, {2.1717809392628533`, 14.572176897661388`}, { + 2.0312107219629225`, 13.860075186099031`}, {1.8944329264314093`, + 13.1709615938717}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{32.60418249978299, 7.73945746609291}, {31.626987959007483`, + 8.10203082157432}, {30.694175687271834`, 8.464613223653483}, { + 29.80251519835569, 8.82619531000804}, {28.95044545716806, + 9.186366225633893}, {28.727393557614718`, 9.284555992463714}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{28.631886696912428`, 9.326599106204439}, { + 28.136405428617955`, 9.544715115526941}, {27.358834077614397`, + 9.900831124683087}, {26.616170369066396`, 10.254303398098234`}, { + 25.906853267882973`, 10.604721080768279`}, {25.229321738973127`, + 10.951673317689128`}, {24.873388103418627`, 11.139818136326847`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{24.781132596104932`, 11.188583956575403`}, { + 24.58104691705507, 11.29434829025012}, {23.95985187509821, + 11.632079984788435`}, {23.364703485388358`, 11.964676253721736`}, { + 22.79456862021134, 12.291944949467686`}, {22.248414151852977`, + 12.613693924443945`}, {21.725206952599088`, 12.929731031068176`}, { + 21.223913894735492`, 13.239864121758039`}, {21.167389770133415`, + 13.275636374687782`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{21.07921325936831, 13.331440378159874`}, { + 20.743501850548018`, 13.543901048931197`}, {19.839576325779618`, + 14.132040108052182`}, {19.004842963267436`, 14.692435484903253`}, { + 18.23297110117612, 15.22460325604074}, {17.615230504942797`, + 15.659368422414197`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{17.5298952053702, 15.719427314354329`}, {17.51763007767032, + 15.728059498020976`}, {16.922035882888594`, 16.15137091937015}, { + 16.364190195685644`, 16.55095396681119}, {15.83943758250957, + 16.926710666595632`}, {15.345191691387095`, 17.278586588863227`}, { + 14.87888084156338, 17.606676657191496`}, {14.437933352283583`, + 17.91107579515795}, {14.119336084497675`, 18.125546664851374`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{14.032771390609014`, 18.183819622783712`}, { + 14.020686912711152`, 18.19195455910177}, {13.624512265571033`, + 18.449605907886507`}, {13.162927955817471`, 18.7353171834392}, { + 12.494265459904154`, 19.111856304905178`}, {11.878169376194116`, + 19.408232831903714`}, {11.306653828466967`, 19.62728493439558}, { + 10.771732940502316`, 19.771850782341545`}, {10.703233262099188`, + 19.786080818383116`}, {10.635263880683283`, 19.79905710098755}, { + 10.28047833250874, 19.827527824428625`}, {10.248765140504853`, + 19.82695943576839}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{10.144430644355005`, 19.82508947122885}, {9.937333575490864, + 19.821377715392483`}, {8.89015653732592, 19.63427485552094}, { + 7.924869009184266, 19.13396031501206}, {7.464683943297934, + 18.78030182013262}, {7.016582902540748, 18.365397246175977`}, { + 6.596879459262006, 17.90249235280233}}]}, + {Arrowheads[{{0.018522790985394364`, 1.}}], + ArrowBox[{{6.52678760667327, 17.82518571625086}, {6.39002147396624, + 17.67434179754651}, {5.786165688148222, 16.887014650816926`}, { + 5.206467259413866, 16.023444733800467`}, {4.652377902090347, + 15.103660974310372`}, {4.383974601218351, 14.616711696950205`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{38.04738862120897, 4.185894000418275}, {37.467493807026365`, + 4.29117337086192}, {36.89851937346901, 4.396776813064768}, { + 36.340285799099576`, 4.502659245591524}, {35.79261356248076, + 4.608775587006894}, {34.72823501674582, 4.8215296707622874`}, { + 33.95039169626236, 4.983394706774173}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{33.84822899744271, 5.004654218153966}, {33.703947564765734`, + 5.034678412848586}, {32.71831503504209, 5.247861161783424}, { + 31.769901256076466`, 5.460717266084436}, {30.857270056370425`, + 5.67288607426926}, {29.978985264425546`, 5.884006934855529}, { + 29.77905654227884, 5.933549318289316}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{29.677768748849527`, 5.958648456849083}, {29.13331289014547, + 6.0935647441391865`}, {28.31862724110582, 6.301100562860422}, { + 27.533654592316132`, 6.506337986203251}, {26.777121218785936`, + 6.709000609351691}, {26.04775339552477, 6.908812027489755}, { + 25.641711890674458`, 7.022336568107484}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{25.541214659495147`, 7.050434439548462}, { + 25.344277397542175`, 7.105495835801455}, {24.66541949984768, + 7.298775629470811}, {24.009905977450824`, 7.488375003681834}, { + 23.148208836877217`, 7.740486277153068}, {22.32209740641028, + 7.983823704355556}, {21.533495492945075`, 8.216870669059556}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{21.433780440426805`, 8.24762825845424}, {20.79012690859723, + 8.446509549985405}, {20.075158559110577`, 8.664283510641763}, { + 19.389703064970227`, 8.87223398651537}, {18.733760426176186`, + 9.070360977606228}, {18.107330642728453`, 9.258664483914334}, { + 17.507291293289878`, 9.43682532109176}, {17.43872507382144, + 9.45676127246096}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{17.338523344220626`, 9.485895397456012}, {16.9305199565233, + 9.604524304790578}, {16.377016632428727`, 9.761761435010788}, { + 15.846781321006157`, 9.908536711752387}, {15.315404779113406`, + 10.05079559595937}, {14.805287045410859`, 10.181549198491028`}, { + 14.013108261210721`, 10.370643339126197`}, {13.296834760644275`, + 10.52367668482355}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{13.194373614364062`, 10.543406857001452`}, { + 12.570970589643531`, 10.658715186436451`}, {11.912819404013131`, + 10.75904231444263}, {11.065074496823504`, 10.852201311192127`}, { + 10.28020294029533, 10.894964449119497`}, {10.162866815735214`, + 10.897699965546765`}, {10.046886547930084`, 10.899290285896486`}, { + 9.709117433500413, 10.890658511444546`}, {9.382401999689897, + 10.872341309348814`}, {9.04678046343293, 10.842251332650026`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{8.942846083605277, 10.832933149132677`}, {8.671164729309828, + 10.808575696653863`}, {8.011025970770946, 10.699894286596136`}, { + 7.397584577192774, 10.550854280657987`}, {6.826439401694834, + 10.366012880321776`}, {6.294943034315532, 10.14909750592898}, { + 5.798330137123992, 9.906817514094255}, {5.121296735164822, + 9.498634570724175}, {5.0538865149316825`, 9.449398105771877}}]}, + {Arrowheads[{{0.012638712578083364`, 1.}}], + ArrowBox[{{4.969619444643511, 9.387849387513327}, {4.511707966607465, + 9.053390571600833}, {3.962028766022461, 8.584892690184596}, { + 3.468925591271482, 8.101814216812416}, {3.0278376262222397`, + 7.613364237702503}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{49.23421804558305, 0.8316664813545216}, {48.51101982045465, + 0.8566509582387026}, {47.79915966134927, 0.8818957332494143}, { + 47.09833028252699, 0.9073954298493504}, {46.40824735226441, + 0.9331435098348084}, {45.72877000144163, 0.9591261745871047}, { + 45.06299789459429, 0.9852027023781942}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{44.958730302279925`, 0.9893803531077733}, {44.40106856163575, + 1.0117400639174792`}, {43.75256273441282, 1.0383436912581903`}, { + 43.114099010149985`, 1.065126708891007}, {42.485536519727304`, + 1.0920753181972462`}, {41.86673439402487, 1.1191757205582245`}, { + 41.25755176392275, 1.1464141173552584`}, {40.78850246109985, + 1.1678153501496118`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{40.68425965912677, 1.1725716187523691`}, { + 40.657847760301024`, 1.173776709969665}, {40.067481514039784`, + 1.2012496997827604`}, {39.48631215601908, 1.228819288175862}, { + 38.91419881711899, 1.2564716765302868`}, {38.35100062821959, + 1.2841930662273513`}, {37.79657672020095, 1.3119696586483724`}, { + 36.713460321076866`, 1.367635887312342}, {36.5152831277517, + 1.378156027799674}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{36.41107859458342, 1.3836876750591467`}, { + 35.663704880901335`, 1.4233616472885051`}, {34.64619869176009, + 1.4790351150138743`}, {33.65983004573886, 1.5345444669254624`}, { + 32.703487234923394`, 1.5897778794602806`}, {32.24356066634335, + 1.61697670549179}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{32.13939140664019, 1.6231369966470601`}, { + 31.776058551399444`, 1.6446235290553408`}, {30.876432287252744`, + 1.6989695921476553`}, {30.003496734569026`, 1.7527042451742365`}, { + 29.405692695819834`, 1.789955808501504}, {28.819480003418875`, + 1.8267349197805682`}, {28.244607992947174`, 1.8630193633547578`}, { + 27.973270007730587`, 1.8802336373921977`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{27.86912812585858, 1.8868406256908998`}, {27.68082599998575, + 1.8987869235674026`}, {27.127883360115614`, 1.9340153847618324`}, { + 26.5855294089178, 1.9686825312813758`}, {25.552974945282806`, + 2.0381397537050145`}, {24.55475397492972, 2.1046408164156496`}, { + 23.70412265418931, 2.1614065861825535`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{23.600002986878568`, 2.1683548761392686`}, { + 23.59587978623814, 2.1686300325466927`}, {22.67635237920806, + 2.2301074020981444`}, {21.796171753839484`, 2.289072925070005}, { + 20.95203716839443, 2.3453151883986934`}, {20.14064788113491, + 2.3986227790206285`}, {19.435083526714784`, 2.4442679465269648`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{19.330947785798966`, 2.450970827341683}, { + 18.616105201172488`, 2.496433942144239}, {18.002626383969353`, + 2.5346459778409858`}, {17.410148971334863`, 2.570608221642296}, { + 16.614216322693593`, 2.617129773469813}, {15.855851598895057`, + 2.659202369632701}, {15.164083814979126`, 2.6952386266731256`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{15.059859785893886`, 2.7003866714439924`}, { + 14.444372621614194`, 2.730088259651493}, {13.862994411619322`, + 2.7558393425949537`}, {13.304444661273038`, 2.778325497332481}, { + 12.255830539526233`, 2.8135030221897366`}, {11.291035103044868`, + 2.8362826319066285`}, {10.888438256837626`, 2.8412868139547105`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{10.784095064693158`, 2.842583774757777}, { + 10.402563198500038`, 2.847326124166525}, {10.242401412705563`, + 2.8483009528073273`}, {10.084711198244852`, 2.848888105358699}, { + 9.745923882541744, 2.847501297711473}, {9.41848089887902, + 2.844327527556718}, {8.646481286148136, 2.8316578528546787`}, { + 7.93728238657567, 2.809222879634646}, {7.285830078242592, + 2.7780381648152788`}, {6.687070239229876, 2.7391192653152365`}, { + 6.612878458040452, 2.732291395190102}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.5089663210109405`, 2.7227283605158}, {5.630927116849549, + 2.6419224066125797`}, {4.902061320825722, 2.547617296684414}, { + 4.265843246427178, 2.4439054882570947`}, {3.221378058167581, + 2.220748895938165}, {2.426380730132568, 1.9901834985655629`}, { + 2.4105078953076413`, 1.984243226294471}}]}, + {Arrowheads[{{0.005629882578595802, 1.}}], + ArrowBox[{{2.312776420891829, 1.9476680603654792`}, { + 1.8238352430992246`, 1.7646860188668028`}, {1.2357375630633354`, + 1.4810766224636773`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{5.422804138815669, 49.06237784513235}, {5.7180125415408005`, + 48.133769060446994`}, {6.014336342928001, 47.28615002998856}, { + 6.311698936632197, 46.513273102085286`}, {6.610023716308318, + 45.80889062506539}, {6.909310681956363, 45.17300259892887}, { + 6.912053336794484, 45.16781968758377}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.960860777942236, 45.075586192893226`}, {7.209559833576332, + 44.605609023675726`}, {7.483906494512723, 44.146652133038145`}, { + 7.759958768910425, 43.73929533460663}, {8.335785207985936, + 43.059172850025035`}, {8.926926102444082, 42.58849496636557}, { + 9.847123551312599, 42.28562331774599}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{9.950103394162635, 42.27291046265703}, {10.019922948842948`, + 42.2709011462738}, {10.382896418236934`, 42.339410749903585`}, { + 10.763334442566057`, 42.476789676779525`}, {11.26829736297392, + 42.714511728431034`}, {11.809766888230172`, 43.07616914481139}, { + 12.39763034537957, 43.57653615607823}, {13.041775061466872`, + 44.23038699238919}, {13.330011975063499`, 44.55115918224427}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{13.398873335225309`, 44.62954192432216}, { + 13.755564037444334`, 45.05943886363038}, {14.14926552365368, + 45.5570389552587}, {14.563050675026018`, 46.102782747596784`}, { + 15.072901269461736`, 46.80456011431776}, {15.625697769140709`, + 47.59766554212114}, {15.883495936148474`, 47.98090219291252}}]}, + {Arrowheads[{{0.011063788351635493`, 1.}}], + ArrowBox[{{15.941739949700994`, 48.0674863643269}, {16.227985067083072`, + 48.493011577962676`}, {16.549733044471818`, 48.98243499482141}, { + 16.886308056308966`, 49.50151076879809}, {17.205344462523815`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{22.222492756922126`, 13.72251761101824}, {21.66929228011176, + 14.113318870339784`}, {21.142564235439213`, 14.49672133070915}, { + 20.640011337705104`, 14.872129011079782`}, {20.16065016729063, + 15.239479707064227`}, {19.70349730457699, 15.598711214275042`}, { + 19.267569329945385`, 15.949761328324776`}, {18.90272055134584, + 16.25064321163222}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{18.822623251580477`, 16.31752303899174}, { + 18.077300538354766`, 16.953201267633034`}, {17.37014221868529, + 17.57925159667856}, {16.72219233328327, 18.170048746679374`}, { + 16.127672572407757`, 18.72612978363757}, {15.72321280012335, + 19.112124906420206`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{15.647722275241327`, 19.184169090829904`}, { + 15.580804626317798`, 19.248031773555244`}, {15.072466396313434`, + 19.737848990112823`}, {14.603636647296515`, 20.193344972746964`}, { + 14.168525878325624`, 20.615502995050935`}, {13.763917699988866`, + 21.00486932013211}, {13.033859609411712`, 21.688223719336833`}, { + 12.703376992889382`, 21.98358466362569}, {12.618989081820196`, + 22.055645316505284`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{12.539633529628224`, 22.123408729867727`}, { + 12.392201857783952`, 22.24930380646843}, {11.55646217873036, + 22.873509680976852`}, {10.828553749993715`, 23.25916605743531}, { + 10.782732246394643`, 23.27731235231735}, {10.737227466659883`, + 23.294468469578415`}, {10.474773473670641`, 23.357407149545708`}, { + 10.219843328184421`, 23.38669263645188}, {9.72221989622388, + 23.37922827640576}, {9.244038857934463, 23.243058776821357`}, { + 8.811694353927784, 23.00404400122332}}]}, + {Arrowheads[{{0.015757229165579895`, 1.}}], + ArrowBox[{{8.727151169542925, 22.9436239632191}, {8.249087343926496, + 22.546564053748188`}, {7.719829863785956, 21.966740141979948`}, { + 7.1832687862815385`, 21.256369245500245`}, {6.639725907738225, + 20.42673827847845}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{50., 11.46237682901988}, {49.88912467024407, + 11.54287682992053}, {49.25623860318609, 12.033250972594347`}, { + 48.648364699713916`, 12.536329915833266`}, {48.065187743679964`, + 13.052353449233644`}, {47.50641146893203, 13.581532094528852`}, { + 46.97177277180982, 14.124025154692017`}, {46.87881788721517, + 14.225206532213788`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{46.80822049649411, 14.302051781107908`}, {46.461008548653, + 14.679991932696266`}, {46.07297034319253, 15.129707180118553`}, { + 45.69935357310561, 15.587521199686858`}, {45.340201495431835`, + 16.053864744570316`}, {44.995557367210786`, 16.52916856793806}, { + 44.66546444548206, 17.01386342295924}, {44.349965987285245`, + 17.508380062802974`}, {44.28484174168989, 17.617642282146665`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{44.23141494137347, 17.70727910974655}, {44.04910524965994, + 18.013149240638413`}, {43.762925489645724`, 18.528601709634685`}, { + 43.399137500753675`, 19.243569870713735`}, {43.06213999586156, + 19.980034893791803`}, {42.752167766312844`, 20.7390106592554}, { + 42.47604906510501, 21.486080922461145`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{42.443016317651974`, 21.585047099552863`}, { + 42.20981639498403, 22.30945519160593}, {41.98017648554454, + 23.132752563002157`}, {41.778031434135414`, 23.980588437556936`}, { + 41.60338124075667, 24.85296281527026}, {41.4756787296126, + 25.639687107466084`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{41.45895908108163, 25.742690200658583`}, { + 41.457314387332445`, 25.75282250357195}, {41.34091935578689, + 26.68311430989181}, {41.25419614612001, 27.64383823422985}, { + 41.197144758331795`, 28.634994276586063`}, {41.17077797668167, + 29.263550328445145`}, {41.1566170833663, 29.903098093408616`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{41.159225073015406`, 30.0074141801061}, {41.18290278128267, + 30.916477862011032`}, {41.239470154571414`, 31.96373594165704}, { + 41.310524231197896`, 33.00682029690799}, {41.41314628077346, + 34.08959161499589}, {41.42248237616456, 34.1718315939104}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{41.43425299715218, 34.27551686931529}, {41.476295295417145`, + 34.645859885103704`}, {41.54733630329811, 35.21204989592076}, { + 41.62626930441633, 35.78816164744705}, {41.713094298771836`, + 36.37419513968258}, {41.808699349169395`, 36.97178450283095}, { + 41.91397251841377, 37.58256386709577}, {42.028913806504974`, + 38.20653323247704}, {42.066788708726065`, 38.400197172450326`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{42.08681727815155, 38.50260830593195}, {42.15352321344301, + 38.84369259897476}, {42.28780073922787, 39.49404196658893}, { + 42.43174638385956, 40.15758133531955}, {42.58536014733808, + 40.834310705166615`}, {42.74864202966342, 41.524230076130124`}, { + 42.902547693371, 42.193979072960275`}, {43.002900928586094`, + 42.574297861926645`}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{43.029524445517225`, 42.67519569243077}, { + 43.097046136761335`, 42.931089463945746`}, {43.30192910040782, + 43.68264479179374}, {43.51755478501513, 44.4492725243773}, { + 43.74428139128791, 45.23160012956945}, {43.982467119930845`, + 46.03025507524323}, {44.1835404360481, 46.68623649936296}}]}, + {Arrowheads[{{0.016199078980985673`, 1.}}], + ArrowBox[{{44.21412206270687, 46.78600597347767}, {44.23247017164858, + 46.84586482927169}, {44.49464874714579, 47.679056859527854`}, { + 44.66394023488933, 48.20566914183808}, {44.83892860311367, + 48.74074678767328}, {45.01978687836011, 49.28458485565135}, { + 45.20668808716997, 49.83747840439018}, {45.26251030228074, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{48.5151686627396, 6.445255918115043}, {47.649670000756565`, + 6.734681197013667}, {46.78858005312277, 7.037906999039333}, { + 45.95225028413573, 7.346977339326902}, {45.14068069379543, + 7.6618922178763755`}, {44.597685680959884`, 7.883255563383042}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{44.50105568739623, 7.922648814049999}, {44.35387128210187, + 7.9826516346877545`}, {43.59182204905506, 8.309255589761037}, { + 42.85453299465499, 8.641704083096224}, {42.14200411890167, + 8.979997114693315}, {41.45423542179509, 9.324134684552309}, { + 40.78898836464187, 9.673702180867823}, {40.72946927608399, + 9.706424080338618}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{40.638026227600164`, 9.756696863613532}, { + 40.144024408748606`, 10.028284991834468`}, {39.519343554115316`, + 10.387883117452244`}, {38.914945800742, 10.752496557721152`}, { + 38.33083114862863, 11.122125312641192`}, {37.76699959777524, + 11.496769382212364`}, {37.223451148181816`, 11.876428766434667`}, { + 37.10061479935517, 11.966731011072298`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{37.01653803166484, 12.028539432739311`}, { + 36.700185799848356`, 12.261103465308103`}, {36.19547103156106, + 12.650600022169911`}, {35.70757432210614, 13.04472498035733}, { + 35.23649567148359, 13.443478339870362`}, {34.7822350796934, + 13.846860100709005`}, {34.34479254673558, 14.254870262873261`}, { + 33.924168072610144`, 14.66750882636313}, {33.85145100854384, + 14.742649853013779`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{33.77888294186041, 14.817636915578268`}, {33.52036165731707, + 15.084775791178611`}, {33.133373300856356`, 15.506671157319705`}, { + 32.664784329928494`, 16.052416659563114`}, {32.22060981863194, + 16.605916986572577`}, {31.69018511154382, 17.315825970278464`}, { + 31.196741637946694`, 18.037629092949565`}, {31.17546955434721, + 18.071822146928035`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{31.120347305636216`, 18.160426444517174`}, { + 30.739513687939585`, 18.77258389424782}, {30.31773555162152, + 19.521947913835163`}, {29.966400820102244`, 20.211927889342782`}, { + 29.642298400859875`, 20.915646369943257`}, {29.34525434268344, + 21.633992407772915`}, {29.25258426489671, 21.884187169646278`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.21633973648338, 21.982041745493895`}, {29.07695017394571, + 22.35837183218061}, {28.83492158582452, 23.101379548430952`}, { + 28.619603456347306`, 23.860792926183127`}, {28.43099578551407, + 24.636611965437133`}, {28.269098573324815`, 25.428836666192975`}, { + 28.17163106156758, 26.01573783387062}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{28.15453544340601, 26.118679194333243`}, {28.13434409265668, + 26.24026152590325}, {28.0271646163868, 27.073681042020564`}, { + 27.947560144515183`, 27.929095214544912`}, {27.895530677041823`, + 28.80650404347629}, {27.876841465838986`, 29.240676560122132`}, { + 27.864960647756902`, 29.680932878497988`}, {27.878765470837422`, + 30.278241465498656`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{27.881176562902063`, 30.382564859276265`}, { + 27.88816919127769, 30.6851226646249}, {27.94692749720561, + 31.72679844192237}, {28.011034837116327`, 32.629532214216155`}, { + 28.10334543037533, 33.564716444154136`}, {28.223859276982616`, + 34.53235113173631}, {28.225070250223766`, 34.540494622633474`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{28.24041896934092, 34.64371090369264}, {28.372576376938188`, + 35.532436276962684`}, {28.552886852606758`, 36.57178034826968}, { + 28.656160902220186`, 37.108727656867075`}, {28.768180826353046`, + 37.65719181409373}, {28.88894662500533, 38.21717281994965}, { + 29.00857095469376, 38.745040664499236`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.032214035756287`, 38.84667689105597}, { + 29.156715845868195`, 39.371685377549284`}, {29.30371926807877, + 39.966216929293}, {29.439764481466057`, 40.53591400049635}, { + 29.61655154169731, 41.17615609747588}, {29.80282569588408, + 41.82928249120391}, {29.998957553744415`, 42.49597690574005}, { + 30.114390647733924`, 42.876882395124895`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{30.144655008685373`, 42.976748567127345`}, { + 30.20531772499636, 43.176923065143924`}, {30.422276819357954`, + 43.872804693475146`}, {30.650205446547247`, 44.584305514793336`}, { + 30.889474216282284`, 45.3121092531581}, {31.188332202941194`, + 46.195123239514565`}, {31.449093099805694`, 46.94138319331566}}]}, + {Arrowheads[{{0.01512400590771079, 1.}}], + ArrowBox[{{31.4835149977021, 47.039893684124664`}, {31.507645673424825`, + 47.108952186248885`}, {31.848733468619592`, 48.055929776770334`}, { + 32.212914429411924`, 49.03838969448818}, {32.40407698468418, + 49.54365480211115}, {32.57901781468988, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{50., 19.16442344844397}, {49.706477758445516`, + 19.818188959844363`}, {49.389871011808275`, 20.591911864344176`}, { + 49.10206576003426, 21.394857633328577`}, {48.842263402555886`, + 22.22442292313457}, {48.61046393937317, 23.080607733762147`}, { + 48.60773112707541, 23.092445708006146`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{48.58425882886829, 23.194122819841102`}, {48.4066673704861, + 23.963412065211315`}, {48.232079498493334`, 24.87577676974791}, { + 48.087906125993534`, 25.820642699637773`}, {47.97414725298669, + 26.7980098548809}, {47.93171908588279, 27.312104119417537`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{47.92313616399198, 27.416101798747597`}, {47.8908028794728, + 27.807878235477293`}, {47.84608234555539, 28.481352352151365`}, { + 47.81513451712641, 29.170323629221468`}, {47.81940832124887, + 30.156688155653644`}, {47.85184215946753, 31.177306034106316`}, { + 47.87075797698969, 31.58567971682966}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{47.87558633692381, 31.689919204522994`}, {47.9014066349487, + 32.2473537526776}, {47.93834963643672, 32.79782495052778}, { + 47.98339981375637, 33.35859437408766}, {48.03655716690765, + 33.92966202335723}, {48.09782169589055, 34.51102789833649}, { + 48.16719340070508, 35.10269199902545}, {48.24467228135124, + 35.7046543254241}, {48.26433133335004, 35.844242617533}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{48.27888412581179, 35.94757412330828}, {48.33112025730474, + 36.31847463173155}, {48.42739924804128, 36.94571267214686}, { + 48.53350925356087, 37.586368446670065`}, {48.64945027386351, + 38.240441955301144`}, {48.77522230894919, 38.907933198040105`}, { + 48.91082535881792, 39.58884217488695}, {49.00876631543992, + 40.056428791832154`}}]}, + {Arrowheads[{{0.019797137831981355`, 1.}}], + ArrowBox[{{49.03015952525968, 40.15856357742369}, {49.05625942346969, + 40.28316888584167}, {49.21152450290451, 40.99091333090427}, { + 49.35860584479218, 41.680847365252156`}, {49.54477099678277, + 42.434908158843044`}, {49.741444834490466`, 43.203561412992826`}, { + 49.948966193382276`, 43.987394490926995`}, {50., + 44.17397522124705}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{50., 8.00659447809414}, {49.551585268260126`, + 8.20165550436517}, {48.732669981643205`, 8.579218405864788}, { + 47.94184350682008, 8.965896258791744}, {47.17910584379076, + 9.361689063146041}, {46.44445699255524, 9.766596818927678}, { + 46.26759995896502, 9.869919437641153}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{46.177498162532814`, 9.922558302882639}, {45.73578254263073, + 10.180615410640526`}, {45.05096808353443, 10.60374072278846}, { + 44.39001361526635, 11.03597275537148}, {43.752919137826474`, + 11.477311508389585`}, {43.139684651214814`, 11.927756981842776`}, { + 42.72027951485643, 12.254779192543133`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{42.6379874849117, 12.31894464790501}, {42.550310155431376`, + 12.38730917573105}, {41.984795650476144`, 12.855968090054409`}, { + 41.443141136349126`, 13.333733724812856`}, {40.94362640894774, + 13.80452473925534}, {40.46436105413998, 14.284153438354512`}, { + 39.80912140585641, 14.986800383757481`}, {39.62677441807408, + 15.200520524520323`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{39.559043927007586`, 15.279904177964305`}, { + 39.19391878402458, 15.70784981009908}, {38.61820076101852, + 16.447981651547273`}, {38.08141490921222, 17.20787584227002}, { + 37.58248592463907, 17.98708142631499}, {37.17308640126758, + 18.695501630181173`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{37.120873195268885`, 18.785850758420242`}, { + 37.12075680440495, 18.786052159826088`}, {36.696302572492634`, + 19.60682504511563}, {36.309198252884904`, 20.451437084495943`}, { + 36.01905069441263, 21.164590767576065`}, {35.7539728043095, + 21.896471803001962`}, {35.519208237666376`, 22.632296873992228`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{35.49016766783572, 22.73251837673516}, {35.29770815368151, + 23.409533715600624`}, {35.10741095913884, 24.19536008809444}, { + 34.94277647695342, 25.003010809814725`}, {34.803804707125266`, + 25.832485880761478`}, {34.69049564965438, 26.6837853009347}, { + 34.67696841400582, 26.82068624107748}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{34.666707395813475`, 26.924531777138874`}, { + 34.60391999442763, 27.559964950786444`}, {34.54514843133188, + 28.46408071076875}, {34.51418096036715, 29.396132580881627`}, { + 34.51101758153343, 30.356120561125074`}, {34.51735362207428, + 30.930775198570107`}, {34.52193665493144, 31.092959998371985`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{34.52488424551125, 31.19726961232964}, {34.53390395990877, + 31.516460117705645`}, {34.613081163642576`, 32.58280928110656}, { + 34.67414084003737, 33.14181336751139}, {34.726612086621, + 33.69048565203447}, {34.842930430005026`, 34.69718648170021}, { + 34.934365996443184`, 35.34935245291421}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{34.9488546380153, 35.45269297313555}, {34.98946297256155, + 35.742332715856996`}, {35.074059568529485`, 36.279322859619526`}, { + 35.166209714290545`, 36.82592435450482}, {35.265913409844735`, + 37.38213720051288}, {35.37317065519204, 37.9479613976437}, { + 35.48893185528895, 38.525156536649384`}, {35.614147415091956`, + 39.11548220828203}, {35.7122742180686, 39.55518862732703}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{35.73500261170108, 39.657034608971415`}, {35.74881733460104, + 39.71893841254165}, {35.89294161381621, 40.33552514942823}, { + 36.04652025273747, 40.96524241894178}, {36.209553251364824`, + 41.60809022108229}, {36.38204060969826, 42.264068555849775`}, { + 36.563982327737776`, 42.93317742324422}, {36.73454281651448, + 43.578754746228405`}, {36.77067888812028, 43.70012306485433}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{36.800456470599016`, 43.8001354612657}, {36.94839100382452, + 44.2969953789721}, {37.1724773347517, 45.02974568203696}, { + 37.40719370125155, 45.77769522427006}, {37.6529319952796, + 46.54153357451852}, {37.91008410879138, 47.32195030162941}, { + 38.0638872958489, 47.77810525815113}}]}, + {Arrowheads[{{0.010772430747056715`, 1.}}], + ArrowBox[{{38.0972275785963, 47.87698705324277}, {38.17904193374241, + 48.11963497444984}, {38.46019736208822, 48.9352771618269}, { + 38.81903635775576, 49.95032318875829}, {38.836973701191006`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{23.470220821913333`, 15.085565547830058`}, { + 22.981366107675314`, 15.518284548499466`}, {22.51639893692169, + 15.947079180848966`}, {22.074405893235802`, 16.371904793283985`}, { + 21.654473560200984`, 16.79271673420994}, {21.25568852140058, + 17.209470352032262`}, {20.87713736041792, 17.62212099515637}, { + 20.52104676307981, 18.033834921251263`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{20.45278368851573, 18.112761067142728`}, { + 20.175251966848197`, 18.433644784931886`}, {19.54114384028032, + 19.226672897579935`}, {18.969702896650194`, 20.00239607954362}, { + 18.455819051893734`, 20.762005077266046`}, {18.07020937629293, + 21.37796775552071}, {18.00638071623046, 21.487912928234255`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{17.95398867495026, 21.578158470310946`}, { + 17.718793488507583`, 21.98328330560478}, {17.398636370309323`, + 22.57909086577481}, {17.108107456015723`, 23.166023290617776`}, { + 16.845675143169853`, 23.74504069512406}, {16.60980782931478, + 24.317103194284048`}, {16.399575590598833`, 24.883052815195416`}, { + 16.237206627866204`, 25.37293915655153}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{16.2053980674546, 25.47230938707473}, {16.045117233213617`, + 26.022835261275823`}, {15.900869356050205`, 26.59921837812327}, { + 15.78019740906542, 27.175178656115946`}, {15.682503269132331`, + 27.752398708975104`}, {15.612922462502699`, 28.286119413998488`}, { + 15.562478980771743`, 28.826173923832307`}, {15.531172823939466`, + 29.37256223847656}, {15.526667513662884`, 29.57719853047741}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{15.524370653873001`, 29.681524501785265`}, { + 15.519003992005867`, 29.92528435793125}, {15.51828034339738, + 30.079992856580102`}, {15.519056007726483`, 30.235480800083707`}, { + 15.55031846211015, 30.846938063698044`}, {15.605096918336777`, + 31.477023789484207`}, {15.672286136286775`, 32.118324809133796`}, { + 15.764296877683512`, 32.782056416510244`}, {15.88261608950664, + 33.472327519599645`}, {15.954143042595671`, 33.825236574737076`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{15.97487130339802, 33.92750838443228}, {16.02873071873582, + 34.19324702638811}, {16.20451650071959, 34.94924342482441}, { + 16.41334975908533, 35.748287993216366`}, {16.662023958756293`, + 36.61085431151899}, {16.952030328464485`, 37.532061136412345`}, { + 17.09255864317092, 37.946257499956985`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{17.12608576403821, 38.04507610154885}, {17.287515595341052`, + 38.52087807236833}, {17.473608667445955`, 39.04344333339228}, { + 17.672626486517135`, 39.58627472385885}, {17.886137999878457`, + 40.15216237691478}, {18.116035418371467`, 40.74440994342615}, { + 18.36332197816409, 41.364908900530885`}, {18.60172543837519, + 41.94875368701877}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{18.641408767784313`, 42.04526416382306}, { + 18.914075466319854`, 42.69822689507231}, {19.219548867018837`, + 43.4148288867849}, {19.54642435368911, 44.16724817764269}, { + 19.895705162498594`, 44.95737624478362}, {20.170394327145438`, + 45.5694559640595}, {20.307977928927432`, 45.871953079265694`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{20.35118088123575, 45.96694091409767}, {20.461257930489893`, + 46.20896096167972}, {20.76929348378262, 46.877654262768814`}, { + 21.09549849827426, 47.57729889245131}, {21.44087048521547, + 48.30965787585175}, {21.806406955856904`, 49.07649423809468}, { + 22.127788009699607`, 49.743922946522126`}}]}, + {Arrowheads[{{0.0008629872787197494, 1.}}], + ArrowBox[{{22.173060242135065`, 49.83794214043768}, { + 22.193105421449207`, 49.87957100430463}, {22.251647228996497`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{37.48627654338087, 8.809842802380324}, {36.626219069263136`, + 9.21585371115884}, {35.80226208661862, 9.627039379453516}, { + 35.01285610304464, 10.04302671328968}, {34.25645162613851, + 10.463442618692657`}, {33.78663623092154, 10.738527125383836`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{33.696585491948284`, 10.7912532883828}, {33.531499163497536`, + 10.88791400168778}, {32.94462640124435, 11.24717935044862}, { + 32.376469636764234`, 11.608337642631321`}, {31.826502929173795`, + 11.971296721113163`}, {31.29420033758966, 12.335964428771419`}, { + 30.779035921128447`, 12.702248608483362`}, {30.280483738906774`, + 13.07005710312627}, {30.22840296815164, 13.109915543313623`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{30.145535284328624`, 13.173335814773386`}, { + 29.798017850041262`, 13.439297755577417`}, {29.37599260236369, + 13.81774248318664}, {28.941039242642436`, 14.192535367333754`}, { + 28.521120294510578`, 14.568576095043651`}, {28.116235757968116`, + 14.945864666316337`}, {27.726385633015052`, 15.324401081151812`}, { + 27.076981316341534`, 15.99698403266353}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{27.004498707194276`, 16.072053701807786`}, { + 26.991788617877116`, 16.085217441511123`}, {26.317329249096773`, + 16.85102517612158}, {25.69710844926041, 17.62179219238419}, { + 25.12522714095442, 18.397486397699954`}, {24.601685324178806`, + 19.178107792068865`}, {24.476263556048252`, 19.385440305087194`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{24.4222519352974, 19.474725962827325`}, {24.12648299893357, + 19.96365637549093}, {23.744421429858292`, 20.663037850868964`}, { + 23.395450104871276`, 21.36761829633955}, {23.06036026273179, + 22.120782852835685`}, {22.760123381498413`, 22.881453612134287`}, { + 22.63672669637018, 23.23800092580061}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{22.60259811312328, 23.336613418212988`}, {22.49387862209047, + 23.65075186067304}, {22.260765145427275`, 24.429798884889625`}, { + 22.089025944988165`, 25.09846013370916}, {21.940365247875135`, + 25.777476997508224`}, {21.814783054088192`, 26.466849476286814`}, { + 21.712279363627335`, 27.16657757004493}, {21.68635092953108, + 27.4002194036681}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{21.67484119228529, 27.50393396292935}, {21.633149117660903`, + 27.879622395429116`}, {21.577687257357237`, 28.608945069085923`}, { + 21.545893782716345`, 29.35454559101535}, {21.53776869373822, + 30.116423961217393`}, {21.5392741412956, 30.42895785101014}, { + 21.54481625445728, 30.744776369430802`}, {21.609285429293784`, + 31.67055681197811}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{21.616534649388687`, 31.774655960208236`}, { + 21.617531093272618`, 31.788964942170228`}, {21.682061597244324`, + 32.340272885302326`}, {21.735322867390412`, 32.879895365729475`}, { + 21.830761850326166`, 33.66274911347372}, {21.951141515156483`, + 34.474479513898956`}, {22.096461861881362`, 35.315086567005174`}, { + 22.211774035222952`, 35.90395917403917}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{22.231827095226194`, 36.00636551485227}, { + 22.266722890500805`, 36.184570272792385`}, {22.465406975195005`, + 37.09010777350419}, {22.695996490144154`, 38.038876211384164`}, { + 22.958491435348257`, 39.03087558643232}, {23.249219889922813`, + 40.05319394567386}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{23.27737268978264, 40.15367568207321}, {23.391168625837675`, + 40.560731551471335`}, {23.57134009587752, 41.12982065095849}, { + 23.76027367554548, 41.71119213444517}, {23.95836224087375, + 42.3055833267851}, {24.16599866789452, 42.913731552832004`}, { + 24.38357583263998, 43.53637413743964}, {24.590315868425485`, + 44.11499595543403}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{24.625691157055126`, 44.21316750181388}, {24.85012387943372, + 44.828091681752}, {25.13732960246073, 45.59660623650886}, { + 25.443211146227988`, 46.394217482154964`}, {25.769079260910146`, + 47.2232764622927}, {26.11624469668185, 48.08613422052446}, { + 26.125331449227513`, 48.10822628298985}}]}, + {Arrowheads[{{0.009318544673586782, 1.}}], + ArrowBox[{{26.165025892478358`, 48.20473294094269}, { + 26.486018203717755`, 48.985141800452595`}, {26.879710532192508`, + 49.92265024567952}, {26.91283074798475, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{7.380939549637546, 50.}, {7.739938473640906, + 49.550735516622474`}, {8.217865940968393, 49.08735724752728}, { + 8.714360981517045, 48.73862405116805}, {9.251282448099278, + 48.501898103269035`}, {9.815927622112142, 48.39445465182176}, { + 9.92423077255682, 48.386441588483436`}, {10.03368119572553, + 48.38314483829652}, {10.396188183227663`, 48.43740701051539}, { + 10.77402969866314, 48.54381143026198}, {10.949430844116431`, + 48.61092876121355}}]}, + {Arrowheads[{{0.011896609445858982`, 1.}}], + ArrowBox[{{11.046890646469466`, 48.64822180050414}, { + 11.373496363207295`, 48.77319763190089}, {12.016547901203626`, + 49.13599711929082}, {12.713002524091502`, 49.64739883655534}, { + 13.109722656106657`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{14.190613870852335`, 21.989082681500314`}, { + 13.760419804759046`, 22.51401904926761}, {13.371275679548933`, + 22.994973110183707`}, {12.691917071134574`, 23.834948410836674`}, { + 12.120358333625525`, 24.523580848348047`}, {11.867595380330492`, + 24.81506608519778}, {11.632741409547945`, 25.07379556891386}, { + 11.5142160679752, 25.19031122425383}}]}, + {Arrowheads[{{0.013098281174180656`, 1.}}], + ArrowBox[{{11.439800400179545`, 25.263465118482014`}, { + 11.133139147050304`, 25.564926699622447`}, {10.696191592637298`, + 25.895136251624617`}, {10.668499387375153`, 25.912191791166414`}, { + 10.640993637960138`, 25.928579700536275`}, {10.435612375063256`, + 26.01285669135882}, {10.236493365647785`, 26.05887068812279}, { + 9.846791987147515, 26.075293846849068`}, {9.466852803349513, + 25.9432905861258}, {9.083403963254911, 25.666758005267006`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{0.9701099597005121, 50.}, {0.9731407875071092, + 49.893201640121646`}, {0.9955140278346496, 49.110658591026066`}, { + 1.0174858373962665`, 48.342315514907355`}, {1.038928373388392, + 47.58690107203786}, {1.059841635811026, 46.844415262417584`}, { + 1.0802256246641688`, 46.11485808604654}, {1.0881837530036005`, + 45.82762042807017}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{1.0910737713986183`, 45.72330920313297}, { + 1.1000803399478198`, 45.39822954292471}, {1.1194057816619793`, + 44.694529633052106`}, {1.1382019498066474`, 44.003758356428726`}, { + 1.1564688443818238`, 43.32591571305456}, {1.1750794788742331`, + 42.62478462227685}, {1.1929691871918549`, 41.93641205434676}, { + 1.2028816452931017`, 41.55075768148098}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{1.205562895608084, 41.446440881535}, {1.2104984324220909`, + 41.254418747840184`}, {1.2264981435506106`, 40.59671690481822}, { + 1.2413673741773048`, 39.97484246280159}, {1.2554754673414465`, + 39.36280525816519}, {1.268822423043036, 38.76060529090903}, { + 1.2814082412820733`, 38.16824256103309}, {1.2932329220585586`, + 37.58571706853739}, {1.2992655091525593`, 37.27344895707759}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{1.301281054636046, 37.169117171745285`}, {1.304296465372491, + 37.013028813421926`}, {1.3145988712238716`, 36.450177795686685`}, { + 1.3241401396127, 35.89716401533168}, {1.3408857395246483`, + 34.81737487943436}, {1.3544797406302853`, 33.77038811840195}, { + 1.3624579347211427`, 32.99553194595931}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{1.363532315292604, 32.8911862246258}, {1.3649221429296108`, + 32.75620373223443}, {1.3722129464226245`, 31.774821720931826`}, { + 1.3737069851424102`, 31.522552660045047`}, {1.3749900576958953`, + 31.27232977004853}, {1.3759812349625555`, 30.28409045732634}, { + 1.3736539266244303`, 29.326830790810384`}, {1.3717963879300215`, + 28.774913201739423`}, {1.3714913662437465`, 28.717185341272476`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{1.3709400042085529`, 28.612835545613223`}, { + 1.3689306744469432`, 28.232553377722535`}, {1.3650567861751959`, + 27.699751318759713`}, {1.3601747231147796`, 27.176507024850963`}, { + 1.3473860726279392`, 26.15869173219567}, {1.3305647229864224`, + 25.179107499756654`}, {1.3146727021752485`, 24.439223030873784`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{1.3124318525091716`, 24.334895841479092`}, { + 1.3102774346454749`, 24.234592655636785`}, {1.2870909680603433`, + 23.321985527938935`}, {1.2610053232310272`, 22.4412861166631}, { + 1.2320205001575268`, 21.59249442180928}, {1.1993699663266277`, + 20.778507775549755`}, {1.1746425776762055`, 20.1631955959647}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{1.1704524234887075`, 20.058928504022386`}, { + 1.167397405979878, 19.98290796224163}, {1.1331388933995155`, + 19.216897999617697`}, {1.096901041590826, 18.479318954809052`}, { + 1.0393175560071022`, 17.414937267260242`}, {0.97970881613222, + 16.407506273963712`}, {0.9470757215035309, 15.890943338590052`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{0.9404966016567355, 15.786799692426383`}, { + 0.9193811647063893, 15.452554588893387`}, {0.85964094446982, + 14.545610826023198`}, {0.8009836839805076, 13.684872161453569`}, { + 0.7434415894066099, 12.870060663928626`}, {0.6876260199035819, + 12.098992286387864`}, {0.6527109424583515, 11.622702526725856`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{0.6450818014200863, 11.518630532120005`}, { + 0.6341483346268778, 11.369482981770775`}, {0.5831665951154305, + 10.679887114918717`}, {0.534579835698731, 10.02886671461697}, { + 0.48861087471807224`, 9.414699229720913}, {0.44548253051474695`, + 8.83566210908592}, {0.36758214368723335`, 7.776349606859256}, { + 0.3375581452637891, 7.3559262088693185`}}]}, + {Arrowheads[{{0.005977184805582084, 1.}}], + ArrowBox[{{0.33012496445705825`, 7.25184003458418}, {0.3005475777104635, + 6.837670500457238}, {0.24391889382623366`, 6.007370240696041}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{3.662177501068409, 49.028240396498525`}, {3.803583529581349, + 48.09430696972094}, {3.9429186269238428`, 47.198057460364524`}, { + 4.079993747411388, 46.338021730281355`}, {4.214619845359483, + 45.51272964132353}, {4.315774016081059, 44.90573532957899}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{4.33292735095522, 44.802803570840894`}, {4.346607875083623, + 44.72071105534313}, {4.475768790899307, 43.96049583419224}, { + 4.601913547122033, 43.230613839722956`}, {4.724661028457513, + 42.52919567203556}, {4.843699963105929, 41.85451711732192}, { + 4.958946070624479, 41.20532581657145}, {5.050612067722278, + 40.69093444996175}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{5.0689193428094255`, 40.58820165318728}, {5.070315070570358, + 40.5803694107736}, {5.177722682500765, 39.978395540917774`}, { + 5.281084625972898, 39.398151847993404`}, {5.380316620543952, + 38.83838597298993}, {5.475334385771126, 38.29784555689677}, { + 5.607599427641654, 37.530962460156616`}, {5.730158280389231, + 36.80165762018195}, {5.782890591963492, 36.47571834971359}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{5.799556429844104, 36.372706536303866`}, {5.842812300528163, + 36.10534130020226}, {5.945451130566394, 35.43946364645617}, { + 6.038018948288843, 34.801320951593844`}, {6.120459931480426, + 34.18820950826547}, {6.192780431775049, 33.59829634392677}, { + 6.255007166286044, 33.02862163997665}, {6.326733525694626, + 32.23322615113391}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{6.3348837266731115`, 32.129201994420114`}, { + 6.384503346902058, 31.36262169679778}, {6.413678580826118, + 30.577417021797316`}, {6.419703984186642, 29.815516508576927`}, { + 6.418958912917197, 29.714788992390215`}, {6.417807196246605, + 29.614380878041487`}, {6.399272200862874, 29.10477159692873}, { + 6.3703959794303335`, 28.59998786441578}, {6.320700022141414, + 27.960421208352315`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{6.312616031767383, 27.85638355673592}, {6.292517266068536, + 27.59772065797574}, {6.175557890157135, 26.605518909229296`}, { + 6.022005863339529, 25.61536735240541}, {5.883975062146253, + 24.87009674551967}, {5.728252430886634, 24.122298195706552`}, { + 5.641036533116933, 23.74036642895198}}]}, + {Arrowheads[{{0.012709842916010137`, 1.}}], + ArrowBox[{{5.617805444264102, 23.63863393480712}, {5.556330854214666, + 23.36942729486526}, {5.369703216784341, 22.608939634895012`}, { + 5.170150352386805, 21.84142338430829}, {4.9596176371772875`, + 21.06925675539658}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{7.223677525521819, 42.45604326642656}, {7.497133560630535, + 41.94542101834788}, {7.784543577477226, 41.47099433415936}, { + 8.071472584678805, 41.05871777105589}, {8.501269585321605, + 40.554542511029304`}, {8.935099171080322, 40.18135840847174}, { + 9.79142740754636, 39.830545392507595`}, {9.851358910686436, + 39.8227871657933}, {9.91160966135354, 39.81725945125586}, { + 10.165185553735444`, 39.85735712535744}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{10.26825613547345, 39.87365556192083}, {10.271050472398839`, + 39.87409742731391}, {10.648853098983556`, 40.01144895832334}, { + 11.102289170029579`, 40.22969418935258}, {11.588243147047937`, + 40.56655519199345}, {12.116508120877484`, 41.03623359794114}, { + 12.69687718235707, 41.65293103889084}, {13.342640093719977`, + 42.43815690621982}, {13.405612675925394`, 42.521353027528946`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{13.468591166752898`, 42.60455695500423}, { + 13.700676052894298`, 42.911175512878344`}, {14.077718426986106`, + 43.43062810440714}, {14.540649561283345`, 44.095373218007374`}, { + 15.044575080856061`, 44.8481740786198}, {15.595943335072297`, + 45.699815949708594`}, {15.819237737291155`, 46.05215417080202}}]}, + {Arrowheads[{{0.009085522653342167, 1.}}], + ArrowBox[{{15.87509731101342, 46.14029548845605}, {15.89143359684925, + 46.166072659014176`}, {16.201202673300102`, 46.66108409473791}, { + 16.52738197112422, 47.18855646435075}, {16.872510701029707`, + 47.75292152902761}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{20.12694150910278, 12.742035321552946`}, { + 19.475309313361567`, 13.106672712330523`}, {18.853322956339937`, + 13.456537053991413`}, {18.258963022182925`, 13.791422784066848`}, { + 17.71175053082192, 14.113317006421621`}, {17.183077090978163`, + 14.419307586081462`}, {16.677991242289075`, 14.709908429218304`}, { + 16.501539787699183`, 14.810404875828599`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{16.41086391515586, 14.862048558818186`}, {15.73858231837493, + 15.244940905922983`}, {14.881589832640975`, 15.718313211478819`}, { + 14.095079858648713`, 16.12992412082897}, {13.612015838254463`, + 16.36793659886111}, {13.15300527780204, 16.579761422848595`}, { + 12.699677697280075`, 16.76466222979054}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{12.603054580667838`, 16.804072345121}, {12.356914470045423`, + 16.904466645027618`}, {11.624195502125907`, 17.14325779402543}, { + 10.94573743961601, 17.299685205508997`}, {10.312429348088251`, + 17.377299215145282`}, {10.232191143929295`, 17.38231889691224}, { + 10.152608909785817`, 17.386050449557032`}, {9.811359184231767, + 17.37259402369173}, {9.48064527163832, 17.335479576279525`}, { + 8.875456256930349, 17.227003907543974`}, {8.538691590541408, + 17.11767233297943}}]}, + {Arrowheads[{{0.016923601674316276`, 1.}}], + ArrowBox[{{8.43943986827253, 17.0854499885445}, {8.302674686555187, + 17.04104879639124}, {7.75853969360489, 16.784246505361683`}, { + 7.239290411171504, 16.463229296995667`}, {6.743270438669417, + 16.083773147998258`}, {6.267498255044522, 15.656274816438579`}, { + 5.645413566862449, 14.98949921316205}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{36.479716132863196`, 0.4016323505227532}, {35.87546906212038, + 0.41067147157894923`}, {35.2814318928921, 0.41969872264618785`}, { + 34.697407923088, 0.4287077903131379}, {34.123200450617716`, + 0.43769236116846894`}, {33.55861277339086, 0.44664612180085017`}, { + 33.00344818931709, 0.4555627587989509}, {32.3061777067387, + 0.4669580480252763}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{32.20184038694285, 0.4686632025755976}, {31.920601492267284`, + 0.47325940824698837`}, {31.27065455267774, 0.48404207226579526`}, { + 30.633104443674384`, 0.4947028220270601}, {30.007701606745016`, + 0.505234380398115}, {29.394196483377435`, 0.5156294702462919}, { + 28.792339515059435`, 0.525880814438923}, {28.20188114327882, + 0.5359811358433402}, {28.02838236709559, 0.5389586962927787}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{27.924046478658035`, 0.5407492934468509}, { + 27.622571809523382`, 0.5459231573268756}, {27.075457614988743`, + 0.5563205837445278}, {26.525725147222868`, 0.5661582550891151}, { + 25.986642600457774`, 0.5758230722474847}, {24.94042726992993, + 0.5946341440055707}, {23.93681162340521, 0.6127537990187855}, { + 23.750677476741124`, 0.6161293831760191}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{23.646343380069148`, 0.6180215052293723}, { + 22.975795660883612`, 0.6301820372871292}, {22.054029160036304`, + 0.6468462373138664}, {21.168161898534446`, 0.6626737776022614}, { + 20.318193876378043`, 0.6776646581523145}, {19.504125093567083`, + 0.6918188789640256}, {19.472955323276842`, 0.6923513546365635}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{19.36861929415349, 0.6941337353458237}, {18.86388165900055, + 0.702756208634227}, {18.244873342382046`, 0.7130993261897992}, { + 17.26723730956536, 0.7288480725635298}, {16.342410706324333`, + 0.7429515518870157}, {15.467571425333125`, 0.7554165158637226}, { + 15.195075762775167`, 0.7589831373437188}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{15.090733447794502`, 0.7603488454742231}, { + 14.639897359265905`, 0.7662497161971161}, {14.043604128476263`, + 0.773380797882648}, {13.47070993833581, 0.7796253755194875}, { + 12.395118680002474`, 0.7894550186470898}, {11.405799273712331`, + 0.795919387444197}, {10.916867850228805`, 0.7976808819587541}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{10.812517275160651`, 0.7980568303162228}, { + 10.495427408911816`, 0.7991992237750833}, {10.324281086477587`, + 0.7995308600687618}, {10.155927515927576`, 0.7997480120600583}, { + 9.814971458543933, 0.7994846727439558}, {9.48545402611965, + 0.7987519072343788}, {8.700078792955896, 0.7956200578521103}, { + 7.979577289538006, 0.7898617345668076}, {7.318761293014036, + 0.7817477286146144}, {6.712442580532048, 0.7715488312316741}, { + 6.638656763119474, 0.7697755977114633}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.534335631573717, 0.767268534243034}, {5.6458847866064135`, + 0.7459171299406784}, {4.903257829353509, 0.7205622578828108}, { + 4.258261404296697, 0.6925638640323629}, {3.2064010428146545`, + 0.6320612542363377}, {2.4122560278133154`, 0.569253782633929}, { + 2.3660459649395396`, 0.5644851764411436}}]}, + {Arrowheads[{{0.004872495342548926, 1.}}], + ArrowBox[{{2.262245933548732, 0.5537736248500198}, {1.814219003441145, + 0.5075398856906186}, {1.2527186891481723`, 0.43247365957612666`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{33.284228421357426`, 4.35668445327842}, {32.3548236467046, + 4.525354326233555}, {31.4574447764906, 4.6933871755879535`}, { + 30.590857468477452`, 4.860514984317108}, {29.75382738042721, + 5.026469735396508}, {29.18487102691367, 5.142211378645766}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.08261417107948, 5.163013284547095}, {28.945120170101927`, + 5.190983411801643}, {28.163501495263645`, 5.353787996508002}, { + 27.40773701367442, 5.5146154724910765`}, {26.676592383096292`, + 5.673197822726358}, {25.697837651698613`, 5.888866038794643}, { + 25.00264063250247, 6.043924839235834}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{24.90079202305755, 6.066641454484549}, {24.758626133029896`, + 6.098350555304389}, {23.856862719588257`, 6.301259730772988}, { + 23.01280011722511, 6.50137943286567}, {22.196757636330634`, + 6.6931614072454595`}, {21.413973045659496`, 6.87758475761888}, { + 20.83576072353346, 7.014178966388414}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{20.73420477549139, 7.0381700745641105`}, { + 20.664446345211708`, 7.0546494839859335`}, {19.948177534987263`, + 7.224355586346618}, {19.26186318643962, 7.3862607462924075`}, { + 18.602199871022247`, 7.539922645414778}, {17.96918758873514, + 7.685341283713729}, {17.362826339578294`, 7.822516661189262}, { + 16.784816535282708`, 7.950575932596747}, {16.666932585984405`, + 7.975958396190243}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{16.564919291393842`, 7.997923631927681}, { + 16.229123684760538`, 8.070226263549376}, {15.220516434634007`, + 8.275902753460873}, {14.282481299946859`, 8.450596509954092}, { + 13.408809849892174`, 8.594833807739283}, {12.593293653663034`, + 8.709140921526695}, {12.456062416612525`, 8.724105969130257}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{12.352326150623574`, 8.73541839472742}, {11.678164666393682`, + 8.808935612241642}, {10.832448207959695`, 8.868355476245918}, { + 10.69738135222392, 8.874889307498668}, {10.56403984719346, + 8.880367009258485}, {10.210638758667116`, 8.884980790230737}, { + 9.86901587011006, 8.882132568164712}, {9.113633723761886, + 8.857554833792474}, {8.41472106320831, 8.796888172702165}, { + 8.190022081807298, 8.764485188453454}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{8.086739209386847, 8.749591158817296}, {7.767474971064815, + 8.703551279058951}, {7.1670925299468875`, 8.580962847027996}, { + 6.610544131265691, 8.43194683385523}, {6.09237647956132, + 8.261586362583335}, {5.374377788568465, 7.960988960643618}, { + 4.732639870181266, 7.626415050507472}, {4.210241833388427, + 7.3018665988777}}]}, + {Arrowheads[{{0.013203088989000106`, 1.}}], + ArrowBox[{{4.123313960110224, 7.24425625523851}, {3.644409163090605, + 6.896268822264425}, {3.1873653005643283`, 6.5154543022109275`}, { + 2.781693542612774, 6.132629472051729}, {2.10514849933814, + 5.381565778183589}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{25.270552352601207`, 8.178002954716998}, { + 24.607671521889493`, 8.405565201082126}, {23.968933060077035`, + 8.629162352359591}, {23.35316031645023, 8.848550580614702}, { + 22.759176640295458`, 9.063486057912769}, {22.185805380899122`, + 9.273724956319104}, {21.410379599566216`, 9.56053530264626}, { + 21.341360238016392`, 9.586156042520043}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{21.243531788515007`, 9.622471030092353}, { + 20.667770330847855`, 9.836199963611852}, {19.95598244545731, + 10.10041690650925}, {19.294302193166306`, 10.356105780835886`}, { + 18.654465242412833`, 10.598987789914487`}, {18.04145941641372, + 10.82981801551163}, {17.455284715168958`, 11.048596457627319`}, { + 17.336903254417834`, 11.092348821744688`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{17.23902307807133, 11.128524157715475`}, { + 16.895941138678555`, 11.255323116261549`}, {16.36040748895613, + 11.449794059404466`}, {15.84566256801531, 11.631805355046215`}, { + 14.878538912478481`, 11.9584490038262}, {14.376393423169754`, + 12.118077650687214`}, {13.895231083128445`, 12.262553717369887`}, { + 13.275968534820485`, 12.433677535927297`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{13.174704355775432`, 12.45885358200318}, {12.6682401053037, + 12.583025127698345`}, {12.102885623176297`, 12.701953579426151`}, { + 11.565976007269615`, 12.794191187469032`}, {10.770459427667948`, + 12.888129482114566`}, {10.03216977693193, 12.921162980062356`}, { + 9.928666816444826, 12.921539421395678`}, {9.826233962623142, + 12.920703998279134`}, {9.495000372803677, 12.900796186137324`}, { + 9.174345566929613, 12.868311339607068`}, {9.045750216221387, + 12.849638839928458`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{8.94248194290329, 12.834643921451832`}, {8.49385914976217, + 12.769502305408873`}, {7.859442430027147, 12.615619645837397`}, { + 7.267015142392209, 12.412372820306981`}, {6.712497021525018, + 12.16547128823197}, {6.193609150208173, 11.879610168173011`}, { + 5.70624947745035, 11.563240673539275`}, {5.186719874123697, + 11.154369701133044`}}]}, + {Arrowheads[{{0.00030816743784531044`, 1.}}], + ArrowBox[{{5.104717905716634, 11.089833966601011`}, {5.05417723271208, + 11.05005834268061}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{36.190296044951495`, 2.278988599990219}, { + 35.192676218892515`, 2.369765546014048}, {34.225910718792655`, + 2.460493451038834}, {33.28885886367611, 2.5509943594550206`}, { + 32.38037997256709, 2.6410903156530523`}, {32.03520907481531, + 2.6761591746478217`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{31.93139225916488, 2.686706811464959}, {31.499333364489786`, + 2.7306033640233744`}, {30.644578358468404`, 2.8193555489564295`}, { + 30.04954921020404, 2.8820694891286935`}, {29.466241613991087`, + 2.9441179678805156`}, {28.894387809846, 3.005462874619257}, { + 28.33372003778525, 3.06606609875228}, {27.78397053782529, + 3.125889529686947}, {27.780560906655122`, 3.126262721047158}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{27.676829145691617`, 3.137616382202573}, { + 27.244871549982594`, 3.1848950568306202`}, {26.22040292264331, + 3.303552061279532}, {25.229968024299886`, 3.4177179116000556`}, { + 24.27892205462306, 3.528154819644949}, {23.530267123775417`, + 3.615783654985654}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{23.42662343213255, 3.62791497959844}, {23.36726501361283, + 3.6348627854142115`}, {22.494996901269204`, 3.737841808907844}, { + 21.658628200878713`, 3.8367001846125817`}, {20.8546693957279, + 3.9310462070151617`}, {20.08312048581676, 4.0208798761155835`}, { + 19.343981471145298`, 4.106201191913848}, {19.280904109575246`, + 4.113389484966046}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{19.1772239261019, 4.125204873624692}, {18.706497975308356`, + 4.178848780049356}, {18.09167797889866, 4.24761146035275}, { + 17.37483257638206, 4.325604438013289}, {16.68688165632021, + 4.397739431963119}, {16.02782521871311, 4.464016442202238}, { + 15.397663263560764`, 4.524435468730647}, {15.025788482097589`, + 4.558078648041699}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{14.921861665902803`, 4.567480814272791}, { + 14.793781139325171`, 4.579068145107517}, {14.213564194468344`, + 4.6279861048920194`}, {13.65701242899028, 4.6711893480841535`}, { + 13.124125842890981`, 4.708677874683921}, {12.119247816814715`, + 4.767486545988051}, {11.19284931346906, 4.805120729975748}, { + 11.030895920565133`, 4.810058227118876}, {10.8713171668112, + 4.81432972535928}, {10.75601153632908, 4.81593300512951}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{10.651670370117776`, 4.817383828305181}, { + 10.508495403501266`, 4.819374620312647}, {10.157803780771825`, + 4.820943996958636}, {9.346482864974295, 4.815469019032042}, { + 8.599515921588882, 4.7914946268532095`}, {7.911641771615255, + 4.750755480994464}, {7.277599236053081, 4.69498624202813}, { + 6.693851357343197, 4.625608623343333}, {6.488073628743292, + 4.594950115790393}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.384861616594407, 4.579572716712511}, {6.154031611879116, + 4.545181709040498}, {5.386603777370995, 4.39540333541825}, { + 4.711359050168454, 4.226500485928004}, {4.11496450113375, + 4.044650166579768}, {3.5903213200267814`, 3.853707066400027}, { + 2.724368460869932, 3.45983837826572}, {2.4401935092996707`, + 3.2928924492504383`}}]}, + {Arrowheads[{{0.001616949458014049, 1.}}], + ArrowBox[{{2.3502197485019285`, 3.240035035180768}, { + 2.0592537009871386`, 3.069099501116813}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{50., 16.927683874390233`}, {49.9085258402617, + 17.06782331794245}, {49.60134528278074, 17.570553536300356`}, { + 49.30827235130409, 18.08416196275136}, {49.029352030259666`, + 18.60894478811419}, {48.61712579644272, 19.461973258711016`}, { + 48.24046421926981, 20.3446945235371}, {48.12710397795115, + 20.64903818988108}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{48.090680417116744`, 20.74682626722369}, {47.89995745562148, + 21.25886933172532}, {47.59619566237826, 22.206258432408568`}, { + 47.329235224753326`, 23.187797036860847`}, {47.09955954529376, + 24.20508078664326}, {46.99908807827641, 24.727986901834374`}, { + 46.992345173418954`, 24.767607240761173`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{46.97483758080441, 24.87047933637055}, {46.90839930688091, + 25.260861076319355`}, {46.827647066467435`, 25.804047234418643`}, { + 46.75698519239615, 26.357889300452676`}, {46.69607454392253, + 26.92188897036574}, {46.64475524434011, 27.495854204966165`}, { + 46.603450025066174`, 28.080588325870487`}, {46.572581617518004`, + 28.67689465469524}, {46.56128821779805, 29.020446761880407`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{46.55785978827449, 29.12474167894363}, {46.55257275311288, + 29.285576513056956`}, {46.54384616326808, 29.90743722257217}, { + 46.54682457940089, 30.543280104857413`}, {46.56193073292859, + 31.193908481529217`}, {46.60074066194667, 32.06841127159385}, { + 46.66204374433008, 32.97165599175458}, {46.69130331353067, + 33.294198238671214`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{46.70073087406533, 33.398122754338054`}, { + 46.746739071145974`, 33.90529314913227}, {46.84613542874499, + 34.853367841558395`}, {46.97296994057879, 35.83926225324546}, { + 47.12499487897946, 36.85885011639126}, {47.21045375814236, + 37.38127909226118}, {47.23724112915973, 37.53625602308441}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{47.25501443364049, 37.63908254447873}, {47.302210243946966`, + 37.912131430995785`}, {47.4002643363933, 38.45140713259508}, { + 47.50461603548134, 38.99910619705906}, {47.61591469445789, + 39.55637347306148}, {47.73480966656976, 40.124353809276094`}, { + 47.861300951816936`, 40.703047205702916`}, {47.99538855019942, + 41.29245366234194}, {48.097844841853195`, 41.7264198027947}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{48.12182223701982, 41.82797898935725}, {48.13707246171722, + 41.892573179193164`}, {48.28635268637032, 42.5034057562566}, { + 48.44322922415874, 43.12495139353223}, {48.607702075082464`, + 43.757210091020056`}, {48.88518382325472, 44.808648426427176`}, { + 49.03538095657439, 45.35087077467897}, {49.17805395600637, + 45.865930463731004`}}]}, + {Arrowheads[{{0.012644001720598238`, 1.}}], + ArrowBox[{{49.20792368938321, 45.9659072381097}, {49.42363453613884, + 46.66881048528552}, {49.661690982383625`, 47.44452784764029}, { + 49.9309249016575, 48.26676300126804}, {50., 48.482957315927486`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{12.565916046932262`, 20.60570641946029}, {12.2123917131082, + 20.833871506624245`}, {11.876577004601629`, 21.031142440303277`}, { + 10.939149459576333`, 21.45006494135886}, {10.103358364970097`, + 21.607336644331554`}, {10.05034315202163, 21.60943094596297}, { + 9.997619283949339, 21.610451041028742`}, {9.659635899296376, + 21.565111216597902`}, {9.329751950939706, 21.47587622049211}, { + 8.698856689190954, 21.177150711403073`}}]}, + {Arrowheads[{{0.004124750181173024, 1.}}], + ArrowBox[{{8.604543597199726, 21.13249397021794}, {8.361564965429825, + 21.017444896506355`}, {7.895113454608308, 20.652898851426308`}}]}}}}, + AspectRatio->1, + Frame->True, + Method->{"TransparentPolygonMesh" -> True}, + PlotRange->{{-1.0878130721773847`, + 51.08781307217738}, {-1.0878130721773847`, 51.08781307217738}}, + PlotRangeClipping->True, + PlotRangePadding->{ + Scaled[0.02], + Scaled[0.02]}]], "Output", + CellChangeTimes->{{3.514689734268895*^9, 3.514689750969233*^9}, + 3.514690222263288*^9, {3.5146902854170923`*^9, 3.5146902918855658`*^9}, { + 3.51469045235388*^9, 3.514690497597476*^9}, 3.514690765392665*^9, + 3.514691032330944*^9, 3.514691256236397*^9, {3.514691300889327*^9, + 3.514691328431656*^9}, 3.514692576408132*^9, + 3.6204255096876917`*^9},ExpressionUUID->"fbbe5a33-6a67-4d3a-b953-\ +c482a45846e5"] +}, Open ]], + +Cell["In versions 6 and 7, we need to load a vector field package:", "Text", + CellChangeTimes->{{3.514690879569215*^9, + 3.5146908964889593`*^9}},ExpressionUUID->"2ab298f9-b4b2-4ee9-8dc7-\ +adc4cf6fa455"], + +Cell[BoxData[ + RowBox[{"Needs", "[", "\"\\"", "]"}]], "Input", + CellChangeTimes->{{3.514689470896014*^9, 3.514689498745194*^9}, { + 3.5146895545698643`*^9, 3.5146895643325367`*^9}, {3.514689637395935*^9, + 3.514689654063842*^9}, {3.5146896842742357`*^9, + 3.514689684696374*^9}},ExpressionUUID->"0e1e16b7-3f89-4782-abbb-\ +905a073ff66c"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"?", "PlotVectorField"}]], "Input",ExpressionUUID->"22a073d9-aeff-41f3-94fa-5757aea7c239"], + +Cell[BoxData[ + StyleBox["\<\"PlotVectorField[f, {x, x0, x1, (xu)}, {y, y0, y1, (yu)}, \ +(options)] produces a vector field plot of the two-dimensional vector \ +function f.\"\>", "MSG"]], "Print", "PrintUsage", + CellChangeTimes->{3.5146899473380747`*^9}, + CellTags-> + "Info3514664747-5819389",ExpressionUUID->"818115c5-a869-4c3c-82fb-\ +74819af00235"] +}, Open ]], + +Cell[BoxData[ + RowBox[{"plot2", "=", + RowBox[{"PlotVectorField", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"eqnc", "-", + RowBox[{"nc", "[", "t", "]"}]}], "/.", + RowBox[{"rc", "\[Rule]", "0.6"}]}], "/.", + RowBox[{"rd", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"\[Rho]c", "\[Rule]", "0.02"}]}], "/.", + RowBox[{"\[Rho]d", "\[Rule]", "0.03"}]}], ")"}], ",", + RowBox[{"(", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"eqnd", "-", + RowBox[{"nd", "[", "t", "]"}]}], "/.", + RowBox[{"rc", "\[Rule]", "0.6"}]}], "/.", + RowBox[{"rd", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"\[Rho]c", "\[Rule]", "0.02"}]}], "/.", + RowBox[{"\[Rho]d", "\[Rule]", "0.03"}]}], ")"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"nc", "[", "t", "]"}], ",", "0", ",", "400"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"nd", "[", "t", "]"}], ",", "0", ",", "400"}], "}"}], ",", + RowBox[{"Frame", "\[Rule]", "True"}], ",", + RowBox[{"ScaleFactor", "\[Rule]", "100"}], ",", + RowBox[{"AspectRatio", "\[Rule]", "1"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"-", "5"}], ",", "410"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"-", "5"}], ",", "410"}], "}"}]}], "}"}]}]}], + "]"}]}]], "Input", + CellChangeTimes->{{3.5145676201702843`*^9, 3.514567651403167*^9}, { + 3.5146893667697697`*^9, 3.514689375103918*^9}, 3.514689681645629*^9, { + 3.514689864226651*^9, 3.514689866402212*^9}, {3.514689908362763*^9, + 3.51468992408733*^9}, 3.514689963971136*^9, {3.514690112116742*^9, + 3.5146901662622538`*^9}, {3.514690870326766*^9, 3.514690873310856*^9}, + 3.5146912794095182`*^9, 3.514691363944281*^9, {3.514692282992526*^9, + 3.5146922849474792`*^9}, {3.5146939941537743`*^9, + 3.5146939971218348`*^9}, {3.620424815049876*^9, 3.620424841354966*^9}, { + 3.620424974591536*^9, 3.620424987756938*^9}, {3.6204255348243856`*^9, + 3.620425537454911*^9}},ExpressionUUID->"512d3847-ba75-4547-b516-\ +141563d99487"], + +Cell["In either version, we can add the equilibria:", "Text", + CellChangeTimes->{{3.51469094557574*^9, + 3.5146909544600782`*^9}},ExpressionUUID->"3e484052-b27f-4ca2-831c-\ +d6f6e7417e01"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"plot3", "=", + RowBox[{"Show", "[", + RowBox[{"plot2", ",", "\[IndentingNewLine]", + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"0", ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + FractionBox["rd", "\[Rho]d"], ",", + FractionBox["rc", "\[Rho]c"]}], "}"}]}], "}"}], "/.", + RowBox[{"rc", "\[Rule]", "0.6"}]}], "/.", + RowBox[{"rd", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"\[Rho]c", "\[Rule]", "0.02"}]}], "/.", + RowBox[{"\[Rho]d", "\[Rule]", "0.03"}]}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{ + RowBox[{"PointSize", "[", "0.03", "]"}], ",", "Red"}], "}"}]}]}], + "]"}]}], "\[IndentingNewLine]", "]"}]}]], "Input", + CellChangeTimes->{{3.514692624128381*^9, 3.5146926249974747`*^9}, { + 3.514694222481324*^9, 3.514694224070882*^9}, {3.620424835155098*^9, + 3.620424841438464*^9}, {3.620424974593631*^9, 3.620424987841607*^9}, + 3.620425551823457*^9},ExpressionUUID->"349b7749-c444-475c-84c9-\ +b83e0eecc762"], + +Cell[BoxData[ + GraphicsBox[{{{}, { + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{50., 5.255627689465548}, {49.07164643991514, + 5.49929454502681}, {48.101654752431905`, 5.768012892194103}, { + 47.16122726915955, 6.042593697561616}, {46.24934810020415, + 6.322803191864825}, {45.98853990724681, 6.407032564076382}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{45.889238795161646`, 6.43910237843306}, {45.36500135567175, + 6.608407605839203}, {44.58598393311282, 6.871537687447511}, { + 43.826982442039586`, 7.138509574582958}, {43.08753418321806, + 7.4092143791227985`}, {42.36717645741425, 7.683543212944289}, { + 41.95989638425604, 7.844802289610991}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{41.86287349110899, 7.88321767792867}, {41.66544656539418, + 7.9613871879246805`}, {40.981881807923834`, 8.242637415941228}, { + 40.316019485769246`, 8.527185008871188}, {39.70688056766348, + 8.824212865066134}, {39.089918510465075`, 9.118531091403003}, { + 38.489733490114446`, 9.415928906407792}, {38.0742600869078, + 9.62991358440455}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{37.9814901997972, 9.677693621027696}, {37.90632550661159, + 9.716406310080501}, {37.3396945599565, 10.019963302421127`}, { + 36.78984065014919, 10.32659988342967}, {36.25676377718965, + 10.636316053106134`}, {35.740463941077884`, 10.949111811450518`}, { + 35.2409411418139, 11.264987158462816`}, {34.75670439677487, + 11.583629558431436`}, {34.40465234828942, 11.823920403928765`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{34.31846359879082, 11.882747976665446`}, {34.286262723338, + 11.904726475644786`}, {33.829616121503285`, 12.228277910102857`}, { + 33.38676459127073, 12.554283861805654`}, {32.54244674561208, + 13.213659316945424`}, {31.75330918636206, 13.882852841064095`}, { + 31.21003027705684, 14.377806997593897`}, {31.077247248736626`, + 14.506056736923023`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{31.00218964042387, 14.578551835299333`}, { + 30.692638150616993`, 14.877535059126219`}, {29.975257805378966`, + 15.62215230541692}, {29.309812325343447`, 16.37682786720651}, { + 28.69413730331939, 17.141603879322957`}, {28.26741617616755, + 17.723705972626668`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{28.205721092727792`, 17.807865942526753`}, { + 28.12606833211576, 17.916522476594224`}, {27.618068132766822`, + 18.67887970316737}, {27.150334054790395`, 19.452211247189897`}, { + 26.722866098186476`, 20.236517108661797`}, {26.33566426295506, + 21.031797287583075`}, {26.160672214451445`, 21.43732678808643}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{26.119328106854564`, 21.533138314643725`}, { + 25.986887720780615`, 21.840057880820073`}, {25.674695643347604`, + 22.66330498523914}, {25.399088030656024`, 23.501538600840274`}, { + 25.160064882705875`, 24.354758727623476`}, {25.077623137676905`, + 24.67623029415256}, {25.000130980593386`, 25.000173926194417`}, { + 24.90713673871171, 25.517801018623775`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{24.888684934653096`, 25.620507955006886`}, { + 24.849004956355706`, 25.841375735399907`}, {24.729767986718073`, + 26.70365873558932}, {24.630530483798537`, 27.542736266356243`}, { + 24.56160354012163, 28.405466030731965`}, {24.52298715568735, + 29.291848028716487`}, {24.518592434839327`, 29.77335905473906}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{24.517640067189014`, 29.877705961018453`}, { + 24.514681330495694`, 30.2018822603098}, {24.538789509441692`, + 31.141564545156765`}, {24.597415137420363`, 32.11689070290223}, { + 24.690558214431714`, 33.12786073354619}, {24.80165046951396, + 34.0386410847478}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{24.814285052363417`, 34.14222463156119}, { + 24.818218740475743`, 34.17447463708866}, {24.97467432311375, + 35.24437486775083}, {25.07876922741073, 35.820598892969294`}, { + 25.19235185283169, 36.40758751827921}, {25.315708318998553`, + 37.0059586209695}, {25.44912474553326, 37.61633007832912}, { + 25.59288725205775, 38.239319767647004`}, {25.59330124435526, + 38.241025736631784`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{25.617910209544327`, 38.34243373772906}, { + 25.747281958193952`, 38.87554556621209}, {25.940101598568962`, + 39.628438210109316`}, {26.150846742815112`, 40.406028023594665`}, { + 26.380551777227023`, 41.210330103819174`}, {26.630251088099318`, + 42.04335954793386}, {26.730898099824202`, 42.36447915704206}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{26.76210739782475, 42.46405407141579}, {26.900979061726613`, + 42.90713145308976}, {27.193770084403532`, 43.803660916437906`}, { + 27.50965854242469, 44.73496303512932}, {27.849678822084716`, + 45.70305290631504}, {28.108387715178683`, 46.414587587559254`}}]}, + {Arrowheads[{{0.017918567746579475`, 1.}}], + ArrowBox[{{28.144045259149596`, 46.51265757997378}, { + 28.216935285765725`, 46.71312916498169}, {28.412055705910014`, + 47.23601123263495}, {28.61516921156907, 47.77136999621915}, { + 28.826524522727077`, 48.319641008522545`}, {29.046370359368215`, + 48.881259822333355`}, {29.27495544147667, 49.45666199043983}, { + 29.493879886714133`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{50., 3.046754492416481}, {49.30691551877229, + 3.1421248170699143`}, {48.549210363966736`, 3.249990429378931}, { + 47.80628351324313, 3.359339012067691}, {47.07786923727012, + 3.4701203299368584`}, {46.36370180671632, 3.582284147787095}, { + 45.87167489311794, 3.662029101277047}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{45.76866777190582, 3.678723915855624}, {45.6633042957297, + 3.695800635187409}, {44.9762365082879, 3.8106364130514456`}, { + 44.30228780980407, 3.9267359231968193`}, {43.641247565691394`, + 4.044043607441145}, {42.99290514136307, 4.162503907602034}, { + 42.35704990223227, 4.282061265497096}, {41.73347121371217, + 4.4026601229439475`}, {41.66063423036925, 4.417142028088762}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{41.55828637224961, 4.437491470158391}, {41.12195844121596, + 4.524244921760202}, {40.522300950156804`, 4.646760103763471}, { + 39.934288105947914`, 4.770150110771365}, {39.35770927400245, + 4.8943593846015}, {38.792353819733584`, 5.019332367071488}, { + 38.23801110855452, 5.145013499998943}, {37.694470505878414`, + 5.271347225201477}, {37.479558112687755`, 5.323145855371648}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{37.37811185657169, 5.3475966421536025`}, { + 36.638953087687874`, 5.525750219702228}, {35.62389307929084, + 5.782090005760034}, {34.64746323451677, 6.039917740144682}, { + 33.708100336221975`, 6.2987927097723135`}, {33.34043127306272, + 6.404343795902534}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{33.240131355765655`, 6.433138073883139}, { + 32.804241167262745`, 6.558274201559078}, {31.93432251049537, + 6.817921502421122}, {31.096781148776145`, 7.077293899274592}, { + 30.290053864961354`, 7.335950679035637}, {29.512577441907304`, + 7.593451128620401}, {29.25733037242637, 7.680680108899937}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.158586035090803`, 7.714425326314875}, { + 28.511300778753974`, 7.9356307371157095`}, {27.5533564203355, + 8.273029929405732}, {26.636332618351013`, 8.605011992601364}, { + 25.783542939708855`, 8.937731817963966}, {25.240519622252435`, + 9.151871130418568}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{25.143443822445573`, 9.190152626550253}, { + 24.960820950146804`, 9.262169306231199}, {24.174196020417014`, + 9.579916239625828}, {23.42366815051949, 9.890972618147854}, { + 22.709237340454223`, 10.195338441797277`}, {22.02708273344312, + 10.492132512118648`}, {21.373383472708078`, 10.780473630656516`}, { + 21.298560537511758`, 10.813967845760393`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{21.203316680414655`, 10.85660341236257}, { + 20.748139558249093`, 11.060361797410883`}, {20.151350990066174`, + 11.331797012381745`}, {19.474857884757967`, 11.643480355238204`}, { + 18.831665723816883`, 11.941936884140334`}, {17.889821661434798`, + 12.37886126421555}, {17.410684364456777`, 12.599672002780904`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{17.315912879115317`, 12.643347504156335`}, { + 17.015519686801376`, 12.781783904480829`}, {16.20218071411488, + 13.150189024441007`}, {15.44322565757358, 13.483560843600925`}, { + 14.54590587797527, 13.85748882834175}, {13.717912173088807`, + 14.174718438279013`}, {13.58614702264218, 14.222698900770094`}, { + 13.470835248789541`, 14.263855968418307`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{13.371651504542532`, 14.296265258562856`}, {13.017694469461, + 14.410053144819937`}, {12.596846456225402`, 14.532352313975206`}, { + 11.859950820294307`, 14.723971973931429`}, {11.173288862944805`, + 14.855946636067003`}, {10.531131397563858`, 14.930933414451436`}, { + 9.92774923753843, 14.951589423154232`}, {9.35975694271045, + 14.920495792063443`}, {9.276367203284325, 14.908390923012659`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{9.173098293260882, 14.893400390107127`}, {8.821060720795387, + 14.842298554977567`}, {8.066659539361678, 14.637970703786886`}, { + 7.366263444900198, 14.344221402127282`}, {6.711521814512744, + 13.973892822186267`}, {6.100322506916809, 13.537647643011448`}, { + 5.529251860062621, 13.0468851667233}, {5.514332818344818, + 13.031918620930668`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{5.4406627207951255`, 12.958013948674845`}, { + 4.996713931940981, 12.512651571945206`}, {4.500855089220485, + 11.945702274813412`}, {4.0404728672678, 11.35632536722847}, { + 3.670711747917073, 10.836353765561283`}, {3.325970938073047, + 10.311000265948131`}, {3.0055039585738204`, 9.785939084975231}, { + 2.9247666496529856`, 9.64479825776259}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{2.872952616238303, 9.55421961902517}, {2.708564330257488, + 9.266844439228795}, {2.4343708708490444`, 8.756721478898363}, { + 2.18212256772314, 8.257050173375378}, {1.9510431961923551`, + 7.771216968048902}, {1.7403565315692708`, 7.302608308308005}, { + 1.3754465083471559`, 6.4199885973137185`}, {1.1337458433457925`, + 5.765980003531753}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{1.0975722251644244`, 5.668099192328073}, { + 1.0779628686587033`, 5.615038983854077}, {0.8387603087711567, + 4.891910419754798}, {0.648172892642414, 4.247745960293024}, { + 0.49777222254129183`, 3.6795828400670922`}, {0.38010712289285203`, + 3.1808485247222476`}, {0.21821852342122994`, 2.3670752012957825`}, { + 0.12319313918665568`, 1.7547993248906482`}, {0.10716134137378217`, + 1.6211922973337174`}}]}, + {Arrowheads[{{0.006901193386245247, 1.}}], + ArrowBox[{{0.09472918763697008, 1.5175842599636071`}, { + 0.07030775321242456, 1.3140590346442143`}, {0.03980150451054112, + 0.982829355931863}, {0.022364466090688092`, 0.7345808087588179}, { + 0.012475050897473553`, 0.5488158092569115}, {0.0070971341252142545`, + 0.41482425570352494`}, {0.004042384116633057, 0.31351763341181166`}, { + 0.002296973446982666, 0.23693643132798137`}, {0.0012989393312688657`, + 0.1790536109198805}, {0.000576397485540716, 0.12064568500470597`}, { + 0.000215303600311363, 0.08121294442028855}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{50., 9.467092475873057}, {49.807348435733154`, + 9.57162462921928}, {49.0682298090966, 9.998001889687844}, { + 48.35637340268402, 10.434920491978248`}, {47.67177921649541, + 10.882380436090495`}, {47.111981052667645`, 11.271838386982596`}, { + 46.57021741408454, 11.669178906329964`}, {46.49514432783939, + 11.726867108256133`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{46.41240090003064, 11.790449409320821`}, {46.09485542211006, + 12.034459993769223`}, {45.63372685980081, 12.406100191279108`}, { + 45.18671336128773, 12.784203076096052`}, {44.753696560701755`, + 13.168872225456479`}, {44.33455809217379, 13.560211216596821`}, { + 43.92917958983478, 13.958323626753511`}, {43.53744268781565, + 14.363313033162978`}, {43.32671368808493, 14.592850009817711`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{43.25614274523294, 14.669719547862398`}, { + 43.159229020247324`, 14.77528301306165}, {42.79423229500632, + 15.193942246371215`}, {42.44221455678894, 15.619143012036906`}, { + 42.103159944955785`, 16.051204285830465`}, {41.77705259886748, + 16.49044504352364}, {41.463876657884605`, 16.937184260888166`}, { + 41.163616261367785`, 17.391740913695795`}, {40.87625554867761, + 17.854433977718266`}, {40.779597110659154`, 18.020351310255176`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{40.72706890854821, 18.110517666714856`}, { + 40.601778659174705`, 18.325582428727333`}, {40.221572001861695`, + 19.033996670486225`}, {39.868795929002914`, 19.762457386972137`}, { + 39.543577668418564`, 20.511926077563757`}, {39.24468735117998, + 21.273108248267175`}, {39.02431433389426, 21.913258616073758`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{38.99034756293841, 22.011926961175188`}, {38.97392737140676, + 22.059625140280357`}, {38.73097965954838, 22.8690730051566}, { + 38.51584421560486, 23.701451842895906`}, {38.328521039576174`, + 24.556761653498278`}, {38.169912156873075`, 25.437861075016585`}, { + 38.07895536317184, 26.07935333348483}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{38.06430598757423, 26.182671190841734`}, {38.04091959290628, + 26.3476087455037}, {37.94154334767579, 27.28600466495962}, { + 37.87178342118161, 28.25304883338435}, {37.83923092998787, + 28.834394700560594`}, {37.817533088819154`, 29.42701002563941}, { + 37.82903198982552, 30.345931668700178`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{37.831161711623764`, 30.450252390569048`}, { + 37.8730242934231, 31.452433909680416`}, {37.92994341213175, + 32.463528122199165`}, {38.01781164150515, 33.51246227009787}, { + 38.07335167269113, 34.0511193198147}, {38.136628981543296`, + 34.599236353376526`}, {38.13819831135887, 34.61155807882468}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{38.15138228174712, 34.715073134633116`}, {38.20764356806165, + 35.15681337078334}, {38.286395432246195`, 35.723850372035145`}, { + 38.373748505041405`, 36.30197529694237}, {38.47056671739176, + 36.892816085315474`}, {38.576850069297265`, 37.496372737154445`}, { + 38.69259856075791, 38.11264525245929}, {38.8178121917737, + 38.741633631229995`}, {38.836633570134346`, 38.831311895202624`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{38.85806749072204, 38.93343814502343}, {38.95249096234463, + 39.38333787346657}, {39.096634872470716`, 40.03775797916902}, { + 39.250243922151945`, 40.704893948337336`}, {39.39441174651897, + 41.351147680618716`}, {39.57874532800328, 42.0646746932398}, { + 39.7732552602604, 42.79218144770993}, {39.828514777014036`, + 42.9921850001184}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{39.85630504749751, 43.09276772587525}, {39.97829714889914, + 43.53429988322069}, {40.19422659952834, 44.29166193896368}, { + 40.42139921775683, 45.064899554130484`}, {40.66017060919343, + 45.85464466791269}, {40.91089637944697, 46.66152921950189}, { + 41.04903944587308, 47.0924503155271}}]}, + {Arrowheads[{{0.014192803458930205`, 1.}}], + ArrowBox[{{41.08089511278807, 47.19182033283425}, {41.23672796035694, + 47.67792262669803}, {41.408047187287615`, 48.1986055906829}, { + 41.585193469766295`, 48.72799998297205}, {41.76833538121613, + 49.26639624460025}, {41.95764149506027, 49.814084816602296`}, { + 42.02290995321195, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{4.319580651254556, 50.}, {4.327294726395148, + 49.961050346695416`}, {4.508291058260853, 49.090026080138}, { + 4.688673087110341, 48.26216167065276}, {4.868220134920151, + 47.475773065346814`}, {5.046400967307639, 46.728234957370844`}, { + 5.222797279475323, 46.01726431404149}, {5.245261065603621, + 45.930326289162316`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{5.271366838167764, 45.82929326241833}, {5.397357787777473, + 45.34169049371491}, {5.570031208568362, 44.70034285474721}, { + 5.74076625820226, 44.09205075549455}, {5.909511653033442, + 43.51564355431306}, {6.076216109416176, 42.96995060955888}, { + 6.240828343704737, 42.453801279588134`}, {6.452787708843304, + 41.82718241251142}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.48622434252224, 41.72833315665968}, {6.56264038219542, + 41.502423194270456`}, {6.8743513734954655`, 40.65153862457891}, { + 7.176667803504246, 39.89541568114387}, {7.470296158121136, + 39.22832247459571}, {7.754946766863427, 38.64214477799765}, { + 8.031126884354078, 38.130674234466646`}, {8.170608497690745, + 37.91923976141991}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{8.228070877858805, 37.83213488945718}, {8.565683139811934, + 37.320362269449696`}, {9.03648788685305, 36.814490656654584`}, { + 9.504124087901678, 36.509899769853384`}, {9.980663685682348, + 36.40305888896133}, {10.226230151583158`, 36.42459116611594}, { + 10.479717559965424`, 36.497822658764164`}, {10.849610640874653`, + 36.68974939129246}, {11.247205725572076`, 36.99443201211079}, { + 11.519955477592566`, 37.28075142271622}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{11.591930796959485`, 37.3563076088048}, { + 11.950943499452919`, 37.73318166502781}, {12.008786234130866`, + 37.80229313541391}, {12.06742837982083, 37.87358400008452}, { + 12.334747992595185`, 38.226164684386646`}, {12.621569486823308`, + 38.62619322141192}, {12.919844979548898`, 39.05283114060843}, { + 13.241028469269423`, 39.53268782414744}, {13.588734824614159`, + 40.071956126263174`}, {13.966578914212386`, 40.67682890118988}, { + 14.010013795312366`, 40.74825387626535}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{14.064233388003805`, 40.83741339411172}, { + 14.378813248186738`, 41.354713271624746`}, {14.833092344757956`, + 42.118942058422704`}, {15.246751280600575`, 42.82692717567917}, { + 15.698379505284956`, 43.61029155354303}, {16.171574819420517`, + 44.44022392736655}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{16.22310245881298, 44.53096566157733}, {16.45845409577451, + 44.94664303451333}, {16.736462380053844`, 45.43967246921526}, { + 17.02894101591767, 45.960222537391246`}, {17.337924369326622`, + 46.51182656960474}, {17.664553437361693`, 47.09646996590635}, { + 18.009969217103894`, 47.71613812634668}, {18.263697901959542`, + 48.172196966622565`}}]}, + {Arrowheads[{{0.009516783655673752, 1.}}], + ArrowBox[{{18.31443075234337, 48.26338557197518}, {18.37531270563422, + 48.372816450976316`}, {18.761724900033666`, 49.06849033984588}, { + 19.170346797383242`, 49.80514519300596}, {19.278311967134666`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{48.70808172879087, 4.093956838965128}, {48.015600704368715`, + 4.2266725384361745`}, {47.33631377568077, 4.361166718624578}, { + 46.67001711655772, 4.497388816191737}, {46.01650690083028, + 4.635288267799045}, {45.375579302329086`, 4.774814510107904}, { + 44.747030494884804`, 4.915916979779714}, {44.62195400884334, + 4.9448595216944895`}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{44.520289107875335`, 4.968384652201853}, {44.13065665232814, + 5.058545113475872}, {43.526253948489796`, 5.202648347857767}, { + 42.933618557200425`, 5.348176119586805}, {42.35254665229069, + 5.495077865324387}, {41.782834407591295`, 5.643303021731904}, { + 41.224277996932926`, 5.792801025470751}, {40.67667359414625, + 5.94352131320233}, {40.47622268155968, 6.000234620228982}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{40.37581290252111, 6.028643423928659}, {40.139817373061945`, + 6.095413321588043}, {39.459911962069974`, 6.293701864208629}, { + 38.796572043056074`, 6.4936692636423645`}, {38.14948481624552, + 6.695223355905408}, {37.51833748186357, 6.898271977013918}, { + 36.902817240135484`, 7.1027229629840525`}, {36.393520684589326`, + 7.277318806173719}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{36.29483513929001, 7.311234473907843}, {35.717406835542015`, + 7.515463373573829}, {35.146891073127144`, 7.723568470225793}, { + 34.59075120426723, 7.93270727580401}, {34.048674429187514`, + 8.142787626324644}, {33.520347948113276`, 8.353717357803855}, { + 33.00545896126979, 8.565404306257795}, {32.405245970933784`, + 8.823052852566216}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{32.309356023355036`, 8.864214750087669}, { + 32.014742271176104`, 8.990681198154508}, {31.07402196070858, + 9.417880990144054}, {30.17918584270716, 9.845633102427938}, { + 29.326707107816212`, 10.272797234454115`}, {28.552052516926214`, + 10.67950785752588}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{28.460229845761305`, 10.729074097524581`}, { + 27.742324461400884`, 11.123793985729197`}, {27.007171886894103`, + 11.546842818976005`}, {26.30787936953296, 11.967736099960934`}, { + 25.64282257782625, 12.386081935682936`}, {25.010377180282784`, + 12.801488433140966`}, {24.888128885413025`, 12.885001004092336`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{24.80196403156696, 12.94386357127988}, {24.407850358601106`, + 13.213097969285446`}, {23.83293783513804, 13.620222277448084`}, { + 23.28459808938979, 14.022723499199762`}, {22.761789600852552`, + 14.420463776111358`}, {22.26347084902251, 14.813305249753759`}, { + 21.788600313395868`, 15.201110061697849`}, {21.477426391746473`, + 15.464257208364062`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{21.39774665257445, 15.531639127449974`}, { + 21.336136473468812`, 15.583740353514509`}, {20.905037808737546`, + 15.96105826677462}, {20.49376146727513, 16.332634273150287`}, { + 20.100946899490324`, 16.69814490609498}, {19.367630816952396`, + 17.41105498866324}, {18.6989450251215, 18.099958388422962`}, { + 18.39686698830514, 18.42919797856758}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{18.326319375369238`, 18.506088928381377`}, { + 18.088744987995376`, 18.76502497931771}, {17.602254806405167`, + 19.320908039731595`}, {17.15298803393434, 19.85857246085529}, { + 16.73682398254914, 20.378456172700123`}, {16.3514733811197, + 20.88080246971684}, {15.994684674556558`, 21.366052562182006`}, { + 15.71693624414, 21.759880316442757`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{15.65700704782492, 21.84530396883594}, {15.358596897028146`, + 22.287009177393045`}, {15.075570069813962`, 22.723859013899304`}, { + 14.594829123835861`, 23.509699672907118`}, {14.179832089842215`, + 24.24642089136489}, {13.823430137262502`, 24.938746513129637`}, { + 13.580018479139605`, 25.459686307046468`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{13.535844191913988`, 25.554226331387117`}, { + 13.518474435526207`, 25.591400382058378`}, {13.480966901733915`, + 25.67640279313711}, {13.444284613175178`, 25.760778393771126`}, { + 13.275610911300683`, 26.189621036069482`}, {13.127021215791121`, + 26.60550237872598}, {12.867586708200312`, 27.414259588961812`}, { + 12.680065344170375`, 28.1846094265204}, {12.558712089105702`, + 28.93201935880526}, {12.513830615561275`, 29.576719947463232`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{12.506583638809852`, 29.680819251890238`}, { + 12.49834548964454, 29.799156267074707`}, {12.523880352172746`, + 30.686027996236586`}, {12.63837034246668, 31.627799152088937`}, { + 12.852545111510091`, 32.661841593843}, {13.001451961853148`, + 33.22796485133233}, {13.166744083068592`, 33.78194477868995}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{13.197795621150187`, 33.88155821706151}, { + 13.402221224260959`, 34.5018913934377}, {13.659722031857633`, + 35.22418999059383}, {13.964043211601997`, 36.0216307440609}, { + 14.325835946904315`, 36.91495736287581}, {14.53050014474458, + 37.4021432279129}, {14.691507637219605`, 37.777359731358345`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{14.7326568788365, 37.87325511064523}, {14.752191427700177`, + 37.91877898663597}, {14.991796194513057`, 38.466690781494705`}, { + 15.250200843925166`, 39.047704754938785`}, {15.63541493674554, + 39.89663309831635}, {16.070615644046338`, 40.83445138669106}, { + 16.30887934079907, 41.340249155511934`}, {16.46576757537701, + 41.67024458702501}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{16.510572904798224`, 41.76448717988874}, {16.56194172637851, + 41.87253528489361}, {16.83057014585352, 42.43273173293991}, { + 17.115531944292986`, 43.02226045775469}, {17.36145691760367, + 43.527251190701676`}, {17.621609851328984`, 44.05767042414354}, { + 17.896896837752735`, 44.6151339978141}, {18.18822396915872, + 45.20125775144718}, {18.344606891439625`, 45.513949043146454`}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{18.39128309078776, 45.607279189769265`}, { + 18.496497337830743`, 45.81765752477659}, {18.822623036052608`, + 46.46594915753615}, {19.167507156108115`, 47.14774848945969}, { + 19.532055790281067`, 47.864671360281}, {19.839183610360138`, + 48.46567286019579}, {20.162741532737172`, 49.09575387135}, { + 20.28266629551243, 49.32818672560848}}]}, + {Arrowheads[{{0.003123479124210378, 1.}}], + ArrowBox[{{20.330513472909036`, 49.42092200190289}, { + 20.503760459119256`, 49.75670162376452}, {20.629867991294255`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{50., 1.7511359116089673`}, {49.960134284961434`, + 1.7540651154278804`}, {49.22221194306671, 1.8099221158901446`}, { + 48.49665648317355, 1.866465206294774}, {47.783278664612, + 1.923666206718645}, {47.08188924671209, 1.9814969372386337`}, { + 46.392298988803866`, 2.039929217931617}, {45.839598440772846`, + 2.0880315798393907`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{45.73564016087489, 2.0970792256591313`}, {45.71431865021737, + 2.098934868874471}, {45.04775899028265, 2.158485710144072}, { + 44.392430768329746`, 2.2185535618172976`}, {43.74799858866116, + 2.2791138280660452`}, {43.11415247384506, 2.340141289741341}, { + 42.49074131060996, 2.401606831938752}, {41.87761398568441, + 2.463481339753843}, {41.58055902877077, 2.494149882712226}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{41.476759504917254`, 2.5048663514405587`}, { + 41.27461938579694, 2.5257356982821815`}, {40.68160639767606, + 2.588340792619332}, {40.098423908050314`, 2.651267507860863}, { + 39.52492080364824, 2.7144867291023376`}, {38.96094597119837, + 2.7779693414393227`}, {38.406348297429226`, 2.841686229967386}, { + 37.86097666906934, 2.9056082797820912`}, {37.32867005149847, + 2.9692294824105367`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{37.22509711996872, 2.9819506099958533`}, {36.27870692373057, + 3.098314247901725}, {35.26722024390743, 3.2272769265000725`}, { + 34.28892882092955, 3.3563449767732725`}, {33.34257143554012, + 3.4852749694533856`}, {33.086097904959004`, 3.5212893298954975`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{32.98276049097098, 3.535800109491692}, {32.426984021354585`, + 3.613842993904198}, {31.54100251198838, 3.741825139489496}, { + 30.68346284105696, 3.8689974955730637`}, {29.85320094217578, + 3.9951361515186856`}, {29.04905274896027, 4.120017196690148}, { + 28.854330464681183`, 4.150854827258613}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{28.75126367556069, 4.167177230102966}, {28.269854195025882`, + 4.243416720451237}, {27.20679901243413, 4.414611358620885}, { + 26.18584056161639, 4.581255495348989}, {25.20487771691266, + 4.742993054384105}, {24.63227596365705, 4.84267479744279}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{24.529470880009804`, 4.860571686292651}, {24.28422135970308, + 4.903266106156867}, {23.39410554313743, 5.057030237105138}, { + 22.539783081365762`, 5.205175637857531}, {21.72125397438806, + 5.347702308414046}, {20.93851822220433, 5.484610248774683}, { + 20.41711286864374, 5.57555160246802}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{20.314313525703067`, 5.593481436410019}, { + 20.188212975061155`, 5.615475370109662}, {19.466975383205117`, + 5.739873583589205}, {18.774805446636215`, 5.857804889213312}, { + 18.11170316535444, 5.969269286981984}, {17.511607102258267`, + 6.068314585996544}, {16.93367662775631, 6.161354991358417}, { + 16.331925585807774`, 6.255110053401209}, {16.196421903476818`, + 6.275379995241686}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{16.093218951584223`, 6.2908180836880145`}, { + 15.752588791268925`, 6.34177281362546}, {15.195666244139757`, + 6.421343272031169}, {14.66115794442027, 6.493821428618338}, { + 13.651403335580103`, 6.6179793006386465`}, {12.715344213118183`, + 6.71472489398798}, {11.948538853035643`, 6.775970877649539}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{11.844518869704418`, 6.784279121867986}, { + 11.762456164560819`, 6.7908336027833345`}, {10.883040045659525`, + 6.836382153963504}, {10.736207864590448`, 6.841656261576708}, { + 10.591389697545472`, 6.846056752660993}, {10.23713261896957, + 6.849706550621802}, {9.894701809328478, 6.848097646452643}, { + 9.117360737405736, 6.830890765822442}, {8.400166188720421, + 6.786857363461106}, {7.738128133578678, 6.718574564403359}, { + 7.677794488865157, 6.709704537825551}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{7.5745529916176455`, 6.694526359400124}, {7.126256542286653, + 6.6286194936839244`}, {6.561285704708233, 6.51910031378486}, { + 6.037337342598416, 6.3938117171738655`}, {5.30157012415421, + 6.167715962877219}, {4.649703319574725, 5.915600277989436}, { + 4.070293411341426, 5.6461960322187}, {3.632676908492608, + 5.40620584902936}}]}, + {Arrowheads[{{0.009018488526614476, 1.}}], + ArrowBox[{{3.5420743658215295`, 5.354565090028833}, {2.704278109852364, + 4.788692615883016}, {2.0432355837584906`, 4.221255216724478}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{6.520942316078481, 38.929339855472676`}, {6.747524110405924, + 38.14081512371605}, {6.961001825179257, 37.41764365197272}, { + 7.161375460398483, 36.75982544024268}, {7.349055095733886, + 36.1569686465526}, {7.5244508108557495`, 35.598681428929154`}, { + 7.736023597766242, 34.93630054198494}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{7.767774354128731, 34.83689695389763}, {7.838390480458867, + 34.61581572188215}, {8.016510119192894, 34.06190121194002}, { + 8.17713297780455, 33.55444364059277}, {8.445888354660749, + 32.678899313682955`}, {8.651342670652985, 31.94788438137426}, { + 8.800181985406788, 31.320100483888233`}, {8.884484583035121, + 30.819696170423114`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{8.901820243325743, 30.716794961797998`}, {8.906353824221085, + 30.689884480990816`}, {8.950274465078182, 30.11185991349578}, { + 8.933361050030085, 29.552482820019254`}, {8.857030721128801, + 28.97820923917736}, {8.719082795565011, 28.360662271193995`}, { + 8.5173165905294, 27.67146501629304}, {8.305589859238136, + 27.049375368300986`}, {8.16008913796415, 26.655289079102204`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{8.123946331127387, 26.557396886521886`}, {8.04838929278722, + 26.352751901936166`}, {7.744418339148343, 25.57122665446563}, { + 7.5747323371208175`, 25.146220186483145`}, {7.393337350207783, + 24.69723191209402}, {7.004260226696846, 23.74466442495637}, { + 6.794018153296074, 23.23298003055406}, {6.573963473675769, + 22.697986476192686`}, {6.568319785750554, 22.684272491493292`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{6.528609454919318, 22.587772369871306`}, {6.513581441497226, + 22.551249580272515`}, {6.266531700514734, 21.949324744657638`}, { + 6.011151532141602, 21.32452646794287}, {5.615226128836256, + 20.350135622059245`}, {5.412497157698578, 19.84697224659695}, { + 5.206590673570895, 19.33316356945433}, {4.998904656112411, + 18.811128860566395`}, {4.962474019194867, 18.71870887957374}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{4.924206026373197, 18.621627755869785`}, {4.790837084982328, + 18.28328738986814}, {4.582387960180644, 17.749639157359567`}, { + 4.3735572817073605`, 17.210184163040676`}, {4.162525160380449, + 16.661346305394304`}, {3.9596043015647355`, 16.12339015968438}, { + 3.7577578004230445`, 15.582488133377872`}, {3.557713612628187, + 15.040070667081643`}, {3.4416454168170247`, 14.719900787821603`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{3.4060807892399114`, 14.621797061493174`}, { + 3.2274111848916682`, 14.128943483027241`}, {2.909215559479851, + 13.229542311586256`}, {2.6070886820923276`, 12.350413885049615`}, { + 2.3249924984286907`, 11.500104935708245`}, {2.147390147086162, + 10.947112548534534`}, {2.060833320365299, 10.67086336691861}}]}, + {Arrowheads[{{0.0034302695058375954`, 1.}}], + ArrowBox[{{2.0296327720313254`, 10.57128571060013}, { + 1.9787952509239446`, 10.409035959386559`}, {1.8193978369665709`, + 9.886948464805657}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{50., 6.874827243658772}, {49.203620389034064`, + 7.163263041922101}, {48.333322841780536`, 7.49686322046547}, { + 47.49223374284091, 7.8382770728481885`}, {46.68035309221518, + 8.187504599070254}, {46.13094238141069, 8.437118439378569}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{46.035936794583485`, 8.480282340104056}, {45.89518917003137, + 8.544228226829274}, {45.1342502564175, 8.908130383822861}, { + 44.39753635137357, 9.27921107005101}, {43.685047454899575`, + 9.657470285513723}, {42.996783566995525`, 10.042908030211}, { + 42.34638784663161, 10.427457718877667`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{42.25769063850247, 10.482422660339001`}, {41.69293081689724, + 10.835319107309243`}, {41.077341954703, 11.242292439710209`}, { + 40.48403073301128, 11.65633346288698}, {39.911049783754635`, + 12.077331338380796`}, {39.35839910693308, 12.50528606619166}, { + 38.86537331414647, 12.90809351978114}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{38.785493966967316`, 12.975223933688156`}, { + 38.3140885705952, 13.382066078764527`}, {37.82242871107889, + 13.83089136352653}, {37.351099123997656`, 14.286673500605577`}, { + 36.90009980935151, 14.74941249000167}, {36.427632965334816`, + 15.268065437920663`}, {35.977437968591566`, 15.79550532888168}, { + 35.85931988760107, 15.942778373419962`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{35.79403123560978, 16.024182155736156`}, {35.52930710200576, + 16.35424787295483}, {35.10448668176217, 16.922698621587035`}, { + 34.70266314735557, 17.50114935904269}, {34.323522938280746`, + 18.089891869586193`}, {33.96657014313624, 18.688693750370863`}, { + 33.63145473123757, 19.297741948238876`}, {33.52122594952762, + 19.515902511305697`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{33.474166806511974`, 19.609040156288028`}, { + 33.31808196315501, 19.917957271987934`}, {33.026357099458814`, + 20.55026053041572}, {32.73390691361097, 21.25154698730158}, { + 32.46655059539791, 21.96949424418804}, {32.22438463830975, + 22.705098267695945`}, {32.00647627194189, 23.44873138049053}, { + 31.992763310045042`, 23.503343362304825`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{31.967349832051884`, 23.604552744234137`}, { + 31.81419248740453, 24.21450310970032}, {31.64729205097233, + 24.999923538773224`}, {31.505774962645294`, 25.804992667709243`}, { + 31.38964122242342, 26.629710496508377`}, {31.299789965554968`, + 27.47707453405408}, {31.282618054763265`, 27.716284647706317`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{31.275146334243594`, 27.820368062555648`}, { + 31.23712032728819, 28.350082289229803`}, {31.201632307623083`, + 29.248733762035556`}, {31.193325906559647`, 30.17302895247133}, { + 31.196237980568633`, 30.68944518677864}, {31.207823904826466`, + 31.214772490868395`}, {31.261258053382626`, 31.99034278318651}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{31.268430496134407`, 32.09444724956137}, { + 31.280624910293685`, 32.27144315217633}, {31.3392793354549, + 32.82572313182294}, {31.389032191645075`, 33.3696252518725}, { + 31.49698521092545, 34.33338576344629}, {31.634158226167248`, + 35.33350954852206}, {31.779002991315153`, 36.23576934593132}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{31.795543296346978`, 36.338801390284885`}, { + 31.80055123737047, 36.36999660709981}, {31.89470524145762, + 36.90187636395193}, {31.996164244535123`, 37.44284693917954}, { + 32.10586027333454, 37.9946721297735}, {32.22472535458742, + 38.55911573272466}, {32.35275948829376, 39.136177748033035`}, { + 32.48996267445358, 39.725858175698605`}, {32.636334913066854`, + 40.32815701572138}, {32.65990111511854, 40.42132368622584}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{32.685490481910925`, 40.52248874027805}, { + 32.791876204133594`, 40.94307426810136}, {32.95658654765381, + 41.57060993283855}, {33.13046594362748, 42.21076400993294}, { + 33.29267330664639, 42.8263650157106}, {33.49789198619859, + 43.51494439793041}, {33.71306370887791, 44.21754049283371}, { + 33.81448092796259, 44.54012309646097}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{33.84577779000505, 44.639670523753274`}, {33.93858047002119, + 44.93485245058366}, {34.17483426496527, 45.66757942134339}, { + 34.422217089046974`, 46.41642055527606}, {34.68112093760313, + 47.18207500254481}, {34.95193780597058, 47.96524191331279}, { + 35.17564521405926, 48.595935001149904`}}]}, + {Arrowheads[{{0.006656836429678303, 1.}}], + ArrowBox[{{35.210529262610564`, 48.694282787148836`}, { + 35.29346894313344, 48.928112697656154`}, {35.6569807278478, + 49.92446064885173}, {35.68510583913165, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{50., 14.317042278784916`}, {49.79846536476008, + 14.537376612102017`}, {49.40644030887509, 14.990385375837368`}, { + 49.028918643930055`, 15.452469502978406`}, {48.665968349402526`, + 15.924071796750399`}, {48.31765740477005, 16.405635060378618`}, { + 47.98405378951019, 16.897602097088335`}, {47.665225483100485`, + 17.40041571010482}, {47.51229945365775, 17.659045986922834`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{47.45918741805998, 17.7488696782792}, {47.36124046501849, + 17.914518702653346`}, {46.974658029572694`, 18.62681614545136}, { + 46.61517531489776, 19.361681432778937`}, {46.28306297024403, + 20.120135742567584`}, {45.97570471952488, 20.892307688146037`}, { + 45.747425333746826`, 21.54770412339392}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{45.71310149216061, 21.64624882265769}, {45.696934760453466`, + 21.692663956877354`}, {45.446076469903936`, 22.518651603932764`}, { + 45.2231298478763, 23.370270629312262`}, {45.02809489437055, + 24.247521033015854`}, {44.86210358164024, 25.153329884018632`}, { + 44.78154217075229, 25.709302108225703`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{44.76657776427871, 25.81257480739211}, {44.72628788193894, + 26.090624251295694`}, {44.620647795266635`, 27.059404134847036`}, { + 44.545183321623334`, 28.059669534672665`}, {44.50654835123847, + 28.70981216361135}, {44.480885425224315`, 29.374275143590665`}, { + 44.48709091384877, 29.973461198971894`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{44.48817157281706, 30.077806855471895`}, {44.49117162165552, + 30.367483871780426`}, {44.530404031511395`, 31.395478307774827`}, { + 44.58594872962269, 32.4513471914469}, {44.625734967197104`, + 32.99441429266528}, {44.67353046378401, 33.547569833471904`}, { + 44.72933521938342, 34.110813813866756`}, {44.74399742622041, + 34.24254535558632}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{44.75554082311682, 34.34625617393385}, {44.79314923399534, + 34.684146233849845`}, {44.864972507619754`, 35.267567093421164`}, { + 44.944805040256675`, 35.86107639258071}, {45.03351531846789, + 36.46626178265941}, {45.13197182881522, 37.08471091498816}, { + 45.24017457129864, 37.71642378956696}, {45.35812354591816, + 38.36140040639582}, {45.37962828448109, 38.472252545588915`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{45.39950138644366, 38.57469396139623}, {45.48581875267378, + 39.01964076547473}, {45.62326019156551, 39.691144866803704`}, { + 45.77044786259332, 40.37591271038272}, {45.92738176575725, + 41.0739442962118}, {46.07566535677869, 41.75314698560655}, { + 46.26356793835725, 42.497726228657335`}, {46.30310678749583, + 42.649041366727204`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{46.32948814192834, 42.75000278506376}, {46.46190878508551, + 43.256776460554455`}, {46.6710339134703, 44.03090130459605}, { + 46.891289340018425`, 44.82070438408026}, {47.12302108123667, + 45.62678932230521}, {47.366575153631864`, 46.44975974256904}, { + 47.463059792993334`, 46.76686699581841}}]}, + {Arrowheads[{{0.015764013498501508`, 1.}}], + ArrowBox[{{47.49343530465901, 46.866699416130004`}, {47.62229757371081, + 47.29021926816991}, {47.78953620961886, 47.82755288342334}, { + 47.96255904674318, 48.3734357558464}, {48.14153700647821, + 48.92815846373074}, {48.32664101021842, 49.49201158536796}, { + 48.49624482199345, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{36.66146237085959, 8.263914813368329}, {35.71546705206069, + 8.667343199075988}, {34.81159710940318, 9.075345179120824}, { + 33.948178062770246`, 9.487460304503008}, {33.1232031285105, + 9.902981563513073}, {32.88160788488025, 10.03116467702101}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{32.7894276842507, 10.080072697489191`}, {32.33478636062148, + 10.321291603608696`}, {31.58143453545975, 10.742064464540771`}, { + 30.86165442938186, 11.16497418606019}, {30.173952818744354`, + 11.589694807917848`}, {29.516836479903773`, 12.015900369864646`}, { + 29.21082587198215, 12.224137670834732`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.12455473587262, 12.282844356387516`}, { + 28.888812189216672`, 12.443264911651475`}, {28.288386723039608`, + 12.871462473029224`}, {27.812745077771755`, 13.224225683822695`}, { + 27.352560046544344`, 13.57668358637938}, {26.907364449599033`, + 13.928775227887105`}, {26.476691107177487`, 14.280439655533701`}, { + 25.82647979178595, 14.837166637098147`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{25.7472144643065, 14.905035567499304`}, {25.65704246687232, + 14.982243057994816`}, {24.929742693607217`, 15.686807477903953`}, { + 24.241844748103517`, 16.387224929881725`}, {23.60269222552805, + 17.084714470171555`}, {23.0122851258808, 17.77927609877344}, { + 22.886893790914343`, 17.939385035401497`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{22.822553033364425`, 18.02154007646487}, { + 22.470623449161778`, 18.470909815687385`}, {21.972560967103952`, + 19.159892670674193`}, {21.512951451440298`, 19.846501713494664`}, { + 21.091794902170815`, 20.5307369441488}, {20.709091319295503`, + 21.212598362636598`}, {20.554650334885732`, 21.517176239641298`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{20.507457695744282`, 21.61024631359145}, {20.32860457317984, + 21.96296812881766}, {19.988119739213047`, 22.712820832827653`}, { + 19.600813081410717`, 23.69184470726316}, {19.275231798499632`, + 24.675144345818538`}, {19.050793405472263`, 25.511958598471697`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{19.023761188874364`, 25.612747700660506`}, { + 19.009247426095087`, 25.666861987389716`}, {18.800731499812372`, + 26.671139870872633`}, {18.698038643681045`, 27.317662178776402`}, { + 18.61813103801594, 27.974673710954345`}, {18.561008682817057`, + 28.642174467406463`}, {18.526671578084397`, 29.320164448132747`}, { + 18.51893932036319, 29.550413556907138`}, {18.514604880965038`, + 29.74703412180877}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{18.515577538831486`, 29.851354677503736`}, { + 18.53292501704715, 30.5365847327041}, {18.57995578282932, + 31.314368299999444`}, {18.641662638120913`, 32.10582057800698}, { + 18.732721672431342`, 32.9246102774389}, {18.85477093563476, + 33.77497554349018}, {18.89476965370882, 34.00413630365761}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{18.912712308706062`, 34.106933409579284`}, { + 19.00944847760532, 34.66115452135578}, {19.198793648023983`, + 35.587749330379765`}, {19.426477276316493`, 36.5630437853814}, { + 19.561173517589673`, 37.09353545256812}, {19.70778272716713, + 37.640010445114925`}, {19.857486575610498`, 38.17035049938011}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{19.886672783363053`, 38.27053518143277}, { + 20.039153109372382`, 38.78594490575548}, {20.225120811068916`, + 39.387921623582564`}, {20.425414539207225`, 40.01091616623641}, { + 20.64063755832167, 40.6561871585837}, {20.87139313294664, + 41.32499322549109}, {21.119496113481485`, 42.020505826927334`}, { + 21.19765531514149, 42.232515873047646`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{21.23375052915746, 42.33042562424416}, {21.387134145976336`, + 42.74648498750797}, {21.675469688441716`, 43.50507217906986}, { + 21.985665198888142`, 44.298408873449866`}, {22.318883135326143`, + 45.12863654248485}, {22.676285955766232`, 45.99789665801166}, { + 22.766502945160617`, 46.21249256321073}}]}, + {Arrowheads[{{0.019295018806835394`, 1.}}], + ArrowBox[{{22.806944177921398`, 46.308688667846056`}, { + 23.059036118218938`, 46.908330691867164`}, {23.468296080694778`, + 47.86208011588822}, {23.79270785106708, 48.604754647815916`}, { + 24.136415647290978`, 49.379289607909726`}, {24.41602856885353, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{6.065923617017819, 50.}, {6.337651605127494, + 49.366768500200685`}, {6.632376243683451, 48.748239313220616`}, { + 6.931135104593402, 48.18860224396082}, {7.233928187857343, + 47.687857292421306`}, {7.505392647270676, 47.29312017236674}, { + 7.780932135147687, 46.942191372141174`}, {8.188857130920077, + 46.5107445524898}, {8.236416266572492, 46.472146956181426`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{8.317441576773264, 46.40638919647893}, {8.607999853016935, + 46.170580641578525`}, {9.489390127522537, 45.768827737528376`}, { + 10.52700470705095, 45.7723042368643}, {10.627875123563744`, + 45.79428797065904}, {10.72985404873297, 45.82049177984651}, { + 11.118168251342006`, 45.98874585596824}, {11.526542968550174`, + 46.2196702284124}, {12.101508577216016`, 46.595917698652755`}, { + 12.10584355132604, 46.59944102174456}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{12.186821443903355`, 46.66525716541736}, { + 12.721666394581243`, 47.09996139142419}, {13.39746264217288, + 47.74841523623559}, {13.760142510376234`, 48.133026189222115`}, { + 14.139343541517947`, 48.55789316259586}, {14.529824353417094`, + 49.01433124179023}, {14.961286111765588`, 49.551554942682586`}, { + 15.059447679183357`, 49.67842662765621}}]}, + {Arrowheads[{{0.001448163833233887, 1.}}], + ArrowBox[{{15.123303631271027`, 49.76095905302466}, { + 15.308251391971183`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{2.4920982917921206`, 50.}, {2.492355221430933, + 49.99707541494844}, {2.5697093403475773`, 49.12990136806211}, { + 2.6458802042681198`, 48.28654893619036}, {2.72075093018016, + 47.46617217705798}, {2.794204635071296, 46.66792514838975}, { + 2.8661244359291285`, 45.89096190791045}, {2.8705657177562873`, + 45.8431464867968}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{2.880216724716865, 45.7392424834145}, {2.9363934497412556`, + 45.13443651334489}, {3.0048947934952763`, 44.39750302241782}, { + 3.0715115841787903`, 43.67931549285405}, {3.1706826577739724`, + 42.599660168163545`}, {3.2629039954457433`, 41.582773909551236`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{3.2721605233403093`, 41.47883405465382}, {3.353360181769914, + 40.56288082598207}, {3.4361716109979366`, 39.60003085896253}, { + 3.5129928471190572`, 38.67130155462539}, {3.583601326155475, + 37.77446876693039}, {3.6173802773864705`, 37.319128942476624`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{3.625100262211921, 37.21506364716394}, {3.6478796264146296`, + 36.907998113178024`}, {3.705654291879761, 36.069401945963776`}, { + 3.755235599296461, 35.28186548132726}, {3.798540740025106, + 34.515700512460796`}, {3.8355697140656977`, 33.77090703936439}, { + 3.86629213494708, 33.0481998664068}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{3.869929695191671, 32.94391205481668}, {3.890861572824205, + 32.3428937370531}, {3.9092492790250954`, 31.65459222098092}, { + 3.921485640020906, 30.982580513821492`}, {3.927570655811637, + 30.326858615574814`}, {3.92837020934439, 30.154803638546454`}, { + 3.928748941428379, 29.983747315327125`}, {3.9216617408297934`, + 29.296417945809083`}, {3.9108605450049225`, 28.77076132233014}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{3.908716787294552, 28.66643209269098}, {3.9078315846436262`, + 28.623352359286947`}, {3.8907521865259196`, 27.95698378751941}, { + 3.867174304545133, 27.30400924526106}, {3.8373572233377327`, + 26.663594477765482`}, {3.8015602275401847`, 26.034905230286256`}, { + 3.7600248719971905`, 25.417397198317364`}, {3.7131859554292124`, + 24.810090633747972`}, {3.6850732969684383`, 24.49921494158346}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{3.67567510576252, 24.395287765848337`}, {3.62500256903564, + 23.834940193217292`}, {3.5244561774069973`, 22.885828473935085`}, { + 3.413141763048003, 21.96012894071209}, {3.2926543084633773`, + 21.055215058359032`}, {3.1762412267695304`, 20.251880951377164`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{3.1610406659772488`, 20.148643747354644`}, { + 3.030094523850258, 19.307924827513055`}, {2.8909753887887213`, + 18.46597272970803}, {2.7486453140336957`, 17.644318943897805`}, { + 2.60436795946291, 16.84338830972699}, {2.4592654096800084`, + 16.06420430367305}, {2.4537240531095224`, 16.03519411433671}}]}, + {Arrowheads[{{0.013483247334737701`, 1.}}], + ArrowBox[{{2.434145463922294, 15.932696003624075`}, {2.31463671838124, + 15.307042106172382`}, {2.1717809392628533`, 14.572176897661388`}, { + 2.0312107219629225`, 13.860075186099031`}, {1.8944329264314093`, + 13.1709615938717}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{32.60418249978299, 7.73945746609291}, {31.626987959007483`, + 8.10203082157432}, {30.694175687271834`, 8.464613223653483}, { + 29.80251519835569, 8.82619531000804}, {28.95044545716806, + 9.186366225633893}, {28.727393557614718`, 9.284555992463714}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{28.631886696912428`, 9.326599106204439}, { + 28.136405428617955`, 9.544715115526941}, {27.358834077614397`, + 9.900831124683087}, {26.616170369066396`, 10.254303398098234`}, { + 25.906853267882973`, 10.604721080768279`}, {25.229321738973127`, + 10.951673317689128`}, {24.873388103418627`, 11.139818136326847`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{24.781132596104932`, 11.188583956575403`}, { + 24.58104691705507, 11.29434829025012}, {23.95985187509821, + 11.632079984788435`}, {23.364703485388358`, 11.964676253721736`}, { + 22.79456862021134, 12.291944949467686`}, {22.248414151852977`, + 12.613693924443945`}, {21.725206952599088`, 12.929731031068176`}, { + 21.223913894735492`, 13.239864121758039`}, {21.167389770133415`, + 13.275636374687782`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{21.07921325936831, 13.331440378159874`}, { + 20.743501850548018`, 13.543901048931197`}, {19.839576325779618`, + 14.132040108052182`}, {19.004842963267436`, 14.692435484903253`}, { + 18.23297110117612, 15.22460325604074}, {17.615230504942797`, + 15.659368422414197`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{17.5298952053702, 15.719427314354329`}, {17.51763007767032, + 15.728059498020976`}, {16.922035882888594`, 16.15137091937015}, { + 16.364190195685644`, 16.55095396681119}, {15.83943758250957, + 16.926710666595632`}, {15.345191691387095`, 17.278586588863227`}, { + 14.87888084156338, 17.606676657191496`}, {14.437933352283583`, + 17.91107579515795}, {14.119336084497675`, 18.125546664851374`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{14.032771390609014`, 18.183819622783712`}, { + 14.020686912711152`, 18.19195455910177}, {13.624512265571033`, + 18.449605907886507`}, {13.162927955817471`, 18.7353171834392}, { + 12.494265459904154`, 19.111856304905178`}, {11.878169376194116`, + 19.408232831903714`}, {11.306653828466967`, 19.62728493439558}, { + 10.771732940502316`, 19.771850782341545`}, {10.703233262099188`, + 19.786080818383116`}, {10.635263880683283`, 19.79905710098755}, { + 10.28047833250874, 19.827527824428625`}, {10.248765140504853`, + 19.82695943576839}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{10.144430644355005`, 19.82508947122885}, {9.937333575490864, + 19.821377715392483`}, {8.89015653732592, 19.63427485552094}, { + 7.924869009184266, 19.13396031501206}, {7.464683943297934, + 18.78030182013262}, {7.016582902540748, 18.365397246175977`}, { + 6.596879459262006, 17.90249235280233}}]}, + {Arrowheads[{{0.018522790985394364`, 1.}}], + ArrowBox[{{6.52678760667327, 17.82518571625086}, {6.39002147396624, + 17.67434179754651}, {5.786165688148222, 16.887014650816926`}, { + 5.206467259413866, 16.023444733800467`}, {4.652377902090347, + 15.103660974310372`}, {4.383974601218351, 14.616711696950205`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{38.04738862120897, 4.185894000418275}, {37.467493807026365`, + 4.29117337086192}, {36.89851937346901, 4.396776813064768}, { + 36.340285799099576`, 4.502659245591524}, {35.79261356248076, + 4.608775587006894}, {34.72823501674582, 4.8215296707622874`}, { + 33.95039169626236, 4.983394706774173}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{33.84822899744271, 5.004654218153966}, {33.703947564765734`, + 5.034678412848586}, {32.71831503504209, 5.247861161783424}, { + 31.769901256076466`, 5.460717266084436}, {30.857270056370425`, + 5.67288607426926}, {29.978985264425546`, 5.884006934855529}, { + 29.77905654227884, 5.933549318289316}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{29.677768748849527`, 5.958648456849083}, {29.13331289014547, + 6.0935647441391865`}, {28.31862724110582, 6.301100562860422}, { + 27.533654592316132`, 6.506337986203251}, {26.777121218785936`, + 6.709000609351691}, {26.04775339552477, 6.908812027489755}, { + 25.641711890674458`, 7.022336568107484}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{25.541214659495147`, 7.050434439548462}, { + 25.344277397542175`, 7.105495835801455}, {24.66541949984768, + 7.298775629470811}, {24.009905977450824`, 7.488375003681834}, { + 23.148208836877217`, 7.740486277153068}, {22.32209740641028, + 7.983823704355556}, {21.533495492945075`, 8.216870669059556}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{21.433780440426805`, 8.24762825845424}, {20.79012690859723, + 8.446509549985405}, {20.075158559110577`, 8.664283510641763}, { + 19.389703064970227`, 8.87223398651537}, {18.733760426176186`, + 9.070360977606228}, {18.107330642728453`, 9.258664483914334}, { + 17.507291293289878`, 9.43682532109176}, {17.43872507382144, + 9.45676127246096}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{17.338523344220626`, 9.485895397456012}, {16.9305199565233, + 9.604524304790578}, {16.377016632428727`, 9.761761435010788}, { + 15.846781321006157`, 9.908536711752387}, {15.315404779113406`, + 10.05079559595937}, {14.805287045410859`, 10.181549198491028`}, { + 14.013108261210721`, 10.370643339126197`}, {13.296834760644275`, + 10.52367668482355}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{13.194373614364062`, 10.543406857001452`}, { + 12.570970589643531`, 10.658715186436451`}, {11.912819404013131`, + 10.75904231444263}, {11.065074496823504`, 10.852201311192127`}, { + 10.28020294029533, 10.894964449119497`}, {10.162866815735214`, + 10.897699965546765`}, {10.046886547930084`, 10.899290285896486`}, { + 9.709117433500413, 10.890658511444546`}, {9.382401999689897, + 10.872341309348814`}, {9.04678046343293, 10.842251332650026`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{8.942846083605277, 10.832933149132677`}, {8.671164729309828, + 10.808575696653863`}, {8.011025970770946, 10.699894286596136`}, { + 7.397584577192774, 10.550854280657987`}, {6.826439401694834, + 10.366012880321776`}, {6.294943034315532, 10.14909750592898}, { + 5.798330137123992, 9.906817514094255}, {5.121296735164822, + 9.498634570724175}, {5.0538865149316825`, 9.449398105771877}}]}, + {Arrowheads[{{0.012638712578083364`, 1.}}], + ArrowBox[{{4.969619444643511, 9.387849387513327}, {4.511707966607465, + 9.053390571600833}, {3.962028766022461, 8.584892690184596}, { + 3.468925591271482, 8.101814216812416}, {3.0278376262222397`, + 7.613364237702503}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{49.23421804558305, 0.8316664813545216}, {48.51101982045465, + 0.8566509582387026}, {47.79915966134927, 0.8818957332494143}, { + 47.09833028252699, 0.9073954298493504}, {46.40824735226441, + 0.9331435098348084}, {45.72877000144163, 0.9591261745871047}, { + 45.06299789459429, 0.9852027023781942}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{44.958730302279925`, 0.9893803531077733}, { + 44.40106856163575, 1.0117400639174792`}, {43.75256273441282, + 1.0383436912581903`}, {43.114099010149985`, 1.065126708891007}, { + 42.485536519727304`, 1.0920753181972462`}, {41.86673439402487, + 1.1191757205582245`}, {41.25755176392275, 1.1464141173552584`}, { + 40.78850246109985, 1.1678153501496118`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{40.68425965912677, 1.1725716187523691`}, { + 40.657847760301024`, 1.173776709969665}, {40.067481514039784`, + 1.2012496997827604`}, {39.48631215601908, 1.228819288175862}, { + 38.91419881711899, 1.2564716765302868`}, {38.35100062821959, + 1.2841930662273513`}, {37.79657672020095, 1.3119696586483724`}, { + 36.713460321076866`, 1.367635887312342}, {36.5152831277517, + 1.378156027799674}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{36.41107859458342, 1.3836876750591467`}, { + 35.663704880901335`, 1.4233616472885051`}, {34.64619869176009, + 1.4790351150138743`}, {33.65983004573886, 1.5345444669254624`}, { + 32.703487234923394`, 1.5897778794602806`}, {32.24356066634335, + 1.61697670549179}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{32.13939140664019, 1.6231369966470601`}, { + 31.776058551399444`, 1.6446235290553408`}, {30.876432287252744`, + 1.6989695921476553`}, {30.003496734569026`, 1.7527042451742365`}, { + 29.405692695819834`, 1.789955808501504}, {28.819480003418875`, + 1.8267349197805682`}, {28.244607992947174`, 1.8630193633547578`}, { + 27.973270007730587`, 1.8802336373921977`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{27.86912812585858, 1.8868406256908998`}, {27.68082599998575, + 1.8987869235674026`}, {27.127883360115614`, 1.9340153847618324`}, { + 26.5855294089178, 1.9686825312813758`}, {25.552974945282806`, + 2.0381397537050145`}, {24.55475397492972, 2.1046408164156496`}, { + 23.70412265418931, 2.1614065861825535`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{23.600002986878568`, 2.1683548761392686`}, { + 23.59587978623814, 2.1686300325466927`}, {22.67635237920806, + 2.2301074020981444`}, {21.796171753839484`, 2.289072925070005}, { + 20.95203716839443, 2.3453151883986934`}, {20.14064788113491, + 2.3986227790206285`}, {19.435083526714784`, 2.4442679465269648`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{19.330947785798966`, 2.450970827341683}, { + 18.616105201172488`, 2.496433942144239}, {18.002626383969353`, + 2.5346459778409858`}, {17.410148971334863`, 2.570608221642296}, { + 16.614216322693593`, 2.617129773469813}, {15.855851598895057`, + 2.659202369632701}, {15.164083814979126`, 2.6952386266731256`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{15.059859785893886`, 2.7003866714439924`}, { + 14.444372621614194`, 2.730088259651493}, {13.862994411619322`, + 2.7558393425949537`}, {13.304444661273038`, 2.778325497332481}, { + 12.255830539526233`, 2.8135030221897366`}, {11.291035103044868`, + 2.8362826319066285`}, {10.888438256837626`, 2.8412868139547105`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{10.784095064693158`, 2.842583774757777}, { + 10.402563198500038`, 2.847326124166525}, {10.242401412705563`, + 2.8483009528073273`}, {10.084711198244852`, 2.848888105358699}, { + 9.745923882541744, 2.847501297711473}, {9.41848089887902, + 2.844327527556718}, {8.646481286148136, 2.8316578528546787`}, { + 7.93728238657567, 2.809222879634646}, {7.285830078242592, + 2.7780381648152788`}, {6.687070239229876, 2.7391192653152365`}, { + 6.612878458040452, 2.732291395190102}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.5089663210109405`, 2.7227283605158}, {5.630927116849549, + 2.6419224066125797`}, {4.902061320825722, 2.547617296684414}, { + 4.265843246427178, 2.4439054882570947`}, {3.221378058167581, + 2.220748895938165}, {2.426380730132568, 1.9901834985655629`}, { + 2.4105078953076413`, 1.984243226294471}}]}, + {Arrowheads[{{0.005629882578595802, 1.}}], + ArrowBox[{{2.312776420891829, 1.9476680603654792`}, { + 1.8238352430992246`, 1.7646860188668028`}, {1.2357375630633354`, + 1.4810766224636773`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{5.422804138815669, 49.06237784513235}, {5.7180125415408005`, + 48.133769060446994`}, {6.014336342928001, 47.28615002998856}, { + 6.311698936632197, 46.513273102085286`}, {6.610023716308318, + 45.80889062506539}, {6.909310681956363, 45.17300259892887}, { + 6.912053336794484, 45.16781968758377}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.960860777942236, 45.075586192893226`}, {7.209559833576332, + 44.605609023675726`}, {7.483906494512723, 44.146652133038145`}, { + 7.759958768910425, 43.73929533460663}, {8.335785207985936, + 43.059172850025035`}, {8.926926102444082, 42.58849496636557}, { + 9.847123551312599, 42.28562331774599}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{9.950103394162635, 42.27291046265703}, {10.019922948842948`, + 42.2709011462738}, {10.382896418236934`, 42.339410749903585`}, { + 10.763334442566057`, 42.476789676779525`}, {11.26829736297392, + 42.714511728431034`}, {11.809766888230172`, 43.07616914481139}, { + 12.39763034537957, 43.57653615607823}, {13.041775061466872`, + 44.23038699238919}, {13.330011975063499`, 44.55115918224427}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{13.398873335225309`, 44.62954192432216}, { + 13.755564037444334`, 45.05943886363038}, {14.14926552365368, + 45.5570389552587}, {14.563050675026018`, 46.102782747596784`}, { + 15.072901269461736`, 46.80456011431776}, {15.625697769140709`, + 47.59766554212114}, {15.883495936148474`, 47.98090219291252}}]}, + {Arrowheads[{{0.011063788351635493`, 1.}}], + ArrowBox[{{15.941739949700994`, 48.0674863643269}, { + 16.227985067083072`, 48.493011577962676`}, {16.549733044471818`, + 48.98243499482141}, {16.886308056308966`, 49.50151076879809}, { + 17.205344462523815`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{22.222492756922126`, 13.72251761101824}, {21.66929228011176, + 14.113318870339784`}, {21.142564235439213`, 14.49672133070915}, { + 20.640011337705104`, 14.872129011079782`}, {20.16065016729063, + 15.239479707064227`}, {19.70349730457699, 15.598711214275042`}, { + 19.267569329945385`, 15.949761328324776`}, {18.90272055134584, + 16.25064321163222}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{18.822623251580477`, 16.31752303899174}, { + 18.077300538354766`, 16.953201267633034`}, {17.37014221868529, + 17.57925159667856}, {16.72219233328327, 18.170048746679374`}, { + 16.127672572407757`, 18.72612978363757}, {15.72321280012335, + 19.112124906420206`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{15.647722275241327`, 19.184169090829904`}, { + 15.580804626317798`, 19.248031773555244`}, {15.072466396313434`, + 19.737848990112823`}, {14.603636647296515`, 20.193344972746964`}, { + 14.168525878325624`, 20.615502995050935`}, {13.763917699988866`, + 21.00486932013211}, {13.033859609411712`, 21.688223719336833`}, { + 12.703376992889382`, 21.98358466362569}, {12.618989081820196`, + 22.055645316505284`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{12.539633529628224`, 22.123408729867727`}, { + 12.392201857783952`, 22.24930380646843}, {11.55646217873036, + 22.873509680976852`}, {10.828553749993715`, 23.25916605743531}, { + 10.782732246394643`, 23.27731235231735}, {10.737227466659883`, + 23.294468469578415`}, {10.474773473670641`, 23.357407149545708`}, { + 10.219843328184421`, 23.38669263645188}, {9.72221989622388, + 23.37922827640576}, {9.244038857934463, 23.243058776821357`}, { + 8.811694353927784, 23.00404400122332}}]}, + {Arrowheads[{{0.015757229165579895`, 1.}}], + ArrowBox[{{8.727151169542925, 22.9436239632191}, {8.249087343926496, + 22.546564053748188`}, {7.719829863785956, 21.966740141979948`}, { + 7.1832687862815385`, 21.256369245500245`}, {6.639725907738225, + 20.42673827847845}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{50., 11.46237682901988}, {49.88912467024407, + 11.54287682992053}, {49.25623860318609, 12.033250972594347`}, { + 48.648364699713916`, 12.536329915833266`}, {48.065187743679964`, + 13.052353449233644`}, {47.50641146893203, 13.581532094528852`}, { + 46.97177277180982, 14.124025154692017`}, {46.87881788721517, + 14.225206532213788`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{46.80822049649411, 14.302051781107908`}, {46.461008548653, + 14.679991932696266`}, {46.07297034319253, 15.129707180118553`}, { + 45.69935357310561, 15.587521199686858`}, {45.340201495431835`, + 16.053864744570316`}, {44.995557367210786`, 16.52916856793806}, { + 44.66546444548206, 17.01386342295924}, {44.349965987285245`, + 17.508380062802974`}, {44.28484174168989, 17.617642282146665`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{44.23141494137347, 17.70727910974655}, {44.04910524965994, + 18.013149240638413`}, {43.762925489645724`, 18.528601709634685`}, { + 43.399137500753675`, 19.243569870713735`}, {43.06213999586156, + 19.980034893791803`}, {42.752167766312844`, 20.7390106592554}, { + 42.47604906510501, 21.486080922461145`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{42.443016317651974`, 21.585047099552863`}, { + 42.20981639498403, 22.30945519160593}, {41.98017648554454, + 23.132752563002157`}, {41.778031434135414`, 23.980588437556936`}, { + 41.60338124075667, 24.85296281527026}, {41.4756787296126, + 25.639687107466084`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{41.45895908108163, 25.742690200658583`}, { + 41.457314387332445`, 25.75282250357195}, {41.34091935578689, + 26.68311430989181}, {41.25419614612001, 27.64383823422985}, { + 41.197144758331795`, 28.634994276586063`}, {41.17077797668167, + 29.263550328445145`}, {41.1566170833663, 29.903098093408616`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{41.159225073015406`, 30.0074141801061}, {41.18290278128267, + 30.916477862011032`}, {41.239470154571414`, 31.96373594165704}, { + 41.310524231197896`, 33.00682029690799}, {41.41314628077346, + 34.08959161499589}, {41.42248237616456, 34.1718315939104}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{41.43425299715218, 34.27551686931529}, {41.476295295417145`, + 34.645859885103704`}, {41.54733630329811, 35.21204989592076}, { + 41.62626930441633, 35.78816164744705}, {41.713094298771836`, + 36.37419513968258}, {41.808699349169395`, 36.97178450283095}, { + 41.91397251841377, 37.58256386709577}, {42.028913806504974`, + 38.20653323247704}, {42.066788708726065`, 38.400197172450326`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{42.08681727815155, 38.50260830593195}, {42.15352321344301, + 38.84369259897476}, {42.28780073922787, 39.49404196658893}, { + 42.43174638385956, 40.15758133531955}, {42.58536014733808, + 40.834310705166615`}, {42.74864202966342, 41.524230076130124`}, { + 42.902547693371, 42.193979072960275`}, {43.002900928586094`, + 42.574297861926645`}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{43.029524445517225`, 42.67519569243077}, { + 43.097046136761335`, 42.931089463945746`}, {43.30192910040782, + 43.68264479179374}, {43.51755478501513, 44.4492725243773}, { + 43.74428139128791, 45.23160012956945}, {43.982467119930845`, + 46.03025507524323}, {44.1835404360481, 46.68623649936296}}]}, + {Arrowheads[{{0.016199078980985673`, 1.}}], + ArrowBox[{{44.21412206270687, 46.78600597347767}, {44.23247017164858, + 46.84586482927169}, {44.49464874714579, 47.679056859527854`}, { + 44.66394023488933, 48.20566914183808}, {44.83892860311367, + 48.74074678767328}, {45.01978687836011, 49.28458485565135}, { + 45.20668808716997, 49.83747840439018}, {45.26251030228074, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{48.5151686627396, 6.445255918115043}, {47.649670000756565`, + 6.734681197013667}, {46.78858005312277, 7.037906999039333}, { + 45.95225028413573, 7.346977339326902}, {45.14068069379543, + 7.6618922178763755`}, {44.597685680959884`, 7.883255563383042}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{44.50105568739623, 7.922648814049999}, {44.35387128210187, + 7.9826516346877545`}, {43.59182204905506, 8.309255589761037}, { + 42.85453299465499, 8.641704083096224}, {42.14200411890167, + 8.979997114693315}, {41.45423542179509, 9.324134684552309}, { + 40.78898836464187, 9.673702180867823}, {40.72946927608399, + 9.706424080338618}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{40.638026227600164`, 9.756696863613532}, { + 40.144024408748606`, 10.028284991834468`}, {39.519343554115316`, + 10.387883117452244`}, {38.914945800742, 10.752496557721152`}, { + 38.33083114862863, 11.122125312641192`}, {37.76699959777524, + 11.496769382212364`}, {37.223451148181816`, 11.876428766434667`}, { + 37.10061479935517, 11.966731011072298`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{37.01653803166484, 12.028539432739311`}, { + 36.700185799848356`, 12.261103465308103`}, {36.19547103156106, + 12.650600022169911`}, {35.70757432210614, 13.04472498035733}, { + 35.23649567148359, 13.443478339870362`}, {34.7822350796934, + 13.846860100709005`}, {34.34479254673558, 14.254870262873261`}, { + 33.924168072610144`, 14.66750882636313}, {33.85145100854384, + 14.742649853013779`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{33.77888294186041, 14.817636915578268`}, {33.52036165731707, + 15.084775791178611`}, {33.133373300856356`, 15.506671157319705`}, { + 32.664784329928494`, 16.052416659563114`}, {32.22060981863194, + 16.605916986572577`}, {31.69018511154382, 17.315825970278464`}, { + 31.196741637946694`, 18.037629092949565`}, {31.17546955434721, + 18.071822146928035`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{31.120347305636216`, 18.160426444517174`}, { + 30.739513687939585`, 18.77258389424782}, {30.31773555162152, + 19.521947913835163`}, {29.966400820102244`, 20.211927889342782`}, { + 29.642298400859875`, 20.915646369943257`}, {29.34525434268344, + 21.633992407772915`}, {29.25258426489671, 21.884187169646278`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.21633973648338, 21.982041745493895`}, {29.07695017394571, + 22.35837183218061}, {28.83492158582452, 23.101379548430952`}, { + 28.619603456347306`, 23.860792926183127`}, {28.43099578551407, + 24.636611965437133`}, {28.269098573324815`, 25.428836666192975`}, { + 28.17163106156758, 26.01573783387062}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{28.15453544340601, 26.118679194333243`}, {28.13434409265668, + 26.24026152590325}, {28.0271646163868, 27.073681042020564`}, { + 27.947560144515183`, 27.929095214544912`}, {27.895530677041823`, + 28.80650404347629}, {27.876841465838986`, 29.240676560122132`}, { + 27.864960647756902`, 29.680932878497988`}, {27.878765470837422`, + 30.278241465498656`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{27.881176562902063`, 30.382564859276265`}, { + 27.88816919127769, 30.6851226646249}, {27.94692749720561, + 31.72679844192237}, {28.011034837116327`, 32.629532214216155`}, { + 28.10334543037533, 33.564716444154136`}, {28.223859276982616`, + 34.53235113173631}, {28.225070250223766`, 34.540494622633474`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{28.24041896934092, 34.64371090369264}, {28.372576376938188`, + 35.532436276962684`}, {28.552886852606758`, 36.57178034826968}, { + 28.656160902220186`, 37.108727656867075`}, {28.768180826353046`, + 37.65719181409373}, {28.88894662500533, 38.21717281994965}, { + 29.00857095469376, 38.745040664499236`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.032214035756287`, 38.84667689105597}, { + 29.156715845868195`, 39.371685377549284`}, {29.30371926807877, + 39.966216929293}, {29.439764481466057`, 40.53591400049635}, { + 29.61655154169731, 41.17615609747588}, {29.80282569588408, + 41.82928249120391}, {29.998957553744415`, 42.49597690574005}, { + 30.114390647733924`, 42.876882395124895`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{30.144655008685373`, 42.976748567127345`}, { + 30.20531772499636, 43.176923065143924`}, {30.422276819357954`, + 43.872804693475146`}, {30.650205446547247`, 44.584305514793336`}, { + 30.889474216282284`, 45.3121092531581}, {31.188332202941194`, + 46.195123239514565`}, {31.449093099805694`, 46.94138319331566}}]}, + {Arrowheads[{{0.01512400590771079, 1.}}], + ArrowBox[{{31.4835149977021, 47.039893684124664`}, { + 31.507645673424825`, 47.108952186248885`}, {31.848733468619592`, + 48.055929776770334`}, {32.212914429411924`, 49.03838969448818}, { + 32.40407698468418, 49.54365480211115}, {32.57901781468988, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{50., 19.16442344844397}, {49.706477758445516`, + 19.818188959844363`}, {49.389871011808275`, 20.591911864344176`}, { + 49.10206576003426, 21.394857633328577`}, {48.842263402555886`, + 22.22442292313457}, {48.61046393937317, 23.080607733762147`}, { + 48.60773112707541, 23.092445708006146`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{48.58425882886829, 23.194122819841102`}, {48.4066673704861, + 23.963412065211315`}, {48.232079498493334`, 24.87577676974791}, { + 48.087906125993534`, 25.820642699637773`}, {47.97414725298669, + 26.7980098548809}, {47.93171908588279, 27.312104119417537`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{47.92313616399198, 27.416101798747597`}, {47.8908028794728, + 27.807878235477293`}, {47.84608234555539, 28.481352352151365`}, { + 47.81513451712641, 29.170323629221468`}, {47.81940832124887, + 30.156688155653644`}, {47.85184215946753, 31.177306034106316`}, { + 47.87075797698969, 31.58567971682966}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{47.87558633692381, 31.689919204522994`}, {47.9014066349487, + 32.2473537526776}, {47.93834963643672, 32.79782495052778}, { + 47.98339981375637, 33.35859437408766}, {48.03655716690765, + 33.92966202335723}, {48.09782169589055, 34.51102789833649}, { + 48.16719340070508, 35.10269199902545}, {48.24467228135124, + 35.7046543254241}, {48.26433133335004, 35.844242617533}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{48.27888412581179, 35.94757412330828}, {48.33112025730474, + 36.31847463173155}, {48.42739924804128, 36.94571267214686}, { + 48.53350925356087, 37.586368446670065`}, {48.64945027386351, + 38.240441955301144`}, {48.77522230894919, 38.907933198040105`}, { + 48.91082535881792, 39.58884217488695}, {49.00876631543992, + 40.056428791832154`}}]}, + {Arrowheads[{{0.019797137831981355`, 1.}}], + ArrowBox[{{49.03015952525968, 40.15856357742369}, {49.05625942346969, + 40.28316888584167}, {49.21152450290451, 40.99091333090427}, { + 49.35860584479218, 41.680847365252156`}, {49.54477099678277, + 42.434908158843044`}, {49.741444834490466`, 43.203561412992826`}, { + 49.948966193382276`, 43.987394490926995`}, {50., + 44.17397522124705}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{50., 8.00659447809414}, {49.551585268260126`, + 8.20165550436517}, {48.732669981643205`, 8.579218405864788}, { + 47.94184350682008, 8.965896258791744}, {47.17910584379076, + 9.361689063146041}, {46.44445699255524, 9.766596818927678}, { + 46.26759995896502, 9.869919437641153}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{46.177498162532814`, 9.922558302882639}, {45.73578254263073, + 10.180615410640526`}, {45.05096808353443, 10.60374072278846}, { + 44.39001361526635, 11.03597275537148}, {43.752919137826474`, + 11.477311508389585`}, {43.139684651214814`, 11.927756981842776`}, { + 42.72027951485643, 12.254779192543133`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{42.6379874849117, 12.31894464790501}, {42.550310155431376`, + 12.38730917573105}, {41.984795650476144`, 12.855968090054409`}, { + 41.443141136349126`, 13.333733724812856`}, {40.94362640894774, + 13.80452473925534}, {40.46436105413998, 14.284153438354512`}, { + 39.80912140585641, 14.986800383757481`}, {39.62677441807408, + 15.200520524520323`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{39.559043927007586`, 15.279904177964305`}, { + 39.19391878402458, 15.70784981009908}, {38.61820076101852, + 16.447981651547273`}, {38.08141490921222, 17.20787584227002}, { + 37.58248592463907, 17.98708142631499}, {37.17308640126758, + 18.695501630181173`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{37.120873195268885`, 18.785850758420242`}, { + 37.12075680440495, 18.786052159826088`}, {36.696302572492634`, + 19.60682504511563}, {36.309198252884904`, 20.451437084495943`}, { + 36.01905069441263, 21.164590767576065`}, {35.7539728043095, + 21.896471803001962`}, {35.519208237666376`, 22.632296873992228`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{35.49016766783572, 22.73251837673516}, {35.29770815368151, + 23.409533715600624`}, {35.10741095913884, 24.19536008809444}, { + 34.94277647695342, 25.003010809814725`}, {34.803804707125266`, + 25.832485880761478`}, {34.69049564965438, 26.6837853009347}, { + 34.67696841400582, 26.82068624107748}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{34.666707395813475`, 26.924531777138874`}, { + 34.60391999442763, 27.559964950786444`}, {34.54514843133188, + 28.46408071076875}, {34.51418096036715, 29.396132580881627`}, { + 34.51101758153343, 30.356120561125074`}, {34.51735362207428, + 30.930775198570107`}, {34.52193665493144, 31.092959998371985`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{34.52488424551125, 31.19726961232964}, {34.53390395990877, + 31.516460117705645`}, {34.613081163642576`, 32.58280928110656}, { + 34.67414084003737, 33.14181336751139}, {34.726612086621, + 33.69048565203447}, {34.842930430005026`, 34.69718648170021}, { + 34.934365996443184`, 35.34935245291421}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{34.9488546380153, 35.45269297313555}, {34.98946297256155, + 35.742332715856996`}, {35.074059568529485`, 36.279322859619526`}, { + 35.166209714290545`, 36.82592435450482}, {35.265913409844735`, + 37.38213720051288}, {35.37317065519204, 37.9479613976437}, { + 35.48893185528895, 38.525156536649384`}, {35.614147415091956`, + 39.11548220828203}, {35.7122742180686, 39.55518862732703}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{35.73500261170108, 39.657034608971415`}, {35.74881733460104, + 39.71893841254165}, {35.89294161381621, 40.33552514942823}, { + 36.04652025273747, 40.96524241894178}, {36.209553251364824`, + 41.60809022108229}, {36.38204060969826, 42.264068555849775`}, { + 36.563982327737776`, 42.93317742324422}, {36.73454281651448, + 43.578754746228405`}, {36.77067888812028, 43.70012306485433}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{36.800456470599016`, 43.8001354612657}, {36.94839100382452, + 44.2969953789721}, {37.1724773347517, 45.02974568203696}, { + 37.40719370125155, 45.77769522427006}, {37.6529319952796, + 46.54153357451852}, {37.91008410879138, 47.32195030162941}, { + 38.0638872958489, 47.77810525815113}}]}, + {Arrowheads[{{0.010772430747056715`, 1.}}], + ArrowBox[{{38.0972275785963, 47.87698705324277}, {38.17904193374241, + 48.11963497444984}, {38.46019736208822, 48.9352771618269}, { + 38.81903635775576, 49.95032318875829}, {38.836973701191006`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{23.470220821913333`, 15.085565547830058`}, { + 22.981366107675314`, 15.518284548499466`}, {22.51639893692169, + 15.947079180848966`}, {22.074405893235802`, 16.371904793283985`}, { + 21.654473560200984`, 16.79271673420994}, {21.25568852140058, + 17.209470352032262`}, {20.87713736041792, 17.62212099515637}, { + 20.52104676307981, 18.033834921251263`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{20.45278368851573, 18.112761067142728`}, { + 20.175251966848197`, 18.433644784931886`}, {19.54114384028032, + 19.226672897579935`}, {18.969702896650194`, 20.00239607954362}, { + 18.455819051893734`, 20.762005077266046`}, {18.07020937629293, + 21.37796775552071}, {18.00638071623046, 21.487912928234255`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{17.95398867495026, 21.578158470310946`}, { + 17.718793488507583`, 21.98328330560478}, {17.398636370309323`, + 22.57909086577481}, {17.108107456015723`, 23.166023290617776`}, { + 16.845675143169853`, 23.74504069512406}, {16.60980782931478, + 24.317103194284048`}, {16.399575590598833`, 24.883052815195416`}, { + 16.237206627866204`, 25.37293915655153}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{16.2053980674546, 25.47230938707473}, {16.045117233213617`, + 26.022835261275823`}, {15.900869356050205`, 26.59921837812327}, { + 15.78019740906542, 27.175178656115946`}, {15.682503269132331`, + 27.752398708975104`}, {15.612922462502699`, 28.286119413998488`}, { + 15.562478980771743`, 28.826173923832307`}, {15.531172823939466`, + 29.37256223847656}, {15.526667513662884`, 29.57719853047741}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{15.524370653873001`, 29.681524501785265`}, { + 15.519003992005867`, 29.92528435793125}, {15.51828034339738, + 30.079992856580102`}, {15.519056007726483`, 30.235480800083707`}, { + 15.55031846211015, 30.846938063698044`}, {15.605096918336777`, + 31.477023789484207`}, {15.672286136286775`, 32.118324809133796`}, { + 15.764296877683512`, 32.782056416510244`}, {15.88261608950664, + 33.472327519599645`}, {15.954143042595671`, 33.825236574737076`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{15.97487130339802, 33.92750838443228}, {16.02873071873582, + 34.19324702638811}, {16.20451650071959, 34.94924342482441}, { + 16.41334975908533, 35.748287993216366`}, {16.662023958756293`, + 36.61085431151899}, {16.952030328464485`, 37.532061136412345`}, { + 17.09255864317092, 37.946257499956985`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{17.12608576403821, 38.04507610154885}, {17.287515595341052`, + 38.52087807236833}, {17.473608667445955`, 39.04344333339228}, { + 17.672626486517135`, 39.58627472385885}, {17.886137999878457`, + 40.15216237691478}, {18.116035418371467`, 40.74440994342615}, { + 18.36332197816409, 41.364908900530885`}, {18.60172543837519, + 41.94875368701877}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{18.641408767784313`, 42.04526416382306}, { + 18.914075466319854`, 42.69822689507231}, {19.219548867018837`, + 43.4148288867849}, {19.54642435368911, 44.16724817764269}, { + 19.895705162498594`, 44.95737624478362}, {20.170394327145438`, + 45.5694559640595}, {20.307977928927432`, 45.871953079265694`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{20.35118088123575, 45.96694091409767}, {20.461257930489893`, + 46.20896096167972}, {20.76929348378262, 46.877654262768814`}, { + 21.09549849827426, 47.57729889245131}, {21.44087048521547, + 48.30965787585175}, {21.806406955856904`, 49.07649423809468}, { + 22.127788009699607`, 49.743922946522126`}}]}, + {Arrowheads[{{0.0008629872787197494, 1.}}], + ArrowBox[{{22.173060242135065`, 49.83794214043768}, { + 22.193105421449207`, 49.87957100430463}, {22.251647228996497`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{37.48627654338087, 8.809842802380324}, {36.626219069263136`, + 9.21585371115884}, {35.80226208661862, 9.627039379453516}, { + 35.01285610304464, 10.04302671328968}, {34.25645162613851, + 10.463442618692657`}, {33.78663623092154, 10.738527125383836`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{33.696585491948284`, 10.7912532883828}, { + 33.531499163497536`, 10.88791400168778}, {32.94462640124435, + 11.24717935044862}, {32.376469636764234`, 11.608337642631321`}, { + 31.826502929173795`, 11.971296721113163`}, {31.29420033758966, + 12.335964428771419`}, {30.779035921128447`, 12.702248608483362`}, { + 30.280483738906774`, 13.07005710312627}, {30.22840296815164, + 13.109915543313623`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{30.145535284328624`, 13.173335814773386`}, { + 29.798017850041262`, 13.439297755577417`}, {29.37599260236369, + 13.81774248318664}, {28.941039242642436`, 14.192535367333754`}, { + 28.521120294510578`, 14.568576095043651`}, {28.116235757968116`, + 14.945864666316337`}, {27.726385633015052`, 15.324401081151812`}, { + 27.076981316341534`, 15.99698403266353}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{27.004498707194276`, 16.072053701807786`}, { + 26.991788617877116`, 16.085217441511123`}, {26.317329249096773`, + 16.85102517612158}, {25.69710844926041, 17.62179219238419}, { + 25.12522714095442, 18.397486397699954`}, {24.601685324178806`, + 19.178107792068865`}, {24.476263556048252`, 19.385440305087194`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{24.4222519352974, 19.474725962827325`}, {24.12648299893357, + 19.96365637549093}, {23.744421429858292`, 20.663037850868964`}, { + 23.395450104871276`, 21.36761829633955}, {23.06036026273179, + 22.120782852835685`}, {22.760123381498413`, 22.881453612134287`}, { + 22.63672669637018, 23.23800092580061}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{22.60259811312328, 23.336613418212988`}, {22.49387862209047, + 23.65075186067304}, {22.260765145427275`, 24.429798884889625`}, { + 22.089025944988165`, 25.09846013370916}, {21.940365247875135`, + 25.777476997508224`}, {21.814783054088192`, 26.466849476286814`}, { + 21.712279363627335`, 27.16657757004493}, {21.68635092953108, + 27.4002194036681}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{21.67484119228529, 27.50393396292935}, {21.633149117660903`, + 27.879622395429116`}, {21.577687257357237`, 28.608945069085923`}, { + 21.545893782716345`, 29.35454559101535}, {21.53776869373822, + 30.116423961217393`}, {21.5392741412956, 30.42895785101014}, { + 21.54481625445728, 30.744776369430802`}, {21.609285429293784`, + 31.67055681197811}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{21.616534649388687`, 31.774655960208236`}, { + 21.617531093272618`, 31.788964942170228`}, {21.682061597244324`, + 32.340272885302326`}, {21.735322867390412`, 32.879895365729475`}, { + 21.830761850326166`, 33.66274911347372}, {21.951141515156483`, + 34.474479513898956`}, {22.096461861881362`, 35.315086567005174`}, { + 22.211774035222952`, 35.90395917403917}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{22.231827095226194`, 36.00636551485227}, { + 22.266722890500805`, 36.184570272792385`}, {22.465406975195005`, + 37.09010777350419}, {22.695996490144154`, 38.038876211384164`}, { + 22.958491435348257`, 39.03087558643232}, {23.249219889922813`, + 40.05319394567386}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{23.27737268978264, 40.15367568207321}, {23.391168625837675`, + 40.560731551471335`}, {23.57134009587752, 41.12982065095849}, { + 23.76027367554548, 41.71119213444517}, {23.95836224087375, + 42.3055833267851}, {24.16599866789452, 42.913731552832004`}, { + 24.38357583263998, 43.53637413743964}, {24.590315868425485`, + 44.11499595543403}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{24.625691157055126`, 44.21316750181388}, {24.85012387943372, + 44.828091681752}, {25.13732960246073, 45.59660623650886}, { + 25.443211146227988`, 46.394217482154964`}, {25.769079260910146`, + 47.2232764622927}, {26.11624469668185, 48.08613422052446}, { + 26.125331449227513`, 48.10822628298985}}]}, + {Arrowheads[{{0.009318544673586782, 1.}}], + ArrowBox[{{26.165025892478358`, 48.20473294094269}, { + 26.486018203717755`, 48.985141800452595`}, {26.879710532192508`, + 49.92265024567952}, {26.91283074798475, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{7.380939549637546, 50.}, {7.739938473640906, + 49.550735516622474`}, {8.217865940968393, 49.08735724752728}, { + 8.714360981517045, 48.73862405116805}, {9.251282448099278, + 48.501898103269035`}, {9.815927622112142, 48.39445465182176}, { + 9.92423077255682, 48.386441588483436`}, {10.03368119572553, + 48.38314483829652}, {10.396188183227663`, 48.43740701051539}, { + 10.77402969866314, 48.54381143026198}, {10.949430844116431`, + 48.61092876121355}}]}, + {Arrowheads[{{0.011896609445858982`, 1.}}], + ArrowBox[{{11.046890646469466`, 48.64822180050414}, { + 11.373496363207295`, 48.77319763190089}, {12.016547901203626`, + 49.13599711929082}, {12.713002524091502`, 49.64739883655534}, { + 13.109722656106657`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{14.190613870852335`, 21.989082681500314`}, { + 13.760419804759046`, 22.51401904926761}, {13.371275679548933`, + 22.994973110183707`}, {12.691917071134574`, 23.834948410836674`}, { + 12.120358333625525`, 24.523580848348047`}, {11.867595380330492`, + 24.81506608519778}, {11.632741409547945`, 25.07379556891386}, { + 11.5142160679752, 25.19031122425383}}]}, + {Arrowheads[{{0.013098281174180656`, 1.}}], + ArrowBox[{{11.439800400179545`, 25.263465118482014`}, { + 11.133139147050304`, 25.564926699622447`}, {10.696191592637298`, + 25.895136251624617`}, {10.668499387375153`, 25.912191791166414`}, { + 10.640993637960138`, 25.928579700536275`}, {10.435612375063256`, + 26.01285669135882}, {10.236493365647785`, 26.05887068812279}, { + 9.846791987147515, 26.075293846849068`}, {9.466852803349513, + 25.9432905861258}, {9.083403963254911, 25.666758005267006`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{0.9701099597005121, 50.}, {0.9731407875071092, + 49.893201640121646`}, {0.9955140278346496, 49.110658591026066`}, { + 1.0174858373962665`, 48.342315514907355`}, {1.038928373388392, + 47.58690107203786}, {1.059841635811026, 46.844415262417584`}, { + 1.0802256246641688`, 46.11485808604654}, {1.0881837530036005`, + 45.82762042807017}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{1.0910737713986183`, 45.72330920313297}, { + 1.1000803399478198`, 45.39822954292471}, {1.1194057816619793`, + 44.694529633052106`}, {1.1382019498066474`, 44.003758356428726`}, { + 1.1564688443818238`, 43.32591571305456}, {1.1750794788742331`, + 42.62478462227685}, {1.1929691871918549`, 41.93641205434676}, { + 1.2028816452931017`, 41.55075768148098}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{1.205562895608084, 41.446440881535}, {1.2104984324220909`, + 41.254418747840184`}, {1.2264981435506106`, 40.59671690481822}, { + 1.2413673741773048`, 39.97484246280159}, {1.2554754673414465`, + 39.36280525816519}, {1.268822423043036, 38.76060529090903}, { + 1.2814082412820733`, 38.16824256103309}, {1.2932329220585586`, + 37.58571706853739}, {1.2992655091525593`, 37.27344895707759}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{1.301281054636046, 37.169117171745285`}, {1.304296465372491, + 37.013028813421926`}, {1.3145988712238716`, 36.450177795686685`}, { + 1.3241401396127, 35.89716401533168}, {1.3408857395246483`, + 34.81737487943436}, {1.3544797406302853`, 33.77038811840195}, { + 1.3624579347211427`, 32.99553194595931}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{1.363532315292604, 32.8911862246258}, {1.3649221429296108`, + 32.75620373223443}, {1.3722129464226245`, 31.774821720931826`}, { + 1.3737069851424102`, 31.522552660045047`}, {1.3749900576958953`, + 31.27232977004853}, {1.3759812349625555`, 30.28409045732634}, { + 1.3736539266244303`, 29.326830790810384`}, {1.3717963879300215`, + 28.774913201739423`}, {1.3714913662437465`, 28.717185341272476`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{1.3709400042085529`, 28.612835545613223`}, { + 1.3689306744469432`, 28.232553377722535`}, {1.3650567861751959`, + 27.699751318759713`}, {1.3601747231147796`, 27.176507024850963`}, { + 1.3473860726279392`, 26.15869173219567}, {1.3305647229864224`, + 25.179107499756654`}, {1.3146727021752485`, 24.439223030873784`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{1.3124318525091716`, 24.334895841479092`}, { + 1.3102774346454749`, 24.234592655636785`}, {1.2870909680603433`, + 23.321985527938935`}, {1.2610053232310272`, 22.4412861166631}, { + 1.2320205001575268`, 21.59249442180928}, {1.1993699663266277`, + 20.778507775549755`}, {1.1746425776762055`, 20.1631955959647}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{1.1704524234887075`, 20.058928504022386`}, { + 1.167397405979878, 19.98290796224163}, {1.1331388933995155`, + 19.216897999617697`}, {1.096901041590826, 18.479318954809052`}, { + 1.0393175560071022`, 17.414937267260242`}, {0.97970881613222, + 16.407506273963712`}, {0.9470757215035309, 15.890943338590052`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{0.9404966016567355, 15.786799692426383`}, { + 0.9193811647063893, 15.452554588893387`}, {0.85964094446982, + 14.545610826023198`}, {0.8009836839805076, 13.684872161453569`}, { + 0.7434415894066099, 12.870060663928626`}, {0.6876260199035819, + 12.098992286387864`}, {0.6527109424583515, 11.622702526725856`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{0.6450818014200863, 11.518630532120005`}, { + 0.6341483346268778, 11.369482981770775`}, {0.5831665951154305, + 10.679887114918717`}, {0.534579835698731, 10.02886671461697}, { + 0.48861087471807224`, 9.414699229720913}, {0.44548253051474695`, + 8.83566210908592}, {0.36758214368723335`, 7.776349606859256}, { + 0.3375581452637891, 7.3559262088693185`}}]}, + {Arrowheads[{{0.005977184805582084, 1.}}], + ArrowBox[{{0.33012496445705825`, 7.25184003458418}, { + 0.3005475777104635, 6.837670500457238}, {0.24391889382623366`, + 6.007370240696041}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{3.662177501068409, 49.028240396498525`}, {3.803583529581349, + 48.09430696972094}, {3.9429186269238428`, 47.198057460364524`}, { + 4.079993747411388, 46.338021730281355`}, {4.214619845359483, + 45.51272964132353}, {4.315774016081059, 44.90573532957899}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{4.33292735095522, 44.802803570840894`}, {4.346607875083623, + 44.72071105534313}, {4.475768790899307, 43.96049583419224}, { + 4.601913547122033, 43.230613839722956`}, {4.724661028457513, + 42.52919567203556}, {4.843699963105929, 41.85451711732192}, { + 4.958946070624479, 41.20532581657145}, {5.050612067722278, + 40.69093444996175}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{5.0689193428094255`, 40.58820165318728}, {5.070315070570358, + 40.5803694107736}, {5.177722682500765, 39.978395540917774`}, { + 5.281084625972898, 39.398151847993404`}, {5.380316620543952, + 38.83838597298993}, {5.475334385771126, 38.29784555689677}, { + 5.607599427641654, 37.530962460156616`}, {5.730158280389231, + 36.80165762018195}, {5.782890591963492, 36.47571834971359}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{5.799556429844104, 36.372706536303866`}, {5.842812300528163, + 36.10534130020226}, {5.945451130566394, 35.43946364645617}, { + 6.038018948288843, 34.801320951593844`}, {6.120459931480426, + 34.18820950826547}, {6.192780431775049, 33.59829634392677}, { + 6.255007166286044, 33.02862163997665}, {6.326733525694626, + 32.23322615113391}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{6.3348837266731115`, 32.129201994420114`}, { + 6.384503346902058, 31.36262169679778}, {6.413678580826118, + 30.577417021797316`}, {6.419703984186642, 29.815516508576927`}, { + 6.418958912917197, 29.714788992390215`}, {6.417807196246605, + 29.614380878041487`}, {6.399272200862874, 29.10477159692873}, { + 6.3703959794303335`, 28.59998786441578}, {6.320700022141414, + 27.960421208352315`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{6.312616031767383, 27.85638355673592}, {6.292517266068536, + 27.59772065797574}, {6.175557890157135, 26.605518909229296`}, { + 6.022005863339529, 25.61536735240541}, {5.883975062146253, + 24.87009674551967}, {5.728252430886634, 24.122298195706552`}, { + 5.641036533116933, 23.74036642895198}}]}, + {Arrowheads[{{0.012709842916010137`, 1.}}], + ArrowBox[{{5.617805444264102, 23.63863393480712}, {5.556330854214666, + 23.36942729486526}, {5.369703216784341, 22.608939634895012`}, { + 5.170150352386805, 21.84142338430829}, {4.9596176371772875`, + 21.06925675539658}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{7.223677525521819, 42.45604326642656}, {7.497133560630535, + 41.94542101834788}, {7.784543577477226, 41.47099433415936}, { + 8.071472584678805, 41.05871777105589}, {8.501269585321605, + 40.554542511029304`}, {8.935099171080322, 40.18135840847174}, { + 9.79142740754636, 39.830545392507595`}, {9.851358910686436, + 39.8227871657933}, {9.91160966135354, 39.81725945125586}, { + 10.165185553735444`, 39.85735712535744}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{10.26825613547345, 39.87365556192083}, {10.271050472398839`, + 39.87409742731391}, {10.648853098983556`, 40.01144895832334}, { + 11.102289170029579`, 40.22969418935258}, {11.588243147047937`, + 40.56655519199345}, {12.116508120877484`, 41.03623359794114}, { + 12.69687718235707, 41.65293103889084}, {13.342640093719977`, + 42.43815690621982}, {13.405612675925394`, 42.521353027528946`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{13.468591166752898`, 42.60455695500423}, { + 13.700676052894298`, 42.911175512878344`}, {14.077718426986106`, + 43.43062810440714}, {14.540649561283345`, 44.095373218007374`}, { + 15.044575080856061`, 44.8481740786198}, {15.595943335072297`, + 45.699815949708594`}, {15.819237737291155`, 46.05215417080202}}]}, + {Arrowheads[{{0.009085522653342167, 1.}}], + ArrowBox[{{15.87509731101342, 46.14029548845605}, {15.89143359684925, + 46.166072659014176`}, {16.201202673300102`, 46.66108409473791}, { + 16.52738197112422, 47.18855646435075}, {16.872510701029707`, + 47.75292152902761}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{20.12694150910278, 12.742035321552946`}, { + 19.475309313361567`, 13.106672712330523`}, {18.853322956339937`, + 13.456537053991413`}, {18.258963022182925`, 13.791422784066848`}, { + 17.71175053082192, 14.113317006421621`}, {17.183077090978163`, + 14.419307586081462`}, {16.677991242289075`, 14.709908429218304`}, { + 16.501539787699183`, 14.810404875828599`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{16.41086391515586, 14.862048558818186`}, {15.73858231837493, + 15.244940905922983`}, {14.881589832640975`, 15.718313211478819`}, { + 14.095079858648713`, 16.12992412082897}, {13.612015838254463`, + 16.36793659886111}, {13.15300527780204, 16.579761422848595`}, { + 12.699677697280075`, 16.76466222979054}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{12.603054580667838`, 16.804072345121}, {12.356914470045423`, + 16.904466645027618`}, {11.624195502125907`, 17.14325779402543}, { + 10.94573743961601, 17.299685205508997`}, {10.312429348088251`, + 17.377299215145282`}, {10.232191143929295`, 17.38231889691224}, { + 10.152608909785817`, 17.386050449557032`}, {9.811359184231767, + 17.37259402369173}, {9.48064527163832, 17.335479576279525`}, { + 8.875456256930349, 17.227003907543974`}, {8.538691590541408, + 17.11767233297943}}]}, + {Arrowheads[{{0.016923601674316276`, 1.}}], + ArrowBox[{{8.43943986827253, 17.0854499885445}, {8.302674686555187, + 17.04104879639124}, {7.75853969360489, 16.784246505361683`}, { + 7.239290411171504, 16.463229296995667`}, {6.743270438669417, + 16.083773147998258`}, {6.267498255044522, 15.656274816438579`}, { + 5.645413566862449, 14.98949921316205}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{36.479716132863196`, 0.4016323505227532}, { + 35.87546906212038, 0.41067147157894923`}, {35.2814318928921, + 0.41969872264618785`}, {34.697407923088, 0.4287077903131379}, { + 34.123200450617716`, 0.43769236116846894`}, {33.55861277339086, + 0.44664612180085017`}, {33.00344818931709, 0.4555627587989509}, { + 32.3061777067387, 0.4669580480252763}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{32.20184038694285, 0.4686632025755976}, { + 31.920601492267284`, 0.47325940824698837`}, {31.27065455267774, + 0.48404207226579526`}, {30.633104443674384`, 0.4947028220270601}, { + 30.007701606745016`, 0.505234380398115}, {29.394196483377435`, + 0.5156294702462919}, {28.792339515059435`, 0.525880814438923}, { + 28.20188114327882, 0.5359811358433402}, {28.02838236709559, + 0.5389586962927787}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{27.924046478658035`, 0.5407492934468509}, { + 27.622571809523382`, 0.5459231573268756}, {27.075457614988743`, + 0.5563205837445278}, {26.525725147222868`, 0.5661582550891151}, { + 25.986642600457774`, 0.5758230722474847}, {24.94042726992993, + 0.5946341440055707}, {23.93681162340521, 0.6127537990187855}, { + 23.750677476741124`, 0.6161293831760191}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{23.646343380069148`, 0.6180215052293723}, { + 22.975795660883612`, 0.6301820372871292}, {22.054029160036304`, + 0.6468462373138664}, {21.168161898534446`, 0.6626737776022614}, { + 20.318193876378043`, 0.6776646581523145}, {19.504125093567083`, + 0.6918188789640256}, {19.472955323276842`, 0.6923513546365635}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{19.36861929415349, 0.6941337353458237}, {18.86388165900055, + 0.702756208634227}, {18.244873342382046`, 0.7130993261897992}, { + 17.26723730956536, 0.7288480725635298}, {16.342410706324333`, + 0.7429515518870157}, {15.467571425333125`, 0.7554165158637226}, { + 15.195075762775167`, 0.7589831373437188}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{15.090733447794502`, 0.7603488454742231}, { + 14.639897359265905`, 0.7662497161971161}, {14.043604128476263`, + 0.773380797882648}, {13.47070993833581, 0.7796253755194875}, { + 12.395118680002474`, 0.7894550186470898}, {11.405799273712331`, + 0.795919387444197}, {10.916867850228805`, 0.7976808819587541}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{10.812517275160651`, 0.7980568303162228}, { + 10.495427408911816`, 0.7991992237750833}, {10.324281086477587`, + 0.7995308600687618}, {10.155927515927576`, 0.7997480120600583}, { + 9.814971458543933, 0.7994846727439558}, {9.48545402611965, + 0.7987519072343788}, {8.700078792955896, 0.7956200578521103}, { + 7.979577289538006, 0.7898617345668076}, {7.318761293014036, + 0.7817477286146144}, {6.712442580532048, 0.7715488312316741}, { + 6.638656763119474, 0.7697755977114633}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.534335631573717, 0.767268534243034}, {5.6458847866064135`, + 0.7459171299406784}, {4.903257829353509, 0.7205622578828108}, { + 4.258261404296697, 0.6925638640323629}, {3.2064010428146545`, + 0.6320612542363377}, {2.4122560278133154`, 0.569253782633929}, { + 2.3660459649395396`, 0.5644851764411436}}]}, + {Arrowheads[{{0.004872495342548926, 1.}}], + ArrowBox[{{2.262245933548732, 0.5537736248500198}, {1.814219003441145, + 0.5075398856906186}, {1.2527186891481723`, + 0.43247365957612666`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{33.284228421357426`, 4.35668445327842}, {32.3548236467046, + 4.525354326233555}, {31.4574447764906, 4.6933871755879535`}, { + 30.590857468477452`, 4.860514984317108}, {29.75382738042721, + 5.026469735396508}, {29.18487102691367, 5.142211378645766}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.08261417107948, 5.163013284547095}, {28.945120170101927`, + 5.190983411801643}, {28.163501495263645`, 5.353787996508002}, { + 27.40773701367442, 5.5146154724910765`}, {26.676592383096292`, + 5.673197822726358}, {25.697837651698613`, 5.888866038794643}, { + 25.00264063250247, 6.043924839235834}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{24.90079202305755, 6.066641454484549}, {24.758626133029896`, + 6.098350555304389}, {23.856862719588257`, 6.301259730772988}, { + 23.01280011722511, 6.50137943286567}, {22.196757636330634`, + 6.6931614072454595`}, {21.413973045659496`, 6.87758475761888}, { + 20.83576072353346, 7.014178966388414}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{20.73420477549139, 7.0381700745641105`}, { + 20.664446345211708`, 7.0546494839859335`}, {19.948177534987263`, + 7.224355586346618}, {19.26186318643962, 7.3862607462924075`}, { + 18.602199871022247`, 7.539922645414778}, {17.96918758873514, + 7.685341283713729}, {17.362826339578294`, 7.822516661189262}, { + 16.784816535282708`, 7.950575932596747}, {16.666932585984405`, + 7.975958396190243}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{16.564919291393842`, 7.997923631927681}, { + 16.229123684760538`, 8.070226263549376}, {15.220516434634007`, + 8.275902753460873}, {14.282481299946859`, 8.450596509954092}, { + 13.408809849892174`, 8.594833807739283}, {12.593293653663034`, + 8.709140921526695}, {12.456062416612525`, 8.724105969130257}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{12.352326150623574`, 8.73541839472742}, { + 11.678164666393682`, 8.808935612241642}, {10.832448207959695`, + 8.868355476245918}, {10.69738135222392, 8.874889307498668}, { + 10.56403984719346, 8.880367009258485}, {10.210638758667116`, + 8.884980790230737}, {9.86901587011006, 8.882132568164712}, { + 9.113633723761886, 8.857554833792474}, {8.41472106320831, + 8.796888172702165}, {8.190022081807298, 8.764485188453454}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{8.086739209386847, 8.749591158817296}, {7.767474971064815, + 8.703551279058951}, {7.1670925299468875`, 8.580962847027996}, { + 6.610544131265691, 8.43194683385523}, {6.09237647956132, + 8.261586362583335}, {5.374377788568465, 7.960988960643618}, { + 4.732639870181266, 7.626415050507472}, {4.210241833388427, + 7.3018665988777}}]}, + {Arrowheads[{{0.013203088989000106`, 1.}}], + ArrowBox[{{4.123313960110224, 7.24425625523851}, {3.644409163090605, + 6.896268822264425}, {3.1873653005643283`, 6.5154543022109275`}, { + 2.781693542612774, 6.132629472051729}, {2.10514849933814, + 5.381565778183589}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{25.270552352601207`, 8.178002954716998}, { + 24.607671521889493`, 8.405565201082126}, {23.968933060077035`, + 8.629162352359591}, {23.35316031645023, 8.848550580614702}, { + 22.759176640295458`, 9.063486057912769}, {22.185805380899122`, + 9.273724956319104}, {21.410379599566216`, 9.56053530264626}, { + 21.341360238016392`, 9.586156042520043}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{21.243531788515007`, 9.622471030092353}, { + 20.667770330847855`, 9.836199963611852}, {19.95598244545731, + 10.10041690650925}, {19.294302193166306`, 10.356105780835886`}, { + 18.654465242412833`, 10.598987789914487`}, {18.04145941641372, + 10.82981801551163}, {17.455284715168958`, 11.048596457627319`}, { + 17.336903254417834`, 11.092348821744688`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{17.23902307807133, 11.128524157715475`}, { + 16.895941138678555`, 11.255323116261549`}, {16.36040748895613, + 11.449794059404466`}, {15.84566256801531, 11.631805355046215`}, { + 14.878538912478481`, 11.9584490038262}, {14.376393423169754`, + 12.118077650687214`}, {13.895231083128445`, 12.262553717369887`}, { + 13.275968534820485`, 12.433677535927297`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{13.174704355775432`, 12.45885358200318}, {12.6682401053037, + 12.583025127698345`}, {12.102885623176297`, 12.701953579426151`}, { + 11.565976007269615`, 12.794191187469032`}, {10.770459427667948`, + 12.888129482114566`}, {10.03216977693193, 12.921162980062356`}, { + 9.928666816444826, 12.921539421395678`}, {9.826233962623142, + 12.920703998279134`}, {9.495000372803677, 12.900796186137324`}, { + 9.174345566929613, 12.868311339607068`}, {9.045750216221387, + 12.849638839928458`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{8.94248194290329, 12.834643921451832`}, {8.49385914976217, + 12.769502305408873`}, {7.859442430027147, 12.615619645837397`}, { + 7.267015142392209, 12.412372820306981`}, {6.712497021525018, + 12.16547128823197}, {6.193609150208173, 11.879610168173011`}, { + 5.70624947745035, 11.563240673539275`}, {5.186719874123697, + 11.154369701133044`}}]}, + {Arrowheads[{{0.00030816743784531044`, 1.}}], + ArrowBox[{{5.104717905716634, 11.089833966601011`}, {5.05417723271208, + 11.05005834268061}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{36.190296044951495`, 2.278988599990219}, { + 35.192676218892515`, 2.369765546014048}, {34.225910718792655`, + 2.460493451038834}, {33.28885886367611, 2.5509943594550206`}, { + 32.38037997256709, 2.6410903156530523`}, {32.03520907481531, + 2.6761591746478217`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{31.93139225916488, 2.686706811464959}, {31.499333364489786`, + 2.7306033640233744`}, {30.644578358468404`, 2.8193555489564295`}, { + 30.04954921020404, 2.8820694891286935`}, {29.466241613991087`, + 2.9441179678805156`}, {28.894387809846, 3.005462874619257}, { + 28.33372003778525, 3.06606609875228}, {27.78397053782529, + 3.125889529686947}, {27.780560906655122`, 3.126262721047158}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{27.676829145691617`, 3.137616382202573}, { + 27.244871549982594`, 3.1848950568306202`}, {26.22040292264331, + 3.303552061279532}, {25.229968024299886`, 3.4177179116000556`}, { + 24.27892205462306, 3.528154819644949}, {23.530267123775417`, + 3.615783654985654}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{23.42662343213255, 3.62791497959844}, {23.36726501361283, + 3.6348627854142115`}, {22.494996901269204`, 3.737841808907844}, { + 21.658628200878713`, 3.8367001846125817`}, {20.8546693957279, + 3.9310462070151617`}, {20.08312048581676, 4.0208798761155835`}, { + 19.343981471145298`, 4.106201191913848}, {19.280904109575246`, + 4.113389484966046}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{19.1772239261019, 4.125204873624692}, {18.706497975308356`, + 4.178848780049356}, {18.09167797889866, 4.24761146035275}, { + 17.37483257638206, 4.325604438013289}, {16.68688165632021, + 4.397739431963119}, {16.02782521871311, 4.464016442202238}, { + 15.397663263560764`, 4.524435468730647}, {15.025788482097589`, + 4.558078648041699}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{14.921861665902803`, 4.567480814272791}, { + 14.793781139325171`, 4.579068145107517}, {14.213564194468344`, + 4.6279861048920194`}, {13.65701242899028, 4.6711893480841535`}, { + 13.124125842890981`, 4.708677874683921}, {12.119247816814715`, + 4.767486545988051}, {11.19284931346906, 4.805120729975748}, { + 11.030895920565133`, 4.810058227118876}, {10.8713171668112, + 4.81432972535928}, {10.75601153632908, 4.81593300512951}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{10.651670370117776`, 4.817383828305181}, { + 10.508495403501266`, 4.819374620312647}, {10.157803780771825`, + 4.820943996958636}, {9.346482864974295, 4.815469019032042}, { + 8.599515921588882, 4.7914946268532095`}, {7.911641771615255, + 4.750755480994464}, {7.277599236053081, 4.69498624202813}, { + 6.693851357343197, 4.625608623343333}, {6.488073628743292, + 4.594950115790393}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.384861616594407, 4.579572716712511}, {6.154031611879116, + 4.545181709040498}, {5.386603777370995, 4.39540333541825}, { + 4.711359050168454, 4.226500485928004}, {4.11496450113375, + 4.044650166579768}, {3.5903213200267814`, 3.853707066400027}, { + 2.724368460869932, 3.45983837826572}, {2.4401935092996707`, + 3.2928924492504383`}}]}, + {Arrowheads[{{0.001616949458014049, 1.}}], + ArrowBox[{{2.3502197485019285`, 3.240035035180768}, { + 2.0592537009871386`, 3.069099501116813}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{50., 16.927683874390233`}, {49.9085258402617, + 17.06782331794245}, {49.60134528278074, 17.570553536300356`}, { + 49.30827235130409, 18.08416196275136}, {49.029352030259666`, + 18.60894478811419}, {48.61712579644272, 19.461973258711016`}, { + 48.24046421926981, 20.3446945235371}, {48.12710397795115, + 20.64903818988108}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{48.090680417116744`, 20.74682626722369}, {47.89995745562148, + 21.25886933172532}, {47.59619566237826, 22.206258432408568`}, { + 47.329235224753326`, 23.187797036860847`}, {47.09955954529376, + 24.20508078664326}, {46.99908807827641, 24.727986901834374`}, { + 46.992345173418954`, 24.767607240761173`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{46.97483758080441, 24.87047933637055}, {46.90839930688091, + 25.260861076319355`}, {46.827647066467435`, 25.804047234418643`}, { + 46.75698519239615, 26.357889300452676`}, {46.69607454392253, + 26.92188897036574}, {46.64475524434011, 27.495854204966165`}, { + 46.603450025066174`, 28.080588325870487`}, {46.572581617518004`, + 28.67689465469524}, {46.56128821779805, 29.020446761880407`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{46.55785978827449, 29.12474167894363}, {46.55257275311288, + 29.285576513056956`}, {46.54384616326808, 29.90743722257217}, { + 46.54682457940089, 30.543280104857413`}, {46.56193073292859, + 31.193908481529217`}, {46.60074066194667, 32.06841127159385}, { + 46.66204374433008, 32.97165599175458}, {46.69130331353067, + 33.294198238671214`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{46.70073087406533, 33.398122754338054`}, { + 46.746739071145974`, 33.90529314913227}, {46.84613542874499, + 34.853367841558395`}, {46.97296994057879, 35.83926225324546}, { + 47.12499487897946, 36.85885011639126}, {47.21045375814236, + 37.38127909226118}, {47.23724112915973, 37.53625602308441}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{47.25501443364049, 37.63908254447873}, {47.302210243946966`, + 37.912131430995785`}, {47.4002643363933, 38.45140713259508}, { + 47.50461603548134, 38.99910619705906}, {47.61591469445789, + 39.55637347306148}, {47.73480966656976, 40.124353809276094`}, { + 47.861300951816936`, 40.703047205702916`}, {47.99538855019942, + 41.29245366234194}, {48.097844841853195`, 41.7264198027947}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{48.12182223701982, 41.82797898935725}, {48.13707246171722, + 41.892573179193164`}, {48.28635268637032, 42.5034057562566}, { + 48.44322922415874, 43.12495139353223}, {48.607702075082464`, + 43.757210091020056`}, {48.88518382325472, 44.808648426427176`}, { + 49.03538095657439, 45.35087077467897}, {49.17805395600637, + 45.865930463731004`}}]}, + {Arrowheads[{{0.012644001720598238`, 1.}}], + ArrowBox[{{49.20792368938321, 45.9659072381097}, {49.42363453613884, + 46.66881048528552}, {49.661690982383625`, 47.44452784764029}, { + 49.9309249016575, 48.26676300126804}, {50., + 48.482957315927486`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{12.565916046932262`, 20.60570641946029}, {12.2123917131082, + 20.833871506624245`}, {11.876577004601629`, 21.031142440303277`}, { + 10.939149459576333`, 21.45006494135886}, {10.103358364970097`, + 21.607336644331554`}, {10.05034315202163, 21.60943094596297}, { + 9.997619283949339, 21.610451041028742`}, {9.659635899296376, + 21.565111216597902`}, {9.329751950939706, 21.47587622049211}, { + 8.698856689190954, 21.177150711403073`}}]}, + {Arrowheads[{{0.004124750181173024, 1.}}], + ArrowBox[{{8.604543597199726, 21.13249397021794}, {8.361564965429825, + 21.017444896506355`}, {7.895113454608308, + 20.652898851426308`}}]}}}}, {{}, + {RGBColor[1, 0, 0], PointSize[0.03], + PointBox[{{0., 0.}, {10., 30.}}]}, {}}}, + AspectRatio->1, + Frame->True, + Method->{"TransparentPolygonMesh" -> True}, + PlotRange->{{-1.0878130721773847`, + 51.08781307217738}, {-1.0878130721773847`, 51.08781307217738}}, + PlotRangeClipping->True, + PlotRangePadding->{ + Scaled[0.02], + Scaled[0.02]}]], "Output", + CellChangeTimes->{3.5146926258032923`*^9, + 3.6204255533267612`*^9},ExpressionUUID->"2dcc3d79-78d7-42f0-8ad8-\ +44b4f87e4e24"] +}, Open ]], + +Cell["\<\ +One might ask how we could separate the domains that are attracted to {0,0} \ +or that grow to infinity. + +Some insight is found by dividing the plot regions according to null-clines. \ +These are lines along which one of the variables remains constant but the \ +other varies.\ +\>", "Text", + CellChangeTimes->{{3.514691069291172*^9, 3.5146911107789927`*^9}, { + 3.514692129539792*^9, 3.514692171497327*^9}, {3.51469286426581*^9, + 3.514692879090166*^9}, {3.5146929252532*^9, 3.514692928932069*^9}, { + 3.620425566137952*^9, + 3.620425568320405*^9}},ExpressionUUID->"ff08303c-386d-42c0-968b-\ +ff661c35b535"], + +Cell["\<\ +Specifically, nc will stay constant (but nd can move, i.e., the system can go \ +up or down) along the following line (green in plot below):\ +\>", "Text", + CellChangeTimes->{{3.514692181045281*^9, 3.514692216801198*^9}, { + 3.514692768132263*^9, 3.5146927753940897`*^9}, {3.620424815162347*^9, + 3.6204248226476192`*^9}},ExpressionUUID->"2d9e6217-f6a7-4e5b-b1b0-\ +330fdff23667"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"nc", "==", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "rc", "+", + RowBox[{"\[Rho]c", " ", "nd"}]}], ")"}], " ", "nc"}]}], ",", "nd"}], + "]"}]], "Input", + CellChangeTimes->{{3.514691137383657*^9, 3.514691144230986*^9}, { + 3.5146912023658953`*^9, 3.5146912038853292`*^9}, {3.6204248152423697`*^9, + 3.620424835253949*^9}, + 3.6204249745951567`*^9},ExpressionUUID->"866342d9-d350-46be-836a-\ +7a2b903f2278"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{"nd", "\[Rule]", + FractionBox["rc", "\[Rho]c"]}], "}"}], "}"}]], "Output", + CellChangeTimes->{{3.514691141721011*^9, 3.51469114500351*^9}, + 3.6204255795537157`*^9},ExpressionUUID->"8eeed916-b849-4714-a6d5-\ +ff0f45749ca9"] +}, Open ]], + +Cell["\<\ +Similarly, nd will stay constant (but nc can move, i.e., the system can go \ +left or right) along the following line (purple in plot below):\ +\>", "Text", + CellChangeTimes->{{3.514692181045281*^9, 3.514692216801198*^9}, { + 3.514692768132263*^9, 3.5146927962424393`*^9}, {3.620424815384218*^9, + 3.620424822918001*^9}},ExpressionUUID->"5cf1d732-dc01-4e0f-a3c2-\ +b9b741a76852"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"nd", "==", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "rd", "+", + RowBox[{"\[Rho]d", " ", "nc"}]}], ")"}], " ", "nd"}]}], ",", "nc"}], + "]"}]], "Input", + CellChangeTimes->{{3.5146911975875387`*^9, 3.5146912000336123`*^9}, { + 3.620424815477747*^9, 3.620424839619342*^9}, + 3.620424987891325*^9},ExpressionUUID->"79511892-01b5-42a5-8787-\ +e47f4d4b73b0"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{"{", + RowBox[{"nc", "\[Rule]", + FractionBox["rd", "\[Rho]d"]}], "}"}], "}"}]], "Output", + CellChangeTimes->{3.514691200545607*^9, + 3.620425581132176*^9},ExpressionUUID->"22d9c645-06c1-4ab5-9aee-\ +60e2558426f9"] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"plot4", "=", + RowBox[{"Show", "[", + RowBox[{"plot3", ",", "\[IndentingNewLine]", + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + FractionBox["rc", "\[Rho]c"], "/.", + RowBox[{"rc", "\[Rule]", "0.6"}]}], "/.", + RowBox[{"rd", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"\[Rho]c", "\[Rule]", "0.02"}]}], "/.", + RowBox[{"\[Rho]d", "\[Rule]", "0.03"}]}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"nc", "[", "t", "]"}], ",", "0", ",", "400"}], "}"}], ",", + RowBox[{"PlotStyle", "\[Rule]", "Green"}]}], "]"}], ",", + "\[IndentingNewLine]", + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + FractionBox["rd", "\[Rho]d"], ",", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + FractionBox["rd", "\[Rho]d"], ",", "400"}], "}"}]}], "}"}], "/.", + RowBox[{"rc", "\[Rule]", "0.6"}]}], "/.", + RowBox[{"rd", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"\[Rho]c", "\[Rule]", "0.02"}]}], "/.", + RowBox[{"\[Rho]d", "\[Rule]", "0.03"}]}], "/.", + RowBox[{"\[Rho]d", "\[Rule]", "0.001"}]}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", "Purple"}]}], "]"}]}], + "\[IndentingNewLine]", "]"}]}]], "Input", + CellChangeTimes->{{3.5146909556777983`*^9, 3.514691054042715*^9}, { + 3.51469178340476*^9, 3.514691854322139*^9}, {3.514692593586814*^9, + 3.5146926071386013`*^9}, {3.514692647146307*^9, 3.5146927211865273`*^9}, { + 3.514694044460018*^9, 3.514694058329012*^9}, {3.5146941178858337`*^9, + 3.5146941521539917`*^9}, {3.5146942431498337`*^9, 3.514694248410611*^9}, { + 3.620424815677053*^9, 3.62042483978756*^9}, {3.620424974597657*^9, + 3.62042498805832*^9}, {3.6204255915019493`*^9, + 3.620425593591058*^9}},ExpressionUUID->"435973e6-70b8-49d5-9cdc-\ +2b803506381f"], + +Cell[BoxData[ + GraphicsBox[{{{{}, { + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{50., 5.255627689465548}, {49.07164643991514, + 5.49929454502681}, {48.101654752431905`, 5.768012892194103}, { + 47.16122726915955, 6.042593697561616}, {46.24934810020415, + 6.322803191864825}, {45.98853990724681, 6.407032564076382}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{45.889238795161646`, 6.43910237843306}, {45.36500135567175, + 6.608407605839203}, {44.58598393311282, 6.871537687447511}, { + 43.826982442039586`, 7.138509574582958}, {43.08753418321806, + 7.4092143791227985`}, {42.36717645741425, 7.683543212944289}, { + 41.95989638425604, 7.844802289610991}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{41.86287349110899, 7.88321767792867}, {41.66544656539418, + 7.9613871879246805`}, {40.981881807923834`, 8.242637415941228}, { + 40.316019485769246`, 8.527185008871188}, {39.70688056766348, + 8.824212865066134}, {39.089918510465075`, 9.118531091403003}, { + 38.489733490114446`, 9.415928906407792}, {38.0742600869078, + 9.62991358440455}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{37.9814901997972, 9.677693621027696}, {37.90632550661159, + 9.716406310080501}, {37.3396945599565, 10.019963302421127`}, { + 36.78984065014919, 10.32659988342967}, {36.25676377718965, + 10.636316053106134`}, {35.740463941077884`, 10.949111811450518`}, { + 35.2409411418139, 11.264987158462816`}, {34.75670439677487, + 11.583629558431436`}, {34.40465234828942, 11.823920403928765`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{34.31846359879082, 11.882747976665446`}, {34.286262723338, + 11.904726475644786`}, {33.829616121503285`, 12.228277910102857`}, { + 33.38676459127073, 12.554283861805654`}, {32.54244674561208, + 13.213659316945424`}, {31.75330918636206, 13.882852841064095`}, { + 31.21003027705684, 14.377806997593897`}, {31.077247248736626`, + 14.506056736923023`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{31.00218964042387, 14.578551835299333`}, { + 30.692638150616993`, 14.877535059126219`}, {29.975257805378966`, + 15.62215230541692}, {29.309812325343447`, 16.37682786720651}, { + 28.69413730331939, 17.141603879322957`}, {28.26741617616755, + 17.723705972626668`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{28.205721092727792`, 17.807865942526753`}, { + 28.12606833211576, 17.916522476594224`}, {27.618068132766822`, + 18.67887970316737}, {27.150334054790395`, 19.452211247189897`}, { + 26.722866098186476`, 20.236517108661797`}, {26.33566426295506, + 21.031797287583075`}, {26.160672214451445`, 21.43732678808643}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{26.119328106854564`, 21.533138314643725`}, { + 25.986887720780615`, 21.840057880820073`}, {25.674695643347604`, + 22.66330498523914}, {25.399088030656024`, 23.501538600840274`}, { + 25.160064882705875`, 24.354758727623476`}, {25.077623137676905`, + 24.67623029415256}, {25.000130980593386`, 25.000173926194417`}, { + 24.90713673871171, 25.517801018623775`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{24.888684934653096`, 25.620507955006886`}, { + 24.849004956355706`, 25.841375735399907`}, {24.729767986718073`, + 26.70365873558932}, {24.630530483798537`, 27.542736266356243`}, { + 24.56160354012163, 28.405466030731965`}, {24.52298715568735, + 29.291848028716487`}, {24.518592434839327`, 29.77335905473906}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{24.517640067189014`, 29.877705961018453`}, { + 24.514681330495694`, 30.2018822603098}, {24.538789509441692`, + 31.141564545156765`}, {24.597415137420363`, 32.11689070290223}, { + 24.690558214431714`, 33.12786073354619}, {24.80165046951396, + 34.0386410847478}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{24.814285052363417`, 34.14222463156119}, { + 24.818218740475743`, 34.17447463708866}, {24.97467432311375, + 35.24437486775083}, {25.07876922741073, 35.820598892969294`}, { + 25.19235185283169, 36.40758751827921}, {25.315708318998553`, + 37.0059586209695}, {25.44912474553326, 37.61633007832912}, { + 25.59288725205775, 38.239319767647004`}, {25.59330124435526, + 38.241025736631784`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{25.617910209544327`, 38.34243373772906}, { + 25.747281958193952`, 38.87554556621209}, {25.940101598568962`, + 39.628438210109316`}, {26.150846742815112`, 40.406028023594665`}, { + 26.380551777227023`, 41.210330103819174`}, {26.630251088099318`, + 42.04335954793386}, {26.730898099824202`, 42.36447915704206}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{26.76210739782475, 42.46405407141579}, { + 26.900979061726613`, 42.90713145308976}, {27.193770084403532`, + 43.803660916437906`}, {27.50965854242469, 44.73496303512932}, { + 27.849678822084716`, 45.70305290631504}, {28.108387715178683`, + 46.414587587559254`}}]}, + {Arrowheads[{{0.017918567746579475`, 1.}}], + ArrowBox[{{28.144045259149596`, 46.51265757997378}, { + 28.216935285765725`, 46.71312916498169}, {28.412055705910014`, + 47.23601123263495}, {28.61516921156907, 47.77136999621915}, { + 28.826524522727077`, 48.319641008522545`}, {29.046370359368215`, + 48.881259822333355`}, {29.27495544147667, 49.45666199043983}, { + 29.493879886714133`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{50., 3.046754492416481}, {49.30691551877229, + 3.1421248170699143`}, {48.549210363966736`, 3.249990429378931}, { + 47.80628351324313, 3.359339012067691}, {47.07786923727012, + 3.4701203299368584`}, {46.36370180671632, 3.582284147787095}, { + 45.87167489311794, 3.662029101277047}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{45.76866777190582, 3.678723915855624}, {45.6633042957297, + 3.695800635187409}, {44.9762365082879, 3.8106364130514456`}, { + 44.30228780980407, 3.9267359231968193`}, {43.641247565691394`, + 4.044043607441145}, {42.99290514136307, 4.162503907602034}, { + 42.35704990223227, 4.282061265497096}, {41.73347121371217, + 4.4026601229439475`}, {41.66063423036925, 4.417142028088762}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{41.55828637224961, 4.437491470158391}, {41.12195844121596, + 4.524244921760202}, {40.522300950156804`, 4.646760103763471}, { + 39.934288105947914`, 4.770150110771365}, {39.35770927400245, + 4.8943593846015}, {38.792353819733584`, 5.019332367071488}, { + 38.23801110855452, 5.145013499998943}, {37.694470505878414`, + 5.271347225201477}, {37.479558112687755`, 5.323145855371648}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{37.37811185657169, 5.3475966421536025`}, { + 36.638953087687874`, 5.525750219702228}, {35.62389307929084, + 5.782090005760034}, {34.64746323451677, 6.039917740144682}, { + 33.708100336221975`, 6.2987927097723135`}, {33.34043127306272, + 6.404343795902534}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{33.240131355765655`, 6.433138073883139}, { + 32.804241167262745`, 6.558274201559078}, {31.93432251049537, + 6.817921502421122}, {31.096781148776145`, 7.077293899274592}, { + 30.290053864961354`, 7.335950679035637}, {29.512577441907304`, + 7.593451128620401}, {29.25733037242637, 7.680680108899937}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.158586035090803`, 7.714425326314875}, { + 28.511300778753974`, 7.9356307371157095`}, {27.5533564203355, + 8.273029929405732}, {26.636332618351013`, 8.605011992601364}, { + 25.783542939708855`, 8.937731817963966}, {25.240519622252435`, + 9.151871130418568}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{25.143443822445573`, 9.190152626550253}, { + 24.960820950146804`, 9.262169306231199}, {24.174196020417014`, + 9.579916239625828}, {23.42366815051949, 9.890972618147854}, { + 22.709237340454223`, 10.195338441797277`}, {22.02708273344312, + 10.492132512118648`}, {21.373383472708078`, 10.780473630656516`}, { + 21.298560537511758`, 10.813967845760393`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{21.203316680414655`, 10.85660341236257}, { + 20.748139558249093`, 11.060361797410883`}, {20.151350990066174`, + 11.331797012381745`}, {19.474857884757967`, 11.643480355238204`}, { + 18.831665723816883`, 11.941936884140334`}, {17.889821661434798`, + 12.37886126421555}, {17.410684364456777`, 12.599672002780904`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{17.315912879115317`, 12.643347504156335`}, { + 17.015519686801376`, 12.781783904480829`}, {16.20218071411488, + 13.150189024441007`}, {15.44322565757358, 13.483560843600925`}, { + 14.54590587797527, 13.85748882834175}, {13.717912173088807`, + 14.174718438279013`}, {13.58614702264218, 14.222698900770094`}, { + 13.470835248789541`, 14.263855968418307`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{13.371651504542532`, 14.296265258562856`}, { + 13.017694469461, 14.410053144819937`}, {12.596846456225402`, + 14.532352313975206`}, {11.859950820294307`, 14.723971973931429`}, { + 11.173288862944805`, 14.855946636067003`}, {10.531131397563858`, + 14.930933414451436`}, {9.92774923753843, 14.951589423154232`}, { + 9.35975694271045, 14.920495792063443`}, {9.276367203284325, + 14.908390923012659`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{9.173098293260882, 14.893400390107127`}, { + 8.821060720795387, 14.842298554977567`}, {8.066659539361678, + 14.637970703786886`}, {7.366263444900198, 14.344221402127282`}, { + 6.711521814512744, 13.973892822186267`}, {6.100322506916809, + 13.537647643011448`}, {5.529251860062621, 13.0468851667233}, { + 5.514332818344818, 13.031918620930668`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{5.4406627207951255`, 12.958013948674845`}, { + 4.996713931940981, 12.512651571945206`}, {4.500855089220485, + 11.945702274813412`}, {4.0404728672678, 11.35632536722847}, { + 3.670711747917073, 10.836353765561283`}, {3.325970938073047, + 10.311000265948131`}, {3.0055039585738204`, 9.785939084975231}, { + 2.9247666496529856`, 9.64479825776259}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{2.872952616238303, 9.55421961902517}, {2.708564330257488, + 9.266844439228795}, {2.4343708708490444`, 8.756721478898363}, { + 2.18212256772314, 8.257050173375378}, {1.9510431961923551`, + 7.771216968048902}, {1.7403565315692708`, 7.302608308308005}, { + 1.3754465083471559`, 6.4199885973137185`}, {1.1337458433457925`, + 5.765980003531753}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{1.0975722251644244`, 5.668099192328073}, { + 1.0779628686587033`, 5.615038983854077}, {0.8387603087711567, + 4.891910419754798}, {0.648172892642414, 4.247745960293024}, { + 0.49777222254129183`, 3.6795828400670922`}, {0.38010712289285203`, + 3.1808485247222476`}, {0.21821852342122994`, 2.3670752012957825`}, { + 0.12319313918665568`, 1.7547993248906482`}, {0.10716134137378217`, + 1.6211922973337174`}}]}, + {Arrowheads[{{0.006901193386245247, 1.}}], + ArrowBox[{{0.09472918763697008, 1.5175842599636071`}, { + 0.07030775321242456, 1.3140590346442143`}, {0.03980150451054112, + 0.982829355931863}, {0.022364466090688092`, 0.7345808087588179}, { + 0.012475050897473553`, 0.5488158092569115}, {0.0070971341252142545`, + 0.41482425570352494`}, {0.004042384116633057, + 0.31351763341181166`}, {0.002296973446982666, + 0.23693643132798137`}, {0.0012989393312688657`, + 0.1790536109198805}, {0.000576397485540716, 0.12064568500470597`}, { + 0.000215303600311363, 0.08121294442028855}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{50., 9.467092475873057}, {49.807348435733154`, + 9.57162462921928}, {49.0682298090966, 9.998001889687844}, { + 48.35637340268402, 10.434920491978248`}, {47.67177921649541, + 10.882380436090495`}, {47.111981052667645`, 11.271838386982596`}, { + 46.57021741408454, 11.669178906329964`}, {46.49514432783939, + 11.726867108256133`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{46.41240090003064, 11.790449409320821`}, { + 46.09485542211006, 12.034459993769223`}, {45.63372685980081, + 12.406100191279108`}, {45.18671336128773, 12.784203076096052`}, { + 44.753696560701755`, 13.168872225456479`}, {44.33455809217379, + 13.560211216596821`}, {43.92917958983478, 13.958323626753511`}, { + 43.53744268781565, 14.363313033162978`}, {43.32671368808493, + 14.592850009817711`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{43.25614274523294, 14.669719547862398`}, { + 43.159229020247324`, 14.77528301306165}, {42.79423229500632, + 15.193942246371215`}, {42.44221455678894, 15.619143012036906`}, { + 42.103159944955785`, 16.051204285830465`}, {41.77705259886748, + 16.49044504352364}, {41.463876657884605`, 16.937184260888166`}, { + 41.163616261367785`, 17.391740913695795`}, {40.87625554867761, + 17.854433977718266`}, {40.779597110659154`, + 18.020351310255176`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{40.72706890854821, 18.110517666714856`}, { + 40.601778659174705`, 18.325582428727333`}, {40.221572001861695`, + 19.033996670486225`}, {39.868795929002914`, 19.762457386972137`}, { + 39.543577668418564`, 20.511926077563757`}, {39.24468735117998, + 21.273108248267175`}, {39.02431433389426, 21.913258616073758`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{38.99034756293841, 22.011926961175188`}, { + 38.97392737140676, 22.059625140280357`}, {38.73097965954838, + 22.8690730051566}, {38.51584421560486, 23.701451842895906`}, { + 38.328521039576174`, 24.556761653498278`}, {38.169912156873075`, + 25.437861075016585`}, {38.07895536317184, 26.07935333348483}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{38.06430598757423, 26.182671190841734`}, { + 38.04091959290628, 26.3476087455037}, {37.94154334767579, + 27.28600466495962}, {37.87178342118161, 28.25304883338435}, { + 37.83923092998787, 28.834394700560594`}, {37.817533088819154`, + 29.42701002563941}, {37.82903198982552, 30.345931668700178`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{37.831161711623764`, 30.450252390569048`}, { + 37.8730242934231, 31.452433909680416`}, {37.92994341213175, + 32.463528122199165`}, {38.01781164150515, 33.51246227009787}, { + 38.07335167269113, 34.0511193198147}, {38.136628981543296`, + 34.599236353376526`}, {38.13819831135887, 34.61155807882468}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{38.15138228174712, 34.715073134633116`}, { + 38.20764356806165, 35.15681337078334}, {38.286395432246195`, + 35.723850372035145`}, {38.373748505041405`, 36.30197529694237}, { + 38.47056671739176, 36.892816085315474`}, {38.576850069297265`, + 37.496372737154445`}, {38.69259856075791, 38.11264525245929}, { + 38.8178121917737, 38.741633631229995`}, {38.836633570134346`, + 38.831311895202624`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{38.85806749072204, 38.93343814502343}, {38.95249096234463, + 39.38333787346657}, {39.096634872470716`, 40.03775797916902}, { + 39.250243922151945`, 40.704893948337336`}, {39.39441174651897, + 41.351147680618716`}, {39.57874532800328, 42.0646746932398}, { + 39.7732552602604, 42.79218144770993}, {39.828514777014036`, + 42.9921850001184}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{39.85630504749751, 43.09276772587525}, {39.97829714889914, + 43.53429988322069}, {40.19422659952834, 44.29166193896368}, { + 40.42139921775683, 45.064899554130484`}, {40.66017060919343, + 45.85464466791269}, {40.91089637944697, 46.66152921950189}, { + 41.04903944587308, 47.0924503155271}}]}, + {Arrowheads[{{0.014192803458930205`, 1.}}], + ArrowBox[{{41.08089511278807, 47.19182033283425}, {41.23672796035694, + 47.67792262669803}, {41.408047187287615`, 48.1986055906829}, { + 41.585193469766295`, 48.72799998297205}, {41.76833538121613, + 49.26639624460025}, {41.95764149506027, 49.814084816602296`}, { + 42.02290995321195, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{4.319580651254556, 50.}, {4.327294726395148, + 49.961050346695416`}, {4.508291058260853, 49.090026080138}, { + 4.688673087110341, 48.26216167065276}, {4.868220134920151, + 47.475773065346814`}, {5.046400967307639, 46.728234957370844`}, { + 5.222797279475323, 46.01726431404149}, {5.245261065603621, + 45.930326289162316`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{5.271366838167764, 45.82929326241833}, {5.397357787777473, + 45.34169049371491}, {5.570031208568362, 44.70034285474721}, { + 5.74076625820226, 44.09205075549455}, {5.909511653033442, + 43.51564355431306}, {6.076216109416176, 42.96995060955888}, { + 6.240828343704737, 42.453801279588134`}, {6.452787708843304, + 41.82718241251142}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.48622434252224, 41.72833315665968}, {6.56264038219542, + 41.502423194270456`}, {6.8743513734954655`, 40.65153862457891}, { + 7.176667803504246, 39.89541568114387}, {7.470296158121136, + 39.22832247459571}, {7.754946766863427, 38.64214477799765}, { + 8.031126884354078, 38.130674234466646`}, {8.170608497690745, + 37.91923976141991}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{8.228070877858805, 37.83213488945718}, {8.565683139811934, + 37.320362269449696`}, {9.03648788685305, 36.814490656654584`}, { + 9.504124087901678, 36.509899769853384`}, {9.980663685682348, + 36.40305888896133}, {10.226230151583158`, 36.42459116611594}, { + 10.479717559965424`, 36.497822658764164`}, {10.849610640874653`, + 36.68974939129246}, {11.247205725572076`, 36.99443201211079}, { + 11.519955477592566`, 37.28075142271622}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{11.591930796959485`, 37.3563076088048}, { + 11.950943499452919`, 37.73318166502781}, {12.008786234130866`, + 37.80229313541391}, {12.06742837982083, 37.87358400008452}, { + 12.334747992595185`, 38.226164684386646`}, {12.621569486823308`, + 38.62619322141192}, {12.919844979548898`, 39.05283114060843}, { + 13.241028469269423`, 39.53268782414744}, {13.588734824614159`, + 40.071956126263174`}, {13.966578914212386`, 40.67682890118988}, { + 14.010013795312366`, 40.74825387626535}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{14.064233388003805`, 40.83741339411172}, { + 14.378813248186738`, 41.354713271624746`}, {14.833092344757956`, + 42.118942058422704`}, {15.246751280600575`, 42.82692717567917}, { + 15.698379505284956`, 43.61029155354303}, {16.171574819420517`, + 44.44022392736655}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{16.22310245881298, 44.53096566157733}, {16.45845409577451, + 44.94664303451333}, {16.736462380053844`, 45.43967246921526}, { + 17.02894101591767, 45.960222537391246`}, {17.337924369326622`, + 46.51182656960474}, {17.664553437361693`, 47.09646996590635}, { + 18.009969217103894`, 47.71613812634668}, {18.263697901959542`, + 48.172196966622565`}}]}, + {Arrowheads[{{0.009516783655673752, 1.}}], + ArrowBox[{{18.31443075234337, 48.26338557197518}, {18.37531270563422, + 48.372816450976316`}, {18.761724900033666`, 49.06849033984588}, { + 19.170346797383242`, 49.80514519300596}, {19.278311967134666`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{48.70808172879087, 4.093956838965128}, { + 48.015600704368715`, 4.2266725384361745`}, {47.33631377568077, + 4.361166718624578}, {46.67001711655772, 4.497388816191737}, { + 46.01650690083028, 4.635288267799045}, {45.375579302329086`, + 4.774814510107904}, {44.747030494884804`, 4.915916979779714}, { + 44.62195400884334, 4.9448595216944895`}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{44.520289107875335`, 4.968384652201853}, { + 44.13065665232814, 5.058545113475872}, {43.526253948489796`, + 5.202648347857767}, {42.933618557200425`, 5.348176119586805}, { + 42.35254665229069, 5.495077865324387}, {41.782834407591295`, + 5.643303021731904}, {41.224277996932926`, 5.792801025470751}, { + 40.67667359414625, 5.94352131320233}, {40.47622268155968, + 6.000234620228982}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{40.37581290252111, 6.028643423928659}, { + 40.139817373061945`, 6.095413321588043}, {39.459911962069974`, + 6.293701864208629}, {38.796572043056074`, 6.4936692636423645`}, { + 38.14948481624552, 6.695223355905408}, {37.51833748186357, + 6.898271977013918}, {36.902817240135484`, 7.1027229629840525`}, { + 36.393520684589326`, 7.277318806173719}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{36.29483513929001, 7.311234473907843}, { + 35.717406835542015`, 7.515463373573829}, {35.146891073127144`, + 7.723568470225793}, {34.59075120426723, 7.93270727580401}, { + 34.048674429187514`, 8.142787626324644}, {33.520347948113276`, + 8.353717357803855}, {33.00545896126979, 8.565404306257795}, { + 32.405245970933784`, 8.823052852566216}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{32.309356023355036`, 8.864214750087669}, { + 32.014742271176104`, 8.990681198154508}, {31.07402196070858, + 9.417880990144054}, {30.17918584270716, 9.845633102427938}, { + 29.326707107816212`, 10.272797234454115`}, {28.552052516926214`, + 10.67950785752588}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{28.460229845761305`, 10.729074097524581`}, { + 27.742324461400884`, 11.123793985729197`}, {27.007171886894103`, + 11.546842818976005`}, {26.30787936953296, 11.967736099960934`}, { + 25.64282257782625, 12.386081935682936`}, {25.010377180282784`, + 12.801488433140966`}, {24.888128885413025`, + 12.885001004092336`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{24.80196403156696, 12.94386357127988}, { + 24.407850358601106`, 13.213097969285446`}, {23.83293783513804, + 13.620222277448084`}, {23.28459808938979, 14.022723499199762`}, { + 22.761789600852552`, 14.420463776111358`}, {22.26347084902251, + 14.813305249753759`}, {21.788600313395868`, 15.201110061697849`}, { + 21.477426391746473`, 15.464257208364062`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{21.39774665257445, 15.531639127449974`}, { + 21.336136473468812`, 15.583740353514509`}, {20.905037808737546`, + 15.96105826677462}, {20.49376146727513, 16.332634273150287`}, { + 20.100946899490324`, 16.69814490609498}, {19.367630816952396`, + 17.41105498866324}, {18.6989450251215, 18.099958388422962`}, { + 18.39686698830514, 18.42919797856758}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{18.326319375369238`, 18.506088928381377`}, { + 18.088744987995376`, 18.76502497931771}, {17.602254806405167`, + 19.320908039731595`}, {17.15298803393434, 19.85857246085529}, { + 16.73682398254914, 20.378456172700123`}, {16.3514733811197, + 20.88080246971684}, {15.994684674556558`, 21.366052562182006`}, { + 15.71693624414, 21.759880316442757`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{15.65700704782492, 21.84530396883594}, { + 15.358596897028146`, 22.287009177393045`}, {15.075570069813962`, + 22.723859013899304`}, {14.594829123835861`, 23.509699672907118`}, { + 14.179832089842215`, 24.24642089136489}, {13.823430137262502`, + 24.938746513129637`}, {13.580018479139605`, + 25.459686307046468`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{13.535844191913988`, 25.554226331387117`}, { + 13.518474435526207`, 25.591400382058378`}, {13.480966901733915`, + 25.67640279313711}, {13.444284613175178`, 25.760778393771126`}, { + 13.275610911300683`, 26.189621036069482`}, {13.127021215791121`, + 26.60550237872598}, {12.867586708200312`, 27.414259588961812`}, { + 12.680065344170375`, 28.1846094265204}, {12.558712089105702`, + 28.93201935880526}, {12.513830615561275`, 29.576719947463232`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{12.506583638809852`, 29.680819251890238`}, { + 12.49834548964454, 29.799156267074707`}, {12.523880352172746`, + 30.686027996236586`}, {12.63837034246668, 31.627799152088937`}, { + 12.852545111510091`, 32.661841593843}, {13.001451961853148`, + 33.22796485133233}, {13.166744083068592`, 33.78194477868995}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{13.197795621150187`, 33.88155821706151}, { + 13.402221224260959`, 34.5018913934377}, {13.659722031857633`, + 35.22418999059383}, {13.964043211601997`, 36.0216307440609}, { + 14.325835946904315`, 36.91495736287581}, {14.53050014474458, + 37.4021432279129}, {14.691507637219605`, 37.777359731358345`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{14.7326568788365, 37.87325511064523}, {14.752191427700177`, + 37.91877898663597}, {14.991796194513057`, 38.466690781494705`}, { + 15.250200843925166`, 39.047704754938785`}, {15.63541493674554, + 39.89663309831635}, {16.070615644046338`, 40.83445138669106}, { + 16.30887934079907, 41.340249155511934`}, {16.46576757537701, + 41.67024458702501}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{16.510572904798224`, 41.76448717988874}, { + 16.56194172637851, 41.87253528489361}, {16.83057014585352, + 42.43273173293991}, {17.115531944292986`, 43.02226045775469}, { + 17.36145691760367, 43.527251190701676`}, {17.621609851328984`, + 44.05767042414354}, {17.896896837752735`, 44.6151339978141}, { + 18.18822396915872, 45.20125775144718}, {18.344606891439625`, + 45.513949043146454`}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{18.39128309078776, 45.607279189769265`}, { + 18.496497337830743`, 45.81765752477659}, {18.822623036052608`, + 46.46594915753615}, {19.167507156108115`, 47.14774848945969}, { + 19.532055790281067`, 47.864671360281}, {19.839183610360138`, + 48.46567286019579}, {20.162741532737172`, 49.09575387135}, { + 20.28266629551243, 49.32818672560848}}]}, + {Arrowheads[{{0.003123479124210378, 1.}}], + ArrowBox[{{20.330513472909036`, 49.42092200190289}, { + 20.503760459119256`, 49.75670162376452}, {20.629867991294255`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{50., 1.7511359116089673`}, {49.960134284961434`, + 1.7540651154278804`}, {49.22221194306671, 1.8099221158901446`}, { + 48.49665648317355, 1.866465206294774}, {47.783278664612, + 1.923666206718645}, {47.08188924671209, 1.9814969372386337`}, { + 46.392298988803866`, 2.039929217931617}, {45.839598440772846`, + 2.0880315798393907`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{45.73564016087489, 2.0970792256591313`}, { + 45.71431865021737, 2.098934868874471}, {45.04775899028265, + 2.158485710144072}, {44.392430768329746`, 2.2185535618172976`}, { + 43.74799858866116, 2.2791138280660452`}, {43.11415247384506, + 2.340141289741341}, {42.49074131060996, 2.401606831938752}, { + 41.87761398568441, 2.463481339753843}, {41.58055902877077, + 2.494149882712226}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{41.476759504917254`, 2.5048663514405587`}, { + 41.27461938579694, 2.5257356982821815`}, {40.68160639767606, + 2.588340792619332}, {40.098423908050314`, 2.651267507860863}, { + 39.52492080364824, 2.7144867291023376`}, {38.96094597119837, + 2.7779693414393227`}, {38.406348297429226`, 2.841686229967386}, { + 37.86097666906934, 2.9056082797820912`}, {37.32867005149847, + 2.9692294824105367`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{37.22509711996872, 2.9819506099958533`}, { + 36.27870692373057, 3.098314247901725}, {35.26722024390743, + 3.2272769265000725`}, {34.28892882092955, 3.3563449767732725`}, { + 33.34257143554012, 3.4852749694533856`}, {33.086097904959004`, + 3.5212893298954975`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{32.98276049097098, 3.535800109491692}, { + 32.426984021354585`, 3.613842993904198}, {31.54100251198838, + 3.741825139489496}, {30.68346284105696, 3.8689974955730637`}, { + 29.85320094217578, 3.9951361515186856`}, {29.04905274896027, + 4.120017196690148}, {28.854330464681183`, 4.150854827258613}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{28.75126367556069, 4.167177230102966}, { + 28.269854195025882`, 4.243416720451237}, {27.20679901243413, + 4.414611358620885}, {26.18584056161639, 4.581255495348989}, { + 25.20487771691266, 4.742993054384105}, {24.63227596365705, + 4.84267479744279}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{24.529470880009804`, 4.860571686292651}, { + 24.28422135970308, 4.903266106156867}, {23.39410554313743, + 5.057030237105138}, {22.539783081365762`, 5.205175637857531}, { + 21.72125397438806, 5.347702308414046}, {20.93851822220433, + 5.484610248774683}, {20.41711286864374, 5.57555160246802}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{20.314313525703067`, 5.593481436410019}, { + 20.188212975061155`, 5.615475370109662}, {19.466975383205117`, + 5.739873583589205}, {18.774805446636215`, 5.857804889213312}, { + 18.11170316535444, 5.969269286981984}, {17.511607102258267`, + 6.068314585996544}, {16.93367662775631, 6.161354991358417}, { + 16.331925585807774`, 6.255110053401209}, {16.196421903476818`, + 6.275379995241686}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{16.093218951584223`, 6.2908180836880145`}, { + 15.752588791268925`, 6.34177281362546}, {15.195666244139757`, + 6.421343272031169}, {14.66115794442027, 6.493821428618338}, { + 13.651403335580103`, 6.6179793006386465`}, {12.715344213118183`, + 6.71472489398798}, {11.948538853035643`, 6.775970877649539}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{11.844518869704418`, 6.784279121867986}, { + 11.762456164560819`, 6.7908336027833345`}, {10.883040045659525`, + 6.836382153963504}, {10.736207864590448`, 6.841656261576708}, { + 10.591389697545472`, 6.846056752660993}, {10.23713261896957, + 6.849706550621802}, {9.894701809328478, 6.848097646452643}, { + 9.117360737405736, 6.830890765822442}, {8.400166188720421, + 6.786857363461106}, {7.738128133578678, 6.718574564403359}, { + 7.677794488865157, 6.709704537825551}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{7.5745529916176455`, 6.694526359400124}, { + 7.126256542286653, 6.6286194936839244`}, {6.561285704708233, + 6.51910031378486}, {6.037337342598416, 6.3938117171738655`}, { + 5.30157012415421, 6.167715962877219}, {4.649703319574725, + 5.915600277989436}, {4.070293411341426, 5.6461960322187}, { + 3.632676908492608, 5.40620584902936}}]}, + {Arrowheads[{{0.009018488526614476, 1.}}], + ArrowBox[{{3.5420743658215295`, 5.354565090028833}, { + 2.704278109852364, 4.788692615883016}, {2.0432355837584906`, + 4.221255216724478}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{6.520942316078481, 38.929339855472676`}, { + 6.747524110405924, 38.14081512371605}, {6.961001825179257, + 37.41764365197272}, {7.161375460398483, 36.75982544024268}, { + 7.349055095733886, 36.1569686465526}, {7.5244508108557495`, + 35.598681428929154`}, {7.736023597766242, 34.93630054198494}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{7.767774354128731, 34.83689695389763}, {7.838390480458867, + 34.61581572188215}, {8.016510119192894, 34.06190121194002}, { + 8.17713297780455, 33.55444364059277}, {8.445888354660749, + 32.678899313682955`}, {8.651342670652985, 31.94788438137426}, { + 8.800181985406788, 31.320100483888233`}, {8.884484583035121, + 30.819696170423114`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{8.901820243325743, 30.716794961797998`}, { + 8.906353824221085, 30.689884480990816`}, {8.950274465078182, + 30.11185991349578}, {8.933361050030085, 29.552482820019254`}, { + 8.857030721128801, 28.97820923917736}, {8.719082795565011, + 28.360662271193995`}, {8.5173165905294, 27.67146501629304}, { + 8.305589859238136, 27.049375368300986`}, {8.16008913796415, + 26.655289079102204`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{8.123946331127387, 26.557396886521886`}, {8.04838929278722, + 26.352751901936166`}, {7.744418339148343, 25.57122665446563}, { + 7.5747323371208175`, 25.146220186483145`}, {7.393337350207783, + 24.69723191209402}, {7.004260226696846, 23.74466442495637}, { + 6.794018153296074, 23.23298003055406}, {6.573963473675769, + 22.697986476192686`}, {6.568319785750554, 22.684272491493292`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{6.528609454919318, 22.587772369871306`}, { + 6.513581441497226, 22.551249580272515`}, {6.266531700514734, + 21.949324744657638`}, {6.011151532141602, 21.32452646794287}, { + 5.615226128836256, 20.350135622059245`}, {5.412497157698578, + 19.84697224659695}, {5.206590673570895, 19.33316356945433}, { + 4.998904656112411, 18.811128860566395`}, {4.962474019194867, + 18.71870887957374}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{4.924206026373197, 18.621627755869785`}, { + 4.790837084982328, 18.28328738986814}, {4.582387960180644, + 17.749639157359567`}, {4.3735572817073605`, 17.210184163040676`}, { + 4.162525160380449, 16.661346305394304`}, {3.9596043015647355`, + 16.12339015968438}, {3.7577578004230445`, 15.582488133377872`}, { + 3.557713612628187, 15.040070667081643`}, {3.4416454168170247`, + 14.719900787821603`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{3.4060807892399114`, 14.621797061493174`}, { + 3.2274111848916682`, 14.128943483027241`}, {2.909215559479851, + 13.229542311586256`}, {2.6070886820923276`, 12.350413885049615`}, { + 2.3249924984286907`, 11.500104935708245`}, {2.147390147086162, + 10.947112548534534`}, {2.060833320365299, 10.67086336691861}}]}, + {Arrowheads[{{0.0034302695058375954`, 1.}}], + ArrowBox[{{2.0296327720313254`, 10.57128571060013}, { + 1.9787952509239446`, 10.409035959386559`}, {1.8193978369665709`, + 9.886948464805657}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{50., 6.874827243658772}, {49.203620389034064`, + 7.163263041922101}, {48.333322841780536`, 7.49686322046547}, { + 47.49223374284091, 7.8382770728481885`}, {46.68035309221518, + 8.187504599070254}, {46.13094238141069, 8.437118439378569}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{46.035936794583485`, 8.480282340104056}, { + 45.89518917003137, 8.544228226829274}, {45.1342502564175, + 8.908130383822861}, {44.39753635137357, 9.27921107005101}, { + 43.685047454899575`, 9.657470285513723}, {42.996783566995525`, + 10.042908030211}, {42.34638784663161, 10.427457718877667`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{42.25769063850247, 10.482422660339001`}, { + 41.69293081689724, 10.835319107309243`}, {41.077341954703, + 11.242292439710209`}, {40.48403073301128, 11.65633346288698}, { + 39.911049783754635`, 12.077331338380796`}, {39.35839910693308, + 12.50528606619166}, {38.86537331414647, 12.90809351978114}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{38.785493966967316`, 12.975223933688156`}, { + 38.3140885705952, 13.382066078764527`}, {37.82242871107889, + 13.83089136352653}, {37.351099123997656`, 14.286673500605577`}, { + 36.90009980935151, 14.74941249000167}, {36.427632965334816`, + 15.268065437920663`}, {35.977437968591566`, 15.79550532888168}, { + 35.85931988760107, 15.942778373419962`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{35.79403123560978, 16.024182155736156`}, { + 35.52930710200576, 16.35424787295483}, {35.10448668176217, + 16.922698621587035`}, {34.70266314735557, 17.50114935904269}, { + 34.323522938280746`, 18.089891869586193`}, {33.96657014313624, + 18.688693750370863`}, {33.63145473123757, 19.297741948238876`}, { + 33.52122594952762, 19.515902511305697`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{33.474166806511974`, 19.609040156288028`}, { + 33.31808196315501, 19.917957271987934`}, {33.026357099458814`, + 20.55026053041572}, {32.73390691361097, 21.25154698730158}, { + 32.46655059539791, 21.96949424418804}, {32.22438463830975, + 22.705098267695945`}, {32.00647627194189, 23.44873138049053}, { + 31.992763310045042`, 23.503343362304825`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{31.967349832051884`, 23.604552744234137`}, { + 31.81419248740453, 24.21450310970032}, {31.64729205097233, + 24.999923538773224`}, {31.505774962645294`, 25.804992667709243`}, { + 31.38964122242342, 26.629710496508377`}, {31.299789965554968`, + 27.47707453405408}, {31.282618054763265`, 27.716284647706317`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{31.275146334243594`, 27.820368062555648`}, { + 31.23712032728819, 28.350082289229803`}, {31.201632307623083`, + 29.248733762035556`}, {31.193325906559647`, 30.17302895247133}, { + 31.196237980568633`, 30.68944518677864}, {31.207823904826466`, + 31.214772490868395`}, {31.261258053382626`, 31.99034278318651}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{31.268430496134407`, 32.09444724956137}, { + 31.280624910293685`, 32.27144315217633}, {31.3392793354549, + 32.82572313182294}, {31.389032191645075`, 33.3696252518725}, { + 31.49698521092545, 34.33338576344629}, {31.634158226167248`, + 35.33350954852206}, {31.779002991315153`, 36.23576934593132}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{31.795543296346978`, 36.338801390284885`}, { + 31.80055123737047, 36.36999660709981}, {31.89470524145762, + 36.90187636395193}, {31.996164244535123`, 37.44284693917954}, { + 32.10586027333454, 37.9946721297735}, {32.22472535458742, + 38.55911573272466}, {32.35275948829376, 39.136177748033035`}, { + 32.48996267445358, 39.725858175698605`}, {32.636334913066854`, + 40.32815701572138}, {32.65990111511854, 40.42132368622584}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{32.685490481910925`, 40.52248874027805}, { + 32.791876204133594`, 40.94307426810136}, {32.95658654765381, + 41.57060993283855}, {33.13046594362748, 42.21076400993294}, { + 33.29267330664639, 42.8263650157106}, {33.49789198619859, + 43.51494439793041}, {33.71306370887791, 44.21754049283371}, { + 33.81448092796259, 44.54012309646097}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{33.84577779000505, 44.639670523753274`}, { + 33.93858047002119, 44.93485245058366}, {34.17483426496527, + 45.66757942134339}, {34.422217089046974`, 46.41642055527606}, { + 34.68112093760313, 47.18207500254481}, {34.95193780597058, + 47.96524191331279}, {35.17564521405926, 48.595935001149904`}}]}, + {Arrowheads[{{0.006656836429678303, 1.}}], + ArrowBox[{{35.210529262610564`, 48.694282787148836`}, { + 35.29346894313344, 48.928112697656154`}, {35.6569807278478, + 49.92446064885173}, {35.68510583913165, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{50., 14.317042278784916`}, {49.79846536476008, + 14.537376612102017`}, {49.40644030887509, 14.990385375837368`}, { + 49.028918643930055`, 15.452469502978406`}, {48.665968349402526`, + 15.924071796750399`}, {48.31765740477005, 16.405635060378618`}, { + 47.98405378951019, 16.897602097088335`}, {47.665225483100485`, + 17.40041571010482}, {47.51229945365775, 17.659045986922834`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{47.45918741805998, 17.7488696782792}, {47.36124046501849, + 17.914518702653346`}, {46.974658029572694`, 18.62681614545136}, { + 46.61517531489776, 19.361681432778937`}, {46.28306297024403, + 20.120135742567584`}, {45.97570471952488, 20.892307688146037`}, { + 45.747425333746826`, 21.54770412339392}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{45.71310149216061, 21.64624882265769}, { + 45.696934760453466`, 21.692663956877354`}, {45.446076469903936`, + 22.518651603932764`}, {45.2231298478763, 23.370270629312262`}, { + 45.02809489437055, 24.247521033015854`}, {44.86210358164024, + 25.153329884018632`}, {44.78154217075229, 25.709302108225703`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{44.76657776427871, 25.81257480739211}, {44.72628788193894, + 26.090624251295694`}, {44.620647795266635`, 27.059404134847036`}, { + 44.545183321623334`, 28.059669534672665`}, {44.50654835123847, + 28.70981216361135}, {44.480885425224315`, 29.374275143590665`}, { + 44.48709091384877, 29.973461198971894`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{44.48817157281706, 30.077806855471895`}, { + 44.49117162165552, 30.367483871780426`}, {44.530404031511395`, + 31.395478307774827`}, {44.58594872962269, 32.4513471914469}, { + 44.625734967197104`, 32.99441429266528}, {44.67353046378401, + 33.547569833471904`}, {44.72933521938342, 34.110813813866756`}, { + 44.74399742622041, 34.24254535558632}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{44.75554082311682, 34.34625617393385}, {44.79314923399534, + 34.684146233849845`}, {44.864972507619754`, 35.267567093421164`}, { + 44.944805040256675`, 35.86107639258071}, {45.03351531846789, + 36.46626178265941}, {45.13197182881522, 37.08471091498816}, { + 45.24017457129864, 37.71642378956696}, {45.35812354591816, + 38.36140040639582}, {45.37962828448109, 38.472252545588915`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{45.39950138644366, 38.57469396139623}, {45.48581875267378, + 39.01964076547473}, {45.62326019156551, 39.691144866803704`}, { + 45.77044786259332, 40.37591271038272}, {45.92738176575725, + 41.0739442962118}, {46.07566535677869, 41.75314698560655}, { + 46.26356793835725, 42.497726228657335`}, {46.30310678749583, + 42.649041366727204`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{46.32948814192834, 42.75000278506376}, {46.46190878508551, + 43.256776460554455`}, {46.6710339134703, 44.03090130459605}, { + 46.891289340018425`, 44.82070438408026}, {47.12302108123667, + 45.62678932230521}, {47.366575153631864`, 46.44975974256904}, { + 47.463059792993334`, 46.76686699581841}}]}, + {Arrowheads[{{0.015764013498501508`, 1.}}], + ArrowBox[{{47.49343530465901, 46.866699416130004`}, { + 47.62229757371081, 47.29021926816991}, {47.78953620961886, + 47.82755288342334}, {47.96255904674318, 48.3734357558464}, { + 48.14153700647821, 48.92815846373074}, {48.32664101021842, + 49.49201158536796}, {48.49624482199345, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{36.66146237085959, 8.263914813368329}, {35.71546705206069, + 8.667343199075988}, {34.81159710940318, 9.075345179120824}, { + 33.948178062770246`, 9.487460304503008}, {33.1232031285105, + 9.902981563513073}, {32.88160788488025, 10.03116467702101}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{32.7894276842507, 10.080072697489191`}, {32.33478636062148, + 10.321291603608696`}, {31.58143453545975, 10.742064464540771`}, { + 30.86165442938186, 11.16497418606019}, {30.173952818744354`, + 11.589694807917848`}, {29.516836479903773`, 12.015900369864646`}, { + 29.21082587198215, 12.224137670834732`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.12455473587262, 12.282844356387516`}, { + 28.888812189216672`, 12.443264911651475`}, {28.288386723039608`, + 12.871462473029224`}, {27.812745077771755`, 13.224225683822695`}, { + 27.352560046544344`, 13.57668358637938}, {26.907364449599033`, + 13.928775227887105`}, {26.476691107177487`, 14.280439655533701`}, { + 25.82647979178595, 14.837166637098147`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{25.7472144643065, 14.905035567499304`}, {25.65704246687232, + 14.982243057994816`}, {24.929742693607217`, 15.686807477903953`}, { + 24.241844748103517`, 16.387224929881725`}, {23.60269222552805, + 17.084714470171555`}, {23.0122851258808, 17.77927609877344}, { + 22.886893790914343`, 17.939385035401497`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{22.822553033364425`, 18.02154007646487}, { + 22.470623449161778`, 18.470909815687385`}, {21.972560967103952`, + 19.159892670674193`}, {21.512951451440298`, 19.846501713494664`}, { + 21.091794902170815`, 20.5307369441488}, {20.709091319295503`, + 21.212598362636598`}, {20.554650334885732`, + 21.517176239641298`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{20.507457695744282`, 21.61024631359145}, { + 20.32860457317984, 21.96296812881766}, {19.988119739213047`, + 22.712820832827653`}, {19.600813081410717`, 23.69184470726316}, { + 19.275231798499632`, 24.675144345818538`}, {19.050793405472263`, + 25.511958598471697`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{19.023761188874364`, 25.612747700660506`}, { + 19.009247426095087`, 25.666861987389716`}, {18.800731499812372`, + 26.671139870872633`}, {18.698038643681045`, 27.317662178776402`}, { + 18.61813103801594, 27.974673710954345`}, {18.561008682817057`, + 28.642174467406463`}, {18.526671578084397`, 29.320164448132747`}, { + 18.51893932036319, 29.550413556907138`}, {18.514604880965038`, + 29.74703412180877}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{18.515577538831486`, 29.851354677503736`}, { + 18.53292501704715, 30.5365847327041}, {18.57995578282932, + 31.314368299999444`}, {18.641662638120913`, 32.10582057800698}, { + 18.732721672431342`, 32.9246102774389}, {18.85477093563476, + 33.77497554349018}, {18.89476965370882, 34.00413630365761}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{18.912712308706062`, 34.106933409579284`}, { + 19.00944847760532, 34.66115452135578}, {19.198793648023983`, + 35.587749330379765`}, {19.426477276316493`, 36.5630437853814}, { + 19.561173517589673`, 37.09353545256812}, {19.70778272716713, + 37.640010445114925`}, {19.857486575610498`, 38.17035049938011}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{19.886672783363053`, 38.27053518143277}, { + 20.039153109372382`, 38.78594490575548}, {20.225120811068916`, + 39.387921623582564`}, {20.425414539207225`, 40.01091616623641}, { + 20.64063755832167, 40.6561871585837}, {20.87139313294664, + 41.32499322549109}, {21.119496113481485`, 42.020505826927334`}, { + 21.19765531514149, 42.232515873047646`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{21.23375052915746, 42.33042562424416}, { + 21.387134145976336`, 42.74648498750797}, {21.675469688441716`, + 43.50507217906986}, {21.985665198888142`, 44.298408873449866`}, { + 22.318883135326143`, 45.12863654248485}, {22.676285955766232`, + 45.99789665801166}, {22.766502945160617`, 46.21249256321073}}]}, + {Arrowheads[{{0.019295018806835394`, 1.}}], + ArrowBox[{{22.806944177921398`, 46.308688667846056`}, { + 23.059036118218938`, 46.908330691867164`}, {23.468296080694778`, + 47.86208011588822}, {23.79270785106708, 48.604754647815916`}, { + 24.136415647290978`, 49.379289607909726`}, {24.41602856885353, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{6.065923617017819, 50.}, {6.337651605127494, + 49.366768500200685`}, {6.632376243683451, 48.748239313220616`}, { + 6.931135104593402, 48.18860224396082}, {7.233928187857343, + 47.687857292421306`}, {7.505392647270676, 47.29312017236674}, { + 7.780932135147687, 46.942191372141174`}, {8.188857130920077, + 46.5107445524898}, {8.236416266572492, 46.472146956181426`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{8.317441576773264, 46.40638919647893}, {8.607999853016935, + 46.170580641578525`}, {9.489390127522537, 45.768827737528376`}, { + 10.52700470705095, 45.7723042368643}, {10.627875123563744`, + 45.79428797065904}, {10.72985404873297, 45.82049177984651}, { + 11.118168251342006`, 45.98874585596824}, {11.526542968550174`, + 46.2196702284124}, {12.101508577216016`, 46.595917698652755`}, { + 12.10584355132604, 46.59944102174456}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{12.186821443903355`, 46.66525716541736}, { + 12.721666394581243`, 47.09996139142419}, {13.39746264217288, + 47.74841523623559}, {13.760142510376234`, 48.133026189222115`}, { + 14.139343541517947`, 48.55789316259586}, {14.529824353417094`, + 49.01433124179023}, {14.961286111765588`, 49.551554942682586`}, { + 15.059447679183357`, 49.67842662765621}}]}, + {Arrowheads[{{0.001448163833233887, 1.}}], + ArrowBox[{{15.123303631271027`, 49.76095905302466}, { + 15.308251391971183`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{2.4920982917921206`, 50.}, {2.492355221430933, + 49.99707541494844}, {2.5697093403475773`, 49.12990136806211}, { + 2.6458802042681198`, 48.28654893619036}, {2.72075093018016, + 47.46617217705798}, {2.794204635071296, 46.66792514838975}, { + 2.8661244359291285`, 45.89096190791045}, {2.8705657177562873`, + 45.8431464867968}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{2.880216724716865, 45.7392424834145}, {2.9363934497412556`, + 45.13443651334489}, {3.0048947934952763`, 44.39750302241782}, { + 3.0715115841787903`, 43.67931549285405}, {3.1706826577739724`, + 42.599660168163545`}, {3.2629039954457433`, + 41.582773909551236`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{3.2721605233403093`, 41.47883405465382}, { + 3.353360181769914, 40.56288082598207}, {3.4361716109979366`, + 39.60003085896253}, {3.5129928471190572`, 38.67130155462539}, { + 3.583601326155475, 37.77446876693039}, {3.6173802773864705`, + 37.319128942476624`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{3.625100262211921, 37.21506364716394}, { + 3.6478796264146296`, 36.907998113178024`}, {3.705654291879761, + 36.069401945963776`}, {3.755235599296461, 35.28186548132726}, { + 3.798540740025106, 34.515700512460796`}, {3.8355697140656977`, + 33.77090703936439}, {3.86629213494708, 33.0481998664068}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{3.869929695191671, 32.94391205481668}, {3.890861572824205, + 32.3428937370531}, {3.9092492790250954`, 31.65459222098092}, { + 3.921485640020906, 30.982580513821492`}, {3.927570655811637, + 30.326858615574814`}, {3.92837020934439, 30.154803638546454`}, { + 3.928748941428379, 29.983747315327125`}, {3.9216617408297934`, + 29.296417945809083`}, {3.9108605450049225`, 28.77076132233014}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{3.908716787294552, 28.66643209269098}, { + 3.9078315846436262`, 28.623352359286947`}, {3.8907521865259196`, + 27.95698378751941}, {3.867174304545133, 27.30400924526106}, { + 3.8373572233377327`, 26.663594477765482`}, {3.8015602275401847`, + 26.034905230286256`}, {3.7600248719971905`, 25.417397198317364`}, { + 3.7131859554292124`, 24.810090633747972`}, {3.6850732969684383`, + 24.49921494158346}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{3.67567510576252, 24.395287765848337`}, {3.62500256903564, + 23.834940193217292`}, {3.5244561774069973`, 22.885828473935085`}, { + 3.413141763048003, 21.96012894071209}, {3.2926543084633773`, + 21.055215058359032`}, {3.1762412267695304`, + 20.251880951377164`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{3.1610406659772488`, 20.148643747354644`}, { + 3.030094523850258, 19.307924827513055`}, {2.8909753887887213`, + 18.46597272970803}, {2.7486453140336957`, 17.644318943897805`}, { + 2.60436795946291, 16.84338830972699}, {2.4592654096800084`, + 16.06420430367305}, {2.4537240531095224`, 16.03519411433671}}]}, + {Arrowheads[{{0.013483247334737701`, 1.}}], + ArrowBox[{{2.434145463922294, 15.932696003624075`}, {2.31463671838124, + 15.307042106172382`}, {2.1717809392628533`, 14.572176897661388`}, { + 2.0312107219629225`, 13.860075186099031`}, {1.8944329264314093`, + 13.1709615938717}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{32.60418249978299, 7.73945746609291}, {31.626987959007483`, + 8.10203082157432}, {30.694175687271834`, 8.464613223653483}, { + 29.80251519835569, 8.82619531000804}, {28.95044545716806, + 9.186366225633893}, {28.727393557614718`, 9.284555992463714}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{28.631886696912428`, 9.326599106204439}, { + 28.136405428617955`, 9.544715115526941}, {27.358834077614397`, + 9.900831124683087}, {26.616170369066396`, 10.254303398098234`}, { + 25.906853267882973`, 10.604721080768279`}, {25.229321738973127`, + 10.951673317689128`}, {24.873388103418627`, + 11.139818136326847`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{24.781132596104932`, 11.188583956575403`}, { + 24.58104691705507, 11.29434829025012}, {23.95985187509821, + 11.632079984788435`}, {23.364703485388358`, 11.964676253721736`}, { + 22.79456862021134, 12.291944949467686`}, {22.248414151852977`, + 12.613693924443945`}, {21.725206952599088`, 12.929731031068176`}, { + 21.223913894735492`, 13.239864121758039`}, {21.167389770133415`, + 13.275636374687782`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{21.07921325936831, 13.331440378159874`}, { + 20.743501850548018`, 13.543901048931197`}, {19.839576325779618`, + 14.132040108052182`}, {19.004842963267436`, 14.692435484903253`}, { + 18.23297110117612, 15.22460325604074}, {17.615230504942797`, + 15.659368422414197`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{17.5298952053702, 15.719427314354329`}, {17.51763007767032, + 15.728059498020976`}, {16.922035882888594`, 16.15137091937015}, { + 16.364190195685644`, 16.55095396681119}, {15.83943758250957, + 16.926710666595632`}, {15.345191691387095`, 17.278586588863227`}, { + 14.87888084156338, 17.606676657191496`}, {14.437933352283583`, + 17.91107579515795}, {14.119336084497675`, 18.125546664851374`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{14.032771390609014`, 18.183819622783712`}, { + 14.020686912711152`, 18.19195455910177}, {13.624512265571033`, + 18.449605907886507`}, {13.162927955817471`, 18.7353171834392}, { + 12.494265459904154`, 19.111856304905178`}, {11.878169376194116`, + 19.408232831903714`}, {11.306653828466967`, 19.62728493439558}, { + 10.771732940502316`, 19.771850782341545`}, {10.703233262099188`, + 19.786080818383116`}, {10.635263880683283`, 19.79905710098755}, { + 10.28047833250874, 19.827527824428625`}, {10.248765140504853`, + 19.82695943576839}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{10.144430644355005`, 19.82508947122885}, { + 9.937333575490864, 19.821377715392483`}, {8.89015653732592, + 19.63427485552094}, {7.924869009184266, 19.13396031501206}, { + 7.464683943297934, 18.78030182013262}, {7.016582902540748, + 18.365397246175977`}, {6.596879459262006, 17.90249235280233}}]}, + {Arrowheads[{{0.018522790985394364`, 1.}}], + ArrowBox[{{6.52678760667327, 17.82518571625086}, {6.39002147396624, + 17.67434179754651}, {5.786165688148222, 16.887014650816926`}, { + 5.206467259413866, 16.023444733800467`}, {4.652377902090347, + 15.103660974310372`}, {4.383974601218351, 14.616711696950205`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{38.04738862120897, 4.185894000418275}, { + 37.467493807026365`, 4.29117337086192}, {36.89851937346901, + 4.396776813064768}, {36.340285799099576`, 4.502659245591524}, { + 35.79261356248076, 4.608775587006894}, {34.72823501674582, + 4.8215296707622874`}, {33.95039169626236, 4.983394706774173}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{33.84822899744271, 5.004654218153966}, { + 33.703947564765734`, 5.034678412848586}, {32.71831503504209, + 5.247861161783424}, {31.769901256076466`, 5.460717266084436}, { + 30.857270056370425`, 5.67288607426926}, {29.978985264425546`, + 5.884006934855529}, {29.77905654227884, 5.933549318289316}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{29.677768748849527`, 5.958648456849083}, { + 29.13331289014547, 6.0935647441391865`}, {28.31862724110582, + 6.301100562860422}, {27.533654592316132`, 6.506337986203251}, { + 26.777121218785936`, 6.709000609351691}, {26.04775339552477, + 6.908812027489755}, {25.641711890674458`, 7.022336568107484}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{25.541214659495147`, 7.050434439548462}, { + 25.344277397542175`, 7.105495835801455}, {24.66541949984768, + 7.298775629470811}, {24.009905977450824`, 7.488375003681834}, { + 23.148208836877217`, 7.740486277153068}, {22.32209740641028, + 7.983823704355556}, {21.533495492945075`, 8.216870669059556}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{21.433780440426805`, 8.24762825845424}, {20.79012690859723, + 8.446509549985405}, {20.075158559110577`, 8.664283510641763}, { + 19.389703064970227`, 8.87223398651537}, {18.733760426176186`, + 9.070360977606228}, {18.107330642728453`, 9.258664483914334}, { + 17.507291293289878`, 9.43682532109176}, {17.43872507382144, + 9.45676127246096}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{17.338523344220626`, 9.485895397456012}, {16.9305199565233, + 9.604524304790578}, {16.377016632428727`, 9.761761435010788}, { + 15.846781321006157`, 9.908536711752387}, {15.315404779113406`, + 10.05079559595937}, {14.805287045410859`, 10.181549198491028`}, { + 14.013108261210721`, 10.370643339126197`}, {13.296834760644275`, + 10.52367668482355}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{13.194373614364062`, 10.543406857001452`}, { + 12.570970589643531`, 10.658715186436451`}, {11.912819404013131`, + 10.75904231444263}, {11.065074496823504`, 10.852201311192127`}, { + 10.28020294029533, 10.894964449119497`}, {10.162866815735214`, + 10.897699965546765`}, {10.046886547930084`, 10.899290285896486`}, { + 9.709117433500413, 10.890658511444546`}, {9.382401999689897, + 10.872341309348814`}, {9.04678046343293, 10.842251332650026`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{8.942846083605277, 10.832933149132677`}, { + 8.671164729309828, 10.808575696653863`}, {8.011025970770946, + 10.699894286596136`}, {7.397584577192774, 10.550854280657987`}, { + 6.826439401694834, 10.366012880321776`}, {6.294943034315532, + 10.14909750592898}, {5.798330137123992, 9.906817514094255}, { + 5.121296735164822, 9.498634570724175}, {5.0538865149316825`, + 9.449398105771877}}]}, + {Arrowheads[{{0.012638712578083364`, 1.}}], + ArrowBox[{{4.969619444643511, 9.387849387513327}, {4.511707966607465, + 9.053390571600833}, {3.962028766022461, 8.584892690184596}, { + 3.468925591271482, 8.101814216812416}, {3.0278376262222397`, + 7.613364237702503}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{49.23421804558305, 0.8316664813545216}, {48.51101982045465, + 0.8566509582387026}, {47.79915966134927, 0.8818957332494143}, { + 47.09833028252699, 0.9073954298493504}, {46.40824735226441, + 0.9331435098348084}, {45.72877000144163, 0.9591261745871047}, { + 45.06299789459429, 0.9852027023781942}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{44.958730302279925`, 0.9893803531077733}, { + 44.40106856163575, 1.0117400639174792`}, {43.75256273441282, + 1.0383436912581903`}, {43.114099010149985`, 1.065126708891007}, { + 42.485536519727304`, 1.0920753181972462`}, {41.86673439402487, + 1.1191757205582245`}, {41.25755176392275, 1.1464141173552584`}, { + 40.78850246109985, 1.1678153501496118`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{40.68425965912677, 1.1725716187523691`}, { + 40.657847760301024`, 1.173776709969665}, {40.067481514039784`, + 1.2012496997827604`}, {39.48631215601908, 1.228819288175862}, { + 38.91419881711899, 1.2564716765302868`}, {38.35100062821959, + 1.2841930662273513`}, {37.79657672020095, 1.3119696586483724`}, { + 36.713460321076866`, 1.367635887312342}, {36.5152831277517, + 1.378156027799674}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{36.41107859458342, 1.3836876750591467`}, { + 35.663704880901335`, 1.4233616472885051`}, {34.64619869176009, + 1.4790351150138743`}, {33.65983004573886, 1.5345444669254624`}, { + 32.703487234923394`, 1.5897778794602806`}, {32.24356066634335, + 1.61697670549179}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{32.13939140664019, 1.6231369966470601`}, { + 31.776058551399444`, 1.6446235290553408`}, {30.876432287252744`, + 1.6989695921476553`}, {30.003496734569026`, 1.7527042451742365`}, { + 29.405692695819834`, 1.789955808501504}, {28.819480003418875`, + 1.8267349197805682`}, {28.244607992947174`, 1.8630193633547578`}, { + 27.973270007730587`, 1.8802336373921977`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{27.86912812585858, 1.8868406256908998`}, { + 27.68082599998575, 1.8987869235674026`}, {27.127883360115614`, + 1.9340153847618324`}, {26.5855294089178, 1.9686825312813758`}, { + 25.552974945282806`, 2.0381397537050145`}, {24.55475397492972, + 2.1046408164156496`}, {23.70412265418931, 2.1614065861825535`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{23.600002986878568`, 2.1683548761392686`}, { + 23.59587978623814, 2.1686300325466927`}, {22.67635237920806, + 2.2301074020981444`}, {21.796171753839484`, 2.289072925070005}, { + 20.95203716839443, 2.3453151883986934`}, {20.14064788113491, + 2.3986227790206285`}, {19.435083526714784`, + 2.4442679465269648`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{19.330947785798966`, 2.450970827341683}, { + 18.616105201172488`, 2.496433942144239}, {18.002626383969353`, + 2.5346459778409858`}, {17.410148971334863`, 2.570608221642296}, { + 16.614216322693593`, 2.617129773469813}, {15.855851598895057`, + 2.659202369632701}, {15.164083814979126`, 2.6952386266731256`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{15.059859785893886`, 2.7003866714439924`}, { + 14.444372621614194`, 2.730088259651493}, {13.862994411619322`, + 2.7558393425949537`}, {13.304444661273038`, 2.778325497332481}, { + 12.255830539526233`, 2.8135030221897366`}, {11.291035103044868`, + 2.8362826319066285`}, {10.888438256837626`, + 2.8412868139547105`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{10.784095064693158`, 2.842583774757777}, { + 10.402563198500038`, 2.847326124166525}, {10.242401412705563`, + 2.8483009528073273`}, {10.084711198244852`, 2.848888105358699}, { + 9.745923882541744, 2.847501297711473}, {9.41848089887902, + 2.844327527556718}, {8.646481286148136, 2.8316578528546787`}, { + 7.93728238657567, 2.809222879634646}, {7.285830078242592, + 2.7780381648152788`}, {6.687070239229876, 2.7391192653152365`}, { + 6.612878458040452, 2.732291395190102}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.5089663210109405`, 2.7227283605158}, {5.630927116849549, + 2.6419224066125797`}, {4.902061320825722, 2.547617296684414}, { + 4.265843246427178, 2.4439054882570947`}, {3.221378058167581, + 2.220748895938165}, {2.426380730132568, 1.9901834985655629`}, { + 2.4105078953076413`, 1.984243226294471}}]}, + {Arrowheads[{{0.005629882578595802, 1.}}], + ArrowBox[{{2.312776420891829, 1.9476680603654792`}, { + 1.8238352430992246`, 1.7646860188668028`}, {1.2357375630633354`, + 1.4810766224636773`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{5.422804138815669, 49.06237784513235}, { + 5.7180125415408005`, 48.133769060446994`}, {6.014336342928001, + 47.28615002998856}, {6.311698936632197, 46.513273102085286`}, { + 6.610023716308318, 45.80889062506539}, {6.909310681956363, + 45.17300259892887}, {6.912053336794484, 45.16781968758377}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.960860777942236, 45.075586192893226`}, { + 7.209559833576332, 44.605609023675726`}, {7.483906494512723, + 44.146652133038145`}, {7.759958768910425, 43.73929533460663}, { + 8.335785207985936, 43.059172850025035`}, {8.926926102444082, + 42.58849496636557}, {9.847123551312599, 42.28562331774599}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{9.950103394162635, 42.27291046265703}, { + 10.019922948842948`, 42.2709011462738}, {10.382896418236934`, + 42.339410749903585`}, {10.763334442566057`, 42.476789676779525`}, { + 11.26829736297392, 42.714511728431034`}, {11.809766888230172`, + 43.07616914481139}, {12.39763034537957, 43.57653615607823}, { + 13.041775061466872`, 44.23038699238919}, {13.330011975063499`, + 44.55115918224427}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{13.398873335225309`, 44.62954192432216}, { + 13.755564037444334`, 45.05943886363038}, {14.14926552365368, + 45.5570389552587}, {14.563050675026018`, 46.102782747596784`}, { + 15.072901269461736`, 46.80456011431776}, {15.625697769140709`, + 47.59766554212114}, {15.883495936148474`, 47.98090219291252}}]}, + {Arrowheads[{{0.011063788351635493`, 1.}}], + ArrowBox[{{15.941739949700994`, 48.0674863643269}, { + 16.227985067083072`, 48.493011577962676`}, {16.549733044471818`, + 48.98243499482141}, {16.886308056308966`, 49.50151076879809}, { + 17.205344462523815`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{22.222492756922126`, 13.72251761101824}, { + 21.66929228011176, 14.113318870339784`}, {21.142564235439213`, + 14.49672133070915}, {20.640011337705104`, 14.872129011079782`}, { + 20.16065016729063, 15.239479707064227`}, {19.70349730457699, + 15.598711214275042`}, {19.267569329945385`, 15.949761328324776`}, { + 18.90272055134584, 16.25064321163222}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{18.822623251580477`, 16.31752303899174}, { + 18.077300538354766`, 16.953201267633034`}, {17.37014221868529, + 17.57925159667856}, {16.72219233328327, 18.170048746679374`}, { + 16.127672572407757`, 18.72612978363757}, {15.72321280012335, + 19.112124906420206`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{15.647722275241327`, 19.184169090829904`}, { + 15.580804626317798`, 19.248031773555244`}, {15.072466396313434`, + 19.737848990112823`}, {14.603636647296515`, 20.193344972746964`}, { + 14.168525878325624`, 20.615502995050935`}, {13.763917699988866`, + 21.00486932013211}, {13.033859609411712`, 21.688223719336833`}, { + 12.703376992889382`, 21.98358466362569}, {12.618989081820196`, + 22.055645316505284`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{12.539633529628224`, 22.123408729867727`}, { + 12.392201857783952`, 22.24930380646843}, {11.55646217873036, + 22.873509680976852`}, {10.828553749993715`, 23.25916605743531}, { + 10.782732246394643`, 23.27731235231735}, {10.737227466659883`, + 23.294468469578415`}, {10.474773473670641`, 23.357407149545708`}, { + 10.219843328184421`, 23.38669263645188}, {9.72221989622388, + 23.37922827640576}, {9.244038857934463, 23.243058776821357`}, { + 8.811694353927784, 23.00404400122332}}]}, + {Arrowheads[{{0.015757229165579895`, 1.}}], + ArrowBox[{{8.727151169542925, 22.9436239632191}, {8.249087343926496, + 22.546564053748188`}, {7.719829863785956, 21.966740141979948`}, { + 7.1832687862815385`, 21.256369245500245`}, {6.639725907738225, + 20.42673827847845}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{50., 11.46237682901988}, {49.88912467024407, + 11.54287682992053}, {49.25623860318609, 12.033250972594347`}, { + 48.648364699713916`, 12.536329915833266`}, {48.065187743679964`, + 13.052353449233644`}, {47.50641146893203, 13.581532094528852`}, { + 46.97177277180982, 14.124025154692017`}, {46.87881788721517, + 14.225206532213788`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{46.80822049649411, 14.302051781107908`}, {46.461008548653, + 14.679991932696266`}, {46.07297034319253, 15.129707180118553`}, { + 45.69935357310561, 15.587521199686858`}, {45.340201495431835`, + 16.053864744570316`}, {44.995557367210786`, 16.52916856793806}, { + 44.66546444548206, 17.01386342295924}, {44.349965987285245`, + 17.508380062802974`}, {44.28484174168989, 17.617642282146665`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{44.23141494137347, 17.70727910974655}, {44.04910524965994, + 18.013149240638413`}, {43.762925489645724`, 18.528601709634685`}, { + 43.399137500753675`, 19.243569870713735`}, {43.06213999586156, + 19.980034893791803`}, {42.752167766312844`, 20.7390106592554}, { + 42.47604906510501, 21.486080922461145`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{42.443016317651974`, 21.585047099552863`}, { + 42.20981639498403, 22.30945519160593}, {41.98017648554454, + 23.132752563002157`}, {41.778031434135414`, 23.980588437556936`}, { + 41.60338124075667, 24.85296281527026}, {41.4756787296126, + 25.639687107466084`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{41.45895908108163, 25.742690200658583`}, { + 41.457314387332445`, 25.75282250357195}, {41.34091935578689, + 26.68311430989181}, {41.25419614612001, 27.64383823422985}, { + 41.197144758331795`, 28.634994276586063`}, {41.17077797668167, + 29.263550328445145`}, {41.1566170833663, 29.903098093408616`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{41.159225073015406`, 30.0074141801061}, {41.18290278128267, + 30.916477862011032`}, {41.239470154571414`, 31.96373594165704}, { + 41.310524231197896`, 33.00682029690799}, {41.41314628077346, + 34.08959161499589}, {41.42248237616456, 34.1718315939104}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{41.43425299715218, 34.27551686931529}, { + 41.476295295417145`, 34.645859885103704`}, {41.54733630329811, + 35.21204989592076}, {41.62626930441633, 35.78816164744705}, { + 41.713094298771836`, 36.37419513968258}, {41.808699349169395`, + 36.97178450283095}, {41.91397251841377, 37.58256386709577}, { + 42.028913806504974`, 38.20653323247704}, {42.066788708726065`, + 38.400197172450326`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{42.08681727815155, 38.50260830593195}, {42.15352321344301, + 38.84369259897476}, {42.28780073922787, 39.49404196658893}, { + 42.43174638385956, 40.15758133531955}, {42.58536014733808, + 40.834310705166615`}, {42.74864202966342, 41.524230076130124`}, { + 42.902547693371, 42.193979072960275`}, {43.002900928586094`, + 42.574297861926645`}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{43.029524445517225`, 42.67519569243077}, { + 43.097046136761335`, 42.931089463945746`}, {43.30192910040782, + 43.68264479179374}, {43.51755478501513, 44.4492725243773}, { + 43.74428139128791, 45.23160012956945}, {43.982467119930845`, + 46.03025507524323}, {44.1835404360481, 46.68623649936296}}]}, + {Arrowheads[{{0.016199078980985673`, 1.}}], + ArrowBox[{{44.21412206270687, 46.78600597347767}, {44.23247017164858, + 46.84586482927169}, {44.49464874714579, 47.679056859527854`}, { + 44.66394023488933, 48.20566914183808}, {44.83892860311367, + 48.74074678767328}, {45.01978687836011, 49.28458485565135}, { + 45.20668808716997, 49.83747840439018}, {45.26251030228074, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{48.5151686627396, 6.445255918115043}, {47.649670000756565`, + 6.734681197013667}, {46.78858005312277, 7.037906999039333}, { + 45.95225028413573, 7.346977339326902}, {45.14068069379543, + 7.6618922178763755`}, {44.597685680959884`, 7.883255563383042}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{44.50105568739623, 7.922648814049999}, {44.35387128210187, + 7.9826516346877545`}, {43.59182204905506, 8.309255589761037}, { + 42.85453299465499, 8.641704083096224}, {42.14200411890167, + 8.979997114693315}, {41.45423542179509, 9.324134684552309}, { + 40.78898836464187, 9.673702180867823}, {40.72946927608399, + 9.706424080338618}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{40.638026227600164`, 9.756696863613532}, { + 40.144024408748606`, 10.028284991834468`}, {39.519343554115316`, + 10.387883117452244`}, {38.914945800742, 10.752496557721152`}, { + 38.33083114862863, 11.122125312641192`}, {37.76699959777524, + 11.496769382212364`}, {37.223451148181816`, 11.876428766434667`}, { + 37.10061479935517, 11.966731011072298`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{37.01653803166484, 12.028539432739311`}, { + 36.700185799848356`, 12.261103465308103`}, {36.19547103156106, + 12.650600022169911`}, {35.70757432210614, 13.04472498035733}, { + 35.23649567148359, 13.443478339870362`}, {34.7822350796934, + 13.846860100709005`}, {34.34479254673558, 14.254870262873261`}, { + 33.924168072610144`, 14.66750882636313}, {33.85145100854384, + 14.742649853013779`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{33.77888294186041, 14.817636915578268`}, { + 33.52036165731707, 15.084775791178611`}, {33.133373300856356`, + 15.506671157319705`}, {32.664784329928494`, 16.052416659563114`}, { + 32.22060981863194, 16.605916986572577`}, {31.69018511154382, + 17.315825970278464`}, {31.196741637946694`, 18.037629092949565`}, { + 31.17546955434721, 18.071822146928035`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{31.120347305636216`, 18.160426444517174`}, { + 30.739513687939585`, 18.77258389424782}, {30.31773555162152, + 19.521947913835163`}, {29.966400820102244`, 20.211927889342782`}, { + 29.642298400859875`, 20.915646369943257`}, {29.34525434268344, + 21.633992407772915`}, {29.25258426489671, 21.884187169646278`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.21633973648338, 21.982041745493895`}, { + 29.07695017394571, 22.35837183218061}, {28.83492158582452, + 23.101379548430952`}, {28.619603456347306`, 23.860792926183127`}, { + 28.43099578551407, 24.636611965437133`}, {28.269098573324815`, + 25.428836666192975`}, {28.17163106156758, 26.01573783387062}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{28.15453544340601, 26.118679194333243`}, { + 28.13434409265668, 26.24026152590325}, {28.0271646163868, + 27.073681042020564`}, {27.947560144515183`, 27.929095214544912`}, { + 27.895530677041823`, 28.80650404347629}, {27.876841465838986`, + 29.240676560122132`}, {27.864960647756902`, 29.680932878497988`}, { + 27.878765470837422`, 30.278241465498656`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{27.881176562902063`, 30.382564859276265`}, { + 27.88816919127769, 30.6851226646249}, {27.94692749720561, + 31.72679844192237}, {28.011034837116327`, 32.629532214216155`}, { + 28.10334543037533, 33.564716444154136`}, {28.223859276982616`, + 34.53235113173631}, {28.225070250223766`, 34.540494622633474`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{28.24041896934092, 34.64371090369264}, { + 28.372576376938188`, 35.532436276962684`}, {28.552886852606758`, + 36.57178034826968}, {28.656160902220186`, 37.108727656867075`}, { + 28.768180826353046`, 37.65719181409373}, {28.88894662500533, + 38.21717281994965}, {29.00857095469376, 38.745040664499236`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.032214035756287`, 38.84667689105597}, { + 29.156715845868195`, 39.371685377549284`}, {29.30371926807877, + 39.966216929293}, {29.439764481466057`, 40.53591400049635}, { + 29.61655154169731, 41.17615609747588}, {29.80282569588408, + 41.82928249120391}, {29.998957553744415`, 42.49597690574005}, { + 30.114390647733924`, 42.876882395124895`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{30.144655008685373`, 42.976748567127345`}, { + 30.20531772499636, 43.176923065143924`}, {30.422276819357954`, + 43.872804693475146`}, {30.650205446547247`, 44.584305514793336`}, { + 30.889474216282284`, 45.3121092531581}, {31.188332202941194`, + 46.195123239514565`}, {31.449093099805694`, 46.94138319331566}}]}, + {Arrowheads[{{0.01512400590771079, 1.}}], + ArrowBox[{{31.4835149977021, 47.039893684124664`}, { + 31.507645673424825`, 47.108952186248885`}, {31.848733468619592`, + 48.055929776770334`}, {32.212914429411924`, 49.03838969448818}, { + 32.40407698468418, 49.54365480211115}, {32.57901781468988, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{50., 19.16442344844397}, {49.706477758445516`, + 19.818188959844363`}, {49.389871011808275`, 20.591911864344176`}, { + 49.10206576003426, 21.394857633328577`}, {48.842263402555886`, + 22.22442292313457}, {48.61046393937317, 23.080607733762147`}, { + 48.60773112707541, 23.092445708006146`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{48.58425882886829, 23.194122819841102`}, {48.4066673704861, + 23.963412065211315`}, {48.232079498493334`, 24.87577676974791}, { + 48.087906125993534`, 25.820642699637773`}, {47.97414725298669, + 26.7980098548809}, {47.93171908588279, 27.312104119417537`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{47.92313616399198, 27.416101798747597`}, {47.8908028794728, + 27.807878235477293`}, {47.84608234555539, 28.481352352151365`}, { + 47.81513451712641, 29.170323629221468`}, {47.81940832124887, + 30.156688155653644`}, {47.85184215946753, 31.177306034106316`}, { + 47.87075797698969, 31.58567971682966}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{47.87558633692381, 31.689919204522994`}, {47.9014066349487, + 32.2473537526776}, {47.93834963643672, 32.79782495052778}, { + 47.98339981375637, 33.35859437408766}, {48.03655716690765, + 33.92966202335723}, {48.09782169589055, 34.51102789833649}, { + 48.16719340070508, 35.10269199902545}, {48.24467228135124, + 35.7046543254241}, {48.26433133335004, 35.844242617533}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{48.27888412581179, 35.94757412330828}, {48.33112025730474, + 36.31847463173155}, {48.42739924804128, 36.94571267214686}, { + 48.53350925356087, 37.586368446670065`}, {48.64945027386351, + 38.240441955301144`}, {48.77522230894919, 38.907933198040105`}, { + 48.91082535881792, 39.58884217488695}, {49.00876631543992, + 40.056428791832154`}}]}, + {Arrowheads[{{0.019797137831981355`, 1.}}], + ArrowBox[{{49.03015952525968, 40.15856357742369}, {49.05625942346969, + 40.28316888584167}, {49.21152450290451, 40.99091333090427}, { + 49.35860584479218, 41.680847365252156`}, {49.54477099678277, + 42.434908158843044`}, {49.741444834490466`, 43.203561412992826`}, { + 49.948966193382276`, 43.987394490926995`}, {50., + 44.17397522124705}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{50., 8.00659447809414}, {49.551585268260126`, + 8.20165550436517}, {48.732669981643205`, 8.579218405864788}, { + 47.94184350682008, 8.965896258791744}, {47.17910584379076, + 9.361689063146041}, {46.44445699255524, 9.766596818927678}, { + 46.26759995896502, 9.869919437641153}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{46.177498162532814`, 9.922558302882639}, { + 45.73578254263073, 10.180615410640526`}, {45.05096808353443, + 10.60374072278846}, {44.39001361526635, 11.03597275537148}, { + 43.752919137826474`, 11.477311508389585`}, {43.139684651214814`, + 11.927756981842776`}, {42.72027951485643, 12.254779192543133`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{42.6379874849117, 12.31894464790501}, {42.550310155431376`, + 12.38730917573105}, {41.984795650476144`, 12.855968090054409`}, { + 41.443141136349126`, 13.333733724812856`}, {40.94362640894774, + 13.80452473925534}, {40.46436105413998, 14.284153438354512`}, { + 39.80912140585641, 14.986800383757481`}, {39.62677441807408, + 15.200520524520323`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{39.559043927007586`, 15.279904177964305`}, { + 39.19391878402458, 15.70784981009908}, {38.61820076101852, + 16.447981651547273`}, {38.08141490921222, 17.20787584227002}, { + 37.58248592463907, 17.98708142631499}, {37.17308640126758, + 18.695501630181173`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{37.120873195268885`, 18.785850758420242`}, { + 37.12075680440495, 18.786052159826088`}, {36.696302572492634`, + 19.60682504511563}, {36.309198252884904`, 20.451437084495943`}, { + 36.01905069441263, 21.164590767576065`}, {35.7539728043095, + 21.896471803001962`}, {35.519208237666376`, + 22.632296873992228`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{35.49016766783572, 22.73251837673516}, {35.29770815368151, + 23.409533715600624`}, {35.10741095913884, 24.19536008809444}, { + 34.94277647695342, 25.003010809814725`}, {34.803804707125266`, + 25.832485880761478`}, {34.69049564965438, 26.6837853009347}, { + 34.67696841400582, 26.82068624107748}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{34.666707395813475`, 26.924531777138874`}, { + 34.60391999442763, 27.559964950786444`}, {34.54514843133188, + 28.46408071076875}, {34.51418096036715, 29.396132580881627`}, { + 34.51101758153343, 30.356120561125074`}, {34.51735362207428, + 30.930775198570107`}, {34.52193665493144, 31.092959998371985`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{34.52488424551125, 31.19726961232964}, {34.53390395990877, + 31.516460117705645`}, {34.613081163642576`, 32.58280928110656}, { + 34.67414084003737, 33.14181336751139}, {34.726612086621, + 33.69048565203447}, {34.842930430005026`, 34.69718648170021}, { + 34.934365996443184`, 35.34935245291421}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{34.9488546380153, 35.45269297313555}, {34.98946297256155, + 35.742332715856996`}, {35.074059568529485`, 36.279322859619526`}, { + 35.166209714290545`, 36.82592435450482}, {35.265913409844735`, + 37.38213720051288}, {35.37317065519204, 37.9479613976437}, { + 35.48893185528895, 38.525156536649384`}, {35.614147415091956`, + 39.11548220828203}, {35.7122742180686, 39.55518862732703}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{35.73500261170108, 39.657034608971415`}, { + 35.74881733460104, 39.71893841254165}, {35.89294161381621, + 40.33552514942823}, {36.04652025273747, 40.96524241894178}, { + 36.209553251364824`, 41.60809022108229}, {36.38204060969826, + 42.264068555849775`}, {36.563982327737776`, 42.93317742324422}, { + 36.73454281651448, 43.578754746228405`}, {36.77067888812028, + 43.70012306485433}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{36.800456470599016`, 43.8001354612657}, {36.94839100382452, + 44.2969953789721}, {37.1724773347517, 45.02974568203696}, { + 37.40719370125155, 45.77769522427006}, {37.6529319952796, + 46.54153357451852}, {37.91008410879138, 47.32195030162941}, { + 38.0638872958489, 47.77810525815113}}]}, + {Arrowheads[{{0.010772430747056715`, 1.}}], + ArrowBox[{{38.0972275785963, 47.87698705324277}, {38.17904193374241, + 48.11963497444984}, {38.46019736208822, 48.9352771618269}, { + 38.81903635775576, 49.95032318875829}, {38.836973701191006`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{23.470220821913333`, 15.085565547830058`}, { + 22.981366107675314`, 15.518284548499466`}, {22.51639893692169, + 15.947079180848966`}, {22.074405893235802`, 16.371904793283985`}, { + 21.654473560200984`, 16.79271673420994}, {21.25568852140058, + 17.209470352032262`}, {20.87713736041792, 17.62212099515637}, { + 20.52104676307981, 18.033834921251263`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{20.45278368851573, 18.112761067142728`}, { + 20.175251966848197`, 18.433644784931886`}, {19.54114384028032, + 19.226672897579935`}, {18.969702896650194`, 20.00239607954362}, { + 18.455819051893734`, 20.762005077266046`}, {18.07020937629293, + 21.37796775552071}, {18.00638071623046, 21.487912928234255`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{17.95398867495026, 21.578158470310946`}, { + 17.718793488507583`, 21.98328330560478}, {17.398636370309323`, + 22.57909086577481}, {17.108107456015723`, 23.166023290617776`}, { + 16.845675143169853`, 23.74504069512406}, {16.60980782931478, + 24.317103194284048`}, {16.399575590598833`, 24.883052815195416`}, { + 16.237206627866204`, 25.37293915655153}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{16.2053980674546, 25.47230938707473}, {16.045117233213617`, + 26.022835261275823`}, {15.900869356050205`, 26.59921837812327}, { + 15.78019740906542, 27.175178656115946`}, {15.682503269132331`, + 27.752398708975104`}, {15.612922462502699`, 28.286119413998488`}, { + 15.562478980771743`, 28.826173923832307`}, {15.531172823939466`, + 29.37256223847656}, {15.526667513662884`, 29.57719853047741}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{15.524370653873001`, 29.681524501785265`}, { + 15.519003992005867`, 29.92528435793125}, {15.51828034339738, + 30.079992856580102`}, {15.519056007726483`, 30.235480800083707`}, { + 15.55031846211015, 30.846938063698044`}, {15.605096918336777`, + 31.477023789484207`}, {15.672286136286775`, 32.118324809133796`}, { + 15.764296877683512`, 32.782056416510244`}, {15.88261608950664, + 33.472327519599645`}, {15.954143042595671`, + 33.825236574737076`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{15.97487130339802, 33.92750838443228}, {16.02873071873582, + 34.19324702638811}, {16.20451650071959, 34.94924342482441}, { + 16.41334975908533, 35.748287993216366`}, {16.662023958756293`, + 36.61085431151899}, {16.952030328464485`, 37.532061136412345`}, { + 17.09255864317092, 37.946257499956985`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{17.12608576403821, 38.04507610154885}, { + 17.287515595341052`, 38.52087807236833}, {17.473608667445955`, + 39.04344333339228}, {17.672626486517135`, 39.58627472385885}, { + 17.886137999878457`, 40.15216237691478}, {18.116035418371467`, + 40.74440994342615}, {18.36332197816409, 41.364908900530885`}, { + 18.60172543837519, 41.94875368701877}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{18.641408767784313`, 42.04526416382306}, { + 18.914075466319854`, 42.69822689507231}, {19.219548867018837`, + 43.4148288867849}, {19.54642435368911, 44.16724817764269}, { + 19.895705162498594`, 44.95737624478362}, {20.170394327145438`, + 45.5694559640595}, {20.307977928927432`, 45.871953079265694`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{20.35118088123575, 45.96694091409767}, { + 20.461257930489893`, 46.20896096167972}, {20.76929348378262, + 46.877654262768814`}, {21.09549849827426, 47.57729889245131}, { + 21.44087048521547, 48.30965787585175}, {21.806406955856904`, + 49.07649423809468}, {22.127788009699607`, 49.743922946522126`}}]}, + {Arrowheads[{{0.0008629872787197494, 1.}}], + ArrowBox[{{22.173060242135065`, 49.83794214043768}, { + 22.193105421449207`, 49.87957100430463}, {22.251647228996497`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{37.48627654338087, 8.809842802380324}, { + 36.626219069263136`, 9.21585371115884}, {35.80226208661862, + 9.627039379453516}, {35.01285610304464, 10.04302671328968}, { + 34.25645162613851, 10.463442618692657`}, {33.78663623092154, + 10.738527125383836`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{33.696585491948284`, 10.7912532883828}, { + 33.531499163497536`, 10.88791400168778}, {32.94462640124435, + 11.24717935044862}, {32.376469636764234`, 11.608337642631321`}, { + 31.826502929173795`, 11.971296721113163`}, {31.29420033758966, + 12.335964428771419`}, {30.779035921128447`, 12.702248608483362`}, { + 30.280483738906774`, 13.07005710312627}, {30.22840296815164, + 13.109915543313623`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{30.145535284328624`, 13.173335814773386`}, { + 29.798017850041262`, 13.439297755577417`}, {29.37599260236369, + 13.81774248318664}, {28.941039242642436`, 14.192535367333754`}, { + 28.521120294510578`, 14.568576095043651`}, {28.116235757968116`, + 14.945864666316337`}, {27.726385633015052`, 15.324401081151812`}, { + 27.076981316341534`, 15.99698403266353}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{27.004498707194276`, 16.072053701807786`}, { + 26.991788617877116`, 16.085217441511123`}, {26.317329249096773`, + 16.85102517612158}, {25.69710844926041, 17.62179219238419}, { + 25.12522714095442, 18.397486397699954`}, {24.601685324178806`, + 19.178107792068865`}, {24.476263556048252`, + 19.385440305087194`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{24.4222519352974, 19.474725962827325`}, {24.12648299893357, + 19.96365637549093}, {23.744421429858292`, 20.663037850868964`}, { + 23.395450104871276`, 21.36761829633955}, {23.06036026273179, + 22.120782852835685`}, {22.760123381498413`, 22.881453612134287`}, { + 22.63672669637018, 23.23800092580061}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{22.60259811312328, 23.336613418212988`}, { + 22.49387862209047, 23.65075186067304}, {22.260765145427275`, + 24.429798884889625`}, {22.089025944988165`, 25.09846013370916}, { + 21.940365247875135`, 25.777476997508224`}, {21.814783054088192`, + 26.466849476286814`}, {21.712279363627335`, 27.16657757004493}, { + 21.68635092953108, 27.4002194036681}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{21.67484119228529, 27.50393396292935}, { + 21.633149117660903`, 27.879622395429116`}, {21.577687257357237`, + 28.608945069085923`}, {21.545893782716345`, 29.35454559101535}, { + 21.53776869373822, 30.116423961217393`}, {21.5392741412956, + 30.42895785101014}, {21.54481625445728, 30.744776369430802`}, { + 21.609285429293784`, 31.67055681197811}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{21.616534649388687`, 31.774655960208236`}, { + 21.617531093272618`, 31.788964942170228`}, {21.682061597244324`, + 32.340272885302326`}, {21.735322867390412`, 32.879895365729475`}, { + 21.830761850326166`, 33.66274911347372}, {21.951141515156483`, + 34.474479513898956`}, {22.096461861881362`, 35.315086567005174`}, { + 22.211774035222952`, 35.90395917403917}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{22.231827095226194`, 36.00636551485227}, { + 22.266722890500805`, 36.184570272792385`}, {22.465406975195005`, + 37.09010777350419}, {22.695996490144154`, 38.038876211384164`}, { + 22.958491435348257`, 39.03087558643232}, {23.249219889922813`, + 40.05319394567386}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{23.27737268978264, 40.15367568207321}, { + 23.391168625837675`, 40.560731551471335`}, {23.57134009587752, + 41.12982065095849}, {23.76027367554548, 41.71119213444517}, { + 23.95836224087375, 42.3055833267851}, {24.16599866789452, + 42.913731552832004`}, {24.38357583263998, 43.53637413743964}, { + 24.590315868425485`, 44.11499595543403}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{24.625691157055126`, 44.21316750181388}, { + 24.85012387943372, 44.828091681752}, {25.13732960246073, + 45.59660623650886}, {25.443211146227988`, 46.394217482154964`}, { + 25.769079260910146`, 47.2232764622927}, {26.11624469668185, + 48.08613422052446}, {26.125331449227513`, 48.10822628298985}}]}, + {Arrowheads[{{0.009318544673586782, 1.}}], + ArrowBox[{{26.165025892478358`, 48.20473294094269}, { + 26.486018203717755`, 48.985141800452595`}, {26.879710532192508`, + 49.92265024567952}, {26.91283074798475, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{7.380939549637546, 50.}, {7.739938473640906, + 49.550735516622474`}, {8.217865940968393, 49.08735724752728}, { + 8.714360981517045, 48.73862405116805}, {9.251282448099278, + 48.501898103269035`}, {9.815927622112142, 48.39445465182176}, { + 9.92423077255682, 48.386441588483436`}, {10.03368119572553, + 48.38314483829652}, {10.396188183227663`, 48.43740701051539}, { + 10.77402969866314, 48.54381143026198}, {10.949430844116431`, + 48.61092876121355}}]}, + {Arrowheads[{{0.011896609445858982`, 1.}}], + ArrowBox[{{11.046890646469466`, 48.64822180050414}, { + 11.373496363207295`, 48.77319763190089}, {12.016547901203626`, + 49.13599711929082}, {12.713002524091502`, 49.64739883655534}, { + 13.109722656106657`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{14.190613870852335`, 21.989082681500314`}, { + 13.760419804759046`, 22.51401904926761}, {13.371275679548933`, + 22.994973110183707`}, {12.691917071134574`, 23.834948410836674`}, { + 12.120358333625525`, 24.523580848348047`}, {11.867595380330492`, + 24.81506608519778}, {11.632741409547945`, 25.07379556891386}, { + 11.5142160679752, 25.19031122425383}}]}, + {Arrowheads[{{0.013098281174180656`, 1.}}], + ArrowBox[{{11.439800400179545`, 25.263465118482014`}, { + 11.133139147050304`, 25.564926699622447`}, {10.696191592637298`, + 25.895136251624617`}, {10.668499387375153`, 25.912191791166414`}, { + 10.640993637960138`, 25.928579700536275`}, {10.435612375063256`, + 26.01285669135882}, {10.236493365647785`, 26.05887068812279}, { + 9.846791987147515, 26.075293846849068`}, {9.466852803349513, + 25.9432905861258}, {9.083403963254911, 25.666758005267006`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{0.9701099597005121, 50.}, {0.9731407875071092, + 49.893201640121646`}, {0.9955140278346496, 49.110658591026066`}, { + 1.0174858373962665`, 48.342315514907355`}, {1.038928373388392, + 47.58690107203786}, {1.059841635811026, 46.844415262417584`}, { + 1.0802256246641688`, 46.11485808604654}, {1.0881837530036005`, + 45.82762042807017}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{1.0910737713986183`, 45.72330920313297}, { + 1.1000803399478198`, 45.39822954292471}, {1.1194057816619793`, + 44.694529633052106`}, {1.1382019498066474`, 44.003758356428726`}, { + 1.1564688443818238`, 43.32591571305456}, {1.1750794788742331`, + 42.62478462227685}, {1.1929691871918549`, 41.93641205434676}, { + 1.2028816452931017`, 41.55075768148098}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{1.205562895608084, 41.446440881535}, {1.2104984324220909`, + 41.254418747840184`}, {1.2264981435506106`, 40.59671690481822}, { + 1.2413673741773048`, 39.97484246280159}, {1.2554754673414465`, + 39.36280525816519}, {1.268822423043036, 38.76060529090903}, { + 1.2814082412820733`, 38.16824256103309}, {1.2932329220585586`, + 37.58571706853739}, {1.2992655091525593`, 37.27344895707759}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{1.301281054636046, 37.169117171745285`}, { + 1.304296465372491, 37.013028813421926`}, {1.3145988712238716`, + 36.450177795686685`}, {1.3241401396127, 35.89716401533168}, { + 1.3408857395246483`, 34.81737487943436}, {1.3544797406302853`, + 33.77038811840195}, {1.3624579347211427`, 32.99553194595931}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{1.363532315292604, 32.8911862246258}, {1.3649221429296108`, + 32.75620373223443}, {1.3722129464226245`, 31.774821720931826`}, { + 1.3737069851424102`, 31.522552660045047`}, {1.3749900576958953`, + 31.27232977004853}, {1.3759812349625555`, 30.28409045732634}, { + 1.3736539266244303`, 29.326830790810384`}, {1.3717963879300215`, + 28.774913201739423`}, {1.3714913662437465`, + 28.717185341272476`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{1.3709400042085529`, 28.612835545613223`}, { + 1.3689306744469432`, 28.232553377722535`}, {1.3650567861751959`, + 27.699751318759713`}, {1.3601747231147796`, 27.176507024850963`}, { + 1.3473860726279392`, 26.15869173219567}, {1.3305647229864224`, + 25.179107499756654`}, {1.3146727021752485`, + 24.439223030873784`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{1.3124318525091716`, 24.334895841479092`}, { + 1.3102774346454749`, 24.234592655636785`}, {1.2870909680603433`, + 23.321985527938935`}, {1.2610053232310272`, 22.4412861166631}, { + 1.2320205001575268`, 21.59249442180928}, {1.1993699663266277`, + 20.778507775549755`}, {1.1746425776762055`, 20.1631955959647}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{1.1704524234887075`, 20.058928504022386`}, { + 1.167397405979878, 19.98290796224163}, {1.1331388933995155`, + 19.216897999617697`}, {1.096901041590826, 18.479318954809052`}, { + 1.0393175560071022`, 17.414937267260242`}, {0.97970881613222, + 16.407506273963712`}, {0.9470757215035309, 15.890943338590052`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{0.9404966016567355, 15.786799692426383`}, { + 0.9193811647063893, 15.452554588893387`}, {0.85964094446982, + 14.545610826023198`}, {0.8009836839805076, 13.684872161453569`}, { + 0.7434415894066099, 12.870060663928626`}, {0.6876260199035819, + 12.098992286387864`}, {0.6527109424583515, 11.622702526725856`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{0.6450818014200863, 11.518630532120005`}, { + 0.6341483346268778, 11.369482981770775`}, {0.5831665951154305, + 10.679887114918717`}, {0.534579835698731, 10.02886671461697}, { + 0.48861087471807224`, 9.414699229720913}, {0.44548253051474695`, + 8.83566210908592}, {0.36758214368723335`, 7.776349606859256}, { + 0.3375581452637891, 7.3559262088693185`}}]}, + {Arrowheads[{{0.005977184805582084, 1.}}], + ArrowBox[{{0.33012496445705825`, 7.25184003458418}, { + 0.3005475777104635, 6.837670500457238}, {0.24391889382623366`, + 6.007370240696041}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{3.662177501068409, 49.028240396498525`}, { + 3.803583529581349, 48.09430696972094}, {3.9429186269238428`, + 47.198057460364524`}, {4.079993747411388, 46.338021730281355`}, { + 4.214619845359483, 45.51272964132353}, {4.315774016081059, + 44.90573532957899}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{4.33292735095522, 44.802803570840894`}, {4.346607875083623, + 44.72071105534313}, {4.475768790899307, 43.96049583419224}, { + 4.601913547122033, 43.230613839722956`}, {4.724661028457513, + 42.52919567203556}, {4.843699963105929, 41.85451711732192}, { + 4.958946070624479, 41.20532581657145}, {5.050612067722278, + 40.69093444996175}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{5.0689193428094255`, 40.58820165318728}, { + 5.070315070570358, 40.5803694107736}, {5.177722682500765, + 39.978395540917774`}, {5.281084625972898, 39.398151847993404`}, { + 5.380316620543952, 38.83838597298993}, {5.475334385771126, + 38.29784555689677}, {5.607599427641654, 37.530962460156616`}, { + 5.730158280389231, 36.80165762018195}, {5.782890591963492, + 36.47571834971359}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{5.799556429844104, 36.372706536303866`}, { + 5.842812300528163, 36.10534130020226}, {5.945451130566394, + 35.43946364645617}, {6.038018948288843, 34.801320951593844`}, { + 6.120459931480426, 34.18820950826547}, {6.192780431775049, + 33.59829634392677}, {6.255007166286044, 33.02862163997665}, { + 6.326733525694626, 32.23322615113391}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{6.3348837266731115`, 32.129201994420114`}, { + 6.384503346902058, 31.36262169679778}, {6.413678580826118, + 30.577417021797316`}, {6.419703984186642, 29.815516508576927`}, { + 6.418958912917197, 29.714788992390215`}, {6.417807196246605, + 29.614380878041487`}, {6.399272200862874, 29.10477159692873}, { + 6.3703959794303335`, 28.59998786441578}, {6.320700022141414, + 27.960421208352315`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{6.312616031767383, 27.85638355673592}, {6.292517266068536, + 27.59772065797574}, {6.175557890157135, 26.605518909229296`}, { + 6.022005863339529, 25.61536735240541}, {5.883975062146253, + 24.87009674551967}, {5.728252430886634, 24.122298195706552`}, { + 5.641036533116933, 23.74036642895198}}]}, + {Arrowheads[{{0.012709842916010137`, 1.}}], + ArrowBox[{{5.617805444264102, 23.63863393480712}, {5.556330854214666, + 23.36942729486526}, {5.369703216784341, 22.608939634895012`}, { + 5.170150352386805, 21.84142338430829}, {4.9596176371772875`, + 21.06925675539658}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{7.223677525521819, 42.45604326642656}, {7.497133560630535, + 41.94542101834788}, {7.784543577477226, 41.47099433415936}, { + 8.071472584678805, 41.05871777105589}, {8.501269585321605, + 40.554542511029304`}, {8.935099171080322, 40.18135840847174}, { + 9.79142740754636, 39.830545392507595`}, {9.851358910686436, + 39.8227871657933}, {9.91160966135354, 39.81725945125586}, { + 10.165185553735444`, 39.85735712535744}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{10.26825613547345, 39.87365556192083}, { + 10.271050472398839`, 39.87409742731391}, {10.648853098983556`, + 40.01144895832334}, {11.102289170029579`, 40.22969418935258}, { + 11.588243147047937`, 40.56655519199345}, {12.116508120877484`, + 41.03623359794114}, {12.69687718235707, 41.65293103889084}, { + 13.342640093719977`, 42.43815690621982}, {13.405612675925394`, + 42.521353027528946`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{13.468591166752898`, 42.60455695500423}, { + 13.700676052894298`, 42.911175512878344`}, {14.077718426986106`, + 43.43062810440714}, {14.540649561283345`, 44.095373218007374`}, { + 15.044575080856061`, 44.8481740786198}, {15.595943335072297`, + 45.699815949708594`}, {15.819237737291155`, 46.05215417080202}}]}, + {Arrowheads[{{0.009085522653342167, 1.}}], + ArrowBox[{{15.87509731101342, 46.14029548845605}, {15.89143359684925, + 46.166072659014176`}, {16.201202673300102`, 46.66108409473791}, { + 16.52738197112422, 47.18855646435075}, {16.872510701029707`, + 47.75292152902761}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{20.12694150910278, 12.742035321552946`}, { + 19.475309313361567`, 13.106672712330523`}, {18.853322956339937`, + 13.456537053991413`}, {18.258963022182925`, 13.791422784066848`}, { + 17.71175053082192, 14.113317006421621`}, {17.183077090978163`, + 14.419307586081462`}, {16.677991242289075`, 14.709908429218304`}, { + 16.501539787699183`, 14.810404875828599`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{16.41086391515586, 14.862048558818186`}, { + 15.73858231837493, 15.244940905922983`}, {14.881589832640975`, + 15.718313211478819`}, {14.095079858648713`, 16.12992412082897}, { + 13.612015838254463`, 16.36793659886111}, {13.15300527780204, + 16.579761422848595`}, {12.699677697280075`, 16.76466222979054}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{12.603054580667838`, 16.804072345121}, { + 12.356914470045423`, 16.904466645027618`}, {11.624195502125907`, + 17.14325779402543}, {10.94573743961601, 17.299685205508997`}, { + 10.312429348088251`, 17.377299215145282`}, {10.232191143929295`, + 17.38231889691224}, {10.152608909785817`, 17.386050449557032`}, { + 9.811359184231767, 17.37259402369173}, {9.48064527163832, + 17.335479576279525`}, {8.875456256930349, 17.227003907543974`}, { + 8.538691590541408, 17.11767233297943}}]}, + {Arrowheads[{{0.016923601674316276`, 1.}}], + ArrowBox[{{8.43943986827253, 17.0854499885445}, {8.302674686555187, + 17.04104879639124}, {7.75853969360489, 16.784246505361683`}, { + 7.239290411171504, 16.463229296995667`}, {6.743270438669417, + 16.083773147998258`}, {6.267498255044522, 15.656274816438579`}, { + 5.645413566862449, 14.98949921316205}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{36.479716132863196`, 0.4016323505227532}, { + 35.87546906212038, 0.41067147157894923`}, {35.2814318928921, + 0.41969872264618785`}, {34.697407923088, 0.4287077903131379}, { + 34.123200450617716`, 0.43769236116846894`}, {33.55861277339086, + 0.44664612180085017`}, {33.00344818931709, 0.4555627587989509}, { + 32.3061777067387, 0.4669580480252763}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{32.20184038694285, 0.4686632025755976}, { + 31.920601492267284`, 0.47325940824698837`}, {31.27065455267774, + 0.48404207226579526`}, {30.633104443674384`, 0.4947028220270601}, { + 30.007701606745016`, 0.505234380398115}, {29.394196483377435`, + 0.5156294702462919}, {28.792339515059435`, 0.525880814438923}, { + 28.20188114327882, 0.5359811358433402}, {28.02838236709559, + 0.5389586962927787}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{27.924046478658035`, 0.5407492934468509}, { + 27.622571809523382`, 0.5459231573268756}, {27.075457614988743`, + 0.5563205837445278}, {26.525725147222868`, 0.5661582550891151}, { + 25.986642600457774`, 0.5758230722474847}, {24.94042726992993, + 0.5946341440055707}, {23.93681162340521, 0.6127537990187855}, { + 23.750677476741124`, 0.6161293831760191}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{23.646343380069148`, 0.6180215052293723}, { + 22.975795660883612`, 0.6301820372871292}, {22.054029160036304`, + 0.6468462373138664}, {21.168161898534446`, 0.6626737776022614}, { + 20.318193876378043`, 0.6776646581523145}, {19.504125093567083`, + 0.6918188789640256}, {19.472955323276842`, 0.6923513546365635}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{19.36861929415349, 0.6941337353458237}, {18.86388165900055, + 0.702756208634227}, {18.244873342382046`, 0.7130993261897992}, { + 17.26723730956536, 0.7288480725635298}, {16.342410706324333`, + 0.7429515518870157}, {15.467571425333125`, 0.7554165158637226}, { + 15.195075762775167`, 0.7589831373437188}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{15.090733447794502`, 0.7603488454742231}, { + 14.639897359265905`, 0.7662497161971161}, {14.043604128476263`, + 0.773380797882648}, {13.47070993833581, 0.7796253755194875}, { + 12.395118680002474`, 0.7894550186470898}, {11.405799273712331`, + 0.795919387444197}, {10.916867850228805`, 0.7976808819587541}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{10.812517275160651`, 0.7980568303162228}, { + 10.495427408911816`, 0.7991992237750833}, {10.324281086477587`, + 0.7995308600687618}, {10.155927515927576`, 0.7997480120600583}, { + 9.814971458543933, 0.7994846727439558}, {9.48545402611965, + 0.7987519072343788}, {8.700078792955896, 0.7956200578521103}, { + 7.979577289538006, 0.7898617345668076}, {7.318761293014036, + 0.7817477286146144}, {6.712442580532048, 0.7715488312316741}, { + 6.638656763119474, 0.7697755977114633}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.534335631573717, 0.767268534243034}, { + 5.6458847866064135`, 0.7459171299406784}, {4.903257829353509, + 0.7205622578828108}, {4.258261404296697, 0.6925638640323629}, { + 3.2064010428146545`, 0.6320612542363377}, {2.4122560278133154`, + 0.569253782633929}, {2.3660459649395396`, 0.5644851764411436}}]}, + {Arrowheads[{{0.004872495342548926, 1.}}], + ArrowBox[{{2.262245933548732, 0.5537736248500198}, {1.814219003441145, + 0.5075398856906186}, {1.2527186891481723`, + 0.43247365957612666`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{33.284228421357426`, 4.35668445327842}, {32.3548236467046, + 4.525354326233555}, {31.4574447764906, 4.6933871755879535`}, { + 30.590857468477452`, 4.860514984317108}, {29.75382738042721, + 5.026469735396508}, {29.18487102691367, 5.142211378645766}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.08261417107948, 5.163013284547095}, { + 28.945120170101927`, 5.190983411801643}, {28.163501495263645`, + 5.353787996508002}, {27.40773701367442, 5.5146154724910765`}, { + 26.676592383096292`, 5.673197822726358}, {25.697837651698613`, + 5.888866038794643}, {25.00264063250247, 6.043924839235834}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{24.90079202305755, 6.066641454484549}, { + 24.758626133029896`, 6.098350555304389}, {23.856862719588257`, + 6.301259730772988}, {23.01280011722511, 6.50137943286567}, { + 22.196757636330634`, 6.6931614072454595`}, {21.413973045659496`, + 6.87758475761888}, {20.83576072353346, 7.014178966388414}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{20.73420477549139, 7.0381700745641105`}, { + 20.664446345211708`, 7.0546494839859335`}, {19.948177534987263`, + 7.224355586346618}, {19.26186318643962, 7.3862607462924075`}, { + 18.602199871022247`, 7.539922645414778}, {17.96918758873514, + 7.685341283713729}, {17.362826339578294`, 7.822516661189262}, { + 16.784816535282708`, 7.950575932596747}, {16.666932585984405`, + 7.975958396190243}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{16.564919291393842`, 7.997923631927681}, { + 16.229123684760538`, 8.070226263549376}, {15.220516434634007`, + 8.275902753460873}, {14.282481299946859`, 8.450596509954092}, { + 13.408809849892174`, 8.594833807739283}, {12.593293653663034`, + 8.709140921526695}, {12.456062416612525`, 8.724105969130257}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{12.352326150623574`, 8.73541839472742}, { + 11.678164666393682`, 8.808935612241642}, {10.832448207959695`, + 8.868355476245918}, {10.69738135222392, 8.874889307498668}, { + 10.56403984719346, 8.880367009258485}, {10.210638758667116`, + 8.884980790230737}, {9.86901587011006, 8.882132568164712}, { + 9.113633723761886, 8.857554833792474}, {8.41472106320831, + 8.796888172702165}, {8.190022081807298, 8.764485188453454}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{8.086739209386847, 8.749591158817296}, {7.767474971064815, + 8.703551279058951}, {7.1670925299468875`, 8.580962847027996}, { + 6.610544131265691, 8.43194683385523}, {6.09237647956132, + 8.261586362583335}, {5.374377788568465, 7.960988960643618}, { + 4.732639870181266, 7.626415050507472}, {4.210241833388427, + 7.3018665988777}}]}, + {Arrowheads[{{0.013203088989000106`, 1.}}], + ArrowBox[{{4.123313960110224, 7.24425625523851}, {3.644409163090605, + 6.896268822264425}, {3.1873653005643283`, 6.5154543022109275`}, { + 2.781693542612774, 6.132629472051729}, {2.10514849933814, + 5.381565778183589}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{25.270552352601207`, 8.178002954716998}, { + 24.607671521889493`, 8.405565201082126}, {23.968933060077035`, + 8.629162352359591}, {23.35316031645023, 8.848550580614702}, { + 22.759176640295458`, 9.063486057912769}, {22.185805380899122`, + 9.273724956319104}, {21.410379599566216`, 9.56053530264626}, { + 21.341360238016392`, 9.586156042520043}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{21.243531788515007`, 9.622471030092353}, { + 20.667770330847855`, 9.836199963611852}, {19.95598244545731, + 10.10041690650925}, {19.294302193166306`, 10.356105780835886`}, { + 18.654465242412833`, 10.598987789914487`}, {18.04145941641372, + 10.82981801551163}, {17.455284715168958`, 11.048596457627319`}, { + 17.336903254417834`, 11.092348821744688`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{17.23902307807133, 11.128524157715475`}, { + 16.895941138678555`, 11.255323116261549`}, {16.36040748895613, + 11.449794059404466`}, {15.84566256801531, 11.631805355046215`}, { + 14.878538912478481`, 11.9584490038262}, {14.376393423169754`, + 12.118077650687214`}, {13.895231083128445`, 12.262553717369887`}, { + 13.275968534820485`, 12.433677535927297`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{13.174704355775432`, 12.45885358200318}, {12.6682401053037, + 12.583025127698345`}, {12.102885623176297`, 12.701953579426151`}, { + 11.565976007269615`, 12.794191187469032`}, {10.770459427667948`, + 12.888129482114566`}, {10.03216977693193, 12.921162980062356`}, { + 9.928666816444826, 12.921539421395678`}, {9.826233962623142, + 12.920703998279134`}, {9.495000372803677, 12.900796186137324`}, { + 9.174345566929613, 12.868311339607068`}, {9.045750216221387, + 12.849638839928458`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{8.94248194290329, 12.834643921451832`}, {8.49385914976217, + 12.769502305408873`}, {7.859442430027147, 12.615619645837397`}, { + 7.267015142392209, 12.412372820306981`}, {6.712497021525018, + 12.16547128823197}, {6.193609150208173, 11.879610168173011`}, { + 5.70624947745035, 11.563240673539275`}, {5.186719874123697, + 11.154369701133044`}}]}, + {Arrowheads[{{0.00030816743784531044`, 1.}}], + ArrowBox[{{5.104717905716634, 11.089833966601011`}, {5.05417723271208, + 11.05005834268061}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{36.190296044951495`, 2.278988599990219}, { + 35.192676218892515`, 2.369765546014048}, {34.225910718792655`, + 2.460493451038834}, {33.28885886367611, 2.5509943594550206`}, { + 32.38037997256709, 2.6410903156530523`}, {32.03520907481531, + 2.6761591746478217`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{31.93139225916488, 2.686706811464959}, { + 31.499333364489786`, 2.7306033640233744`}, {30.644578358468404`, + 2.8193555489564295`}, {30.04954921020404, 2.8820694891286935`}, { + 29.466241613991087`, 2.9441179678805156`}, {28.894387809846, + 3.005462874619257}, {28.33372003778525, 3.06606609875228}, { + 27.78397053782529, 3.125889529686947}, {27.780560906655122`, + 3.126262721047158}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{27.676829145691617`, 3.137616382202573}, { + 27.244871549982594`, 3.1848950568306202`}, {26.22040292264331, + 3.303552061279532}, {25.229968024299886`, 3.4177179116000556`}, { + 24.27892205462306, 3.528154819644949}, {23.530267123775417`, + 3.615783654985654}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{23.42662343213255, 3.62791497959844}, {23.36726501361283, + 3.6348627854142115`}, {22.494996901269204`, 3.737841808907844}, { + 21.658628200878713`, 3.8367001846125817`}, {20.8546693957279, + 3.9310462070151617`}, {20.08312048581676, 4.0208798761155835`}, { + 19.343981471145298`, 4.106201191913848}, {19.280904109575246`, + 4.113389484966046}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{19.1772239261019, 4.125204873624692}, {18.706497975308356`, + 4.178848780049356}, {18.09167797889866, 4.24761146035275}, { + 17.37483257638206, 4.325604438013289}, {16.68688165632021, + 4.397739431963119}, {16.02782521871311, 4.464016442202238}, { + 15.397663263560764`, 4.524435468730647}, {15.025788482097589`, + 4.558078648041699}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{14.921861665902803`, 4.567480814272791}, { + 14.793781139325171`, 4.579068145107517}, {14.213564194468344`, + 4.6279861048920194`}, {13.65701242899028, 4.6711893480841535`}, { + 13.124125842890981`, 4.708677874683921}, {12.119247816814715`, + 4.767486545988051}, {11.19284931346906, 4.805120729975748}, { + 11.030895920565133`, 4.810058227118876}, {10.8713171668112, + 4.81432972535928}, {10.75601153632908, 4.81593300512951}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{10.651670370117776`, 4.817383828305181}, { + 10.508495403501266`, 4.819374620312647}, {10.157803780771825`, + 4.820943996958636}, {9.346482864974295, 4.815469019032042}, { + 8.599515921588882, 4.7914946268532095`}, {7.911641771615255, + 4.750755480994464}, {7.277599236053081, 4.69498624202813}, { + 6.693851357343197, 4.625608623343333}, {6.488073628743292, + 4.594950115790393}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.384861616594407, 4.579572716712511}, {6.154031611879116, + 4.545181709040498}, {5.386603777370995, 4.39540333541825}, { + 4.711359050168454, 4.226500485928004}, {4.11496450113375, + 4.044650166579768}, {3.5903213200267814`, 3.853707066400027}, { + 2.724368460869932, 3.45983837826572}, {2.4401935092996707`, + 3.2928924492504383`}}]}, + {Arrowheads[{{0.001616949458014049, 1.}}], + ArrowBox[{{2.3502197485019285`, 3.240035035180768}, { + 2.0592537009871386`, 3.069099501116813}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{50., 16.927683874390233`}, {49.9085258402617, + 17.06782331794245}, {49.60134528278074, 17.570553536300356`}, { + 49.30827235130409, 18.08416196275136}, {49.029352030259666`, + 18.60894478811419}, {48.61712579644272, 19.461973258711016`}, { + 48.24046421926981, 20.3446945235371}, {48.12710397795115, + 20.64903818988108}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{48.090680417116744`, 20.74682626722369}, { + 47.89995745562148, 21.25886933172532}, {47.59619566237826, + 22.206258432408568`}, {47.329235224753326`, 23.187797036860847`}, { + 47.09955954529376, 24.20508078664326}, {46.99908807827641, + 24.727986901834374`}, {46.992345173418954`, + 24.767607240761173`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{46.97483758080441, 24.87047933637055}, {46.90839930688091, + 25.260861076319355`}, {46.827647066467435`, 25.804047234418643`}, { + 46.75698519239615, 26.357889300452676`}, {46.69607454392253, + 26.92188897036574}, {46.64475524434011, 27.495854204966165`}, { + 46.603450025066174`, 28.080588325870487`}, {46.572581617518004`, + 28.67689465469524}, {46.56128821779805, 29.020446761880407`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{46.55785978827449, 29.12474167894363}, {46.55257275311288, + 29.285576513056956`}, {46.54384616326808, 29.90743722257217}, { + 46.54682457940089, 30.543280104857413`}, {46.56193073292859, + 31.193908481529217`}, {46.60074066194667, 32.06841127159385}, { + 46.66204374433008, 32.97165599175458}, {46.69130331353067, + 33.294198238671214`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{46.70073087406533, 33.398122754338054`}, { + 46.746739071145974`, 33.90529314913227}, {46.84613542874499, + 34.853367841558395`}, {46.97296994057879, 35.83926225324546}, { + 47.12499487897946, 36.85885011639126}, {47.21045375814236, + 37.38127909226118}, {47.23724112915973, 37.53625602308441}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{47.25501443364049, 37.63908254447873}, { + 47.302210243946966`, 37.912131430995785`}, {47.4002643363933, + 38.45140713259508}, {47.50461603548134, 38.99910619705906}, { + 47.61591469445789, 39.55637347306148}, {47.73480966656976, + 40.124353809276094`}, {47.861300951816936`, 40.703047205702916`}, { + 47.99538855019942, 41.29245366234194}, {48.097844841853195`, + 41.7264198027947}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{48.12182223701982, 41.82797898935725}, {48.13707246171722, + 41.892573179193164`}, {48.28635268637032, 42.5034057562566}, { + 48.44322922415874, 43.12495139353223}, {48.607702075082464`, + 43.757210091020056`}, {48.88518382325472, 44.808648426427176`}, { + 49.03538095657439, 45.35087077467897}, {49.17805395600637, + 45.865930463731004`}}]}, + {Arrowheads[{{0.012644001720598238`, 1.}}], + ArrowBox[{{49.20792368938321, 45.9659072381097}, {49.42363453613884, + 46.66881048528552}, {49.661690982383625`, 47.44452784764029}, { + 49.9309249016575, 48.26676300126804}, {50., 48.482957315927486`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{12.565916046932262`, 20.60570641946029}, {12.2123917131082, + 20.833871506624245`}, {11.876577004601629`, 21.031142440303277`}, { + 10.939149459576333`, 21.45006494135886}, {10.103358364970097`, + 21.607336644331554`}, {10.05034315202163, 21.60943094596297}, { + 9.997619283949339, 21.610451041028742`}, {9.659635899296376, + 21.565111216597902`}, {9.329751950939706, 21.47587622049211}, { + 8.698856689190954, 21.177150711403073`}}]}, + {Arrowheads[{{0.004124750181173024, 1.}}], + ArrowBox[{{8.604543597199726, 21.13249397021794}, {8.361564965429825, + 21.017444896506355`}, {7.895113454608308, + 20.652898851426308`}}]}}}}, {{}, + {RGBColor[1, 0, 0], PointSize[0.03], + PointBox[{{0., 0.}, {10., 30.}}]}, {}}}, {{}, {}, + {RGBColor[0, 1, 0], LineBox[CompressedData[" +1:eJxTTMoPSmViYGAwAWIQrdT/d/E8uYd2DGBg53Bq4u3CF+n8DjC+1152v2fp +8nD+WV4zTpZYAzjfqd/1wHJ/Czg/Vf8XryGvA5zvq5n6UczdBc7fdKW29KSF +B5xvLaS1nqXeB85P/z1p7tKIADg//9hz4/W+QXB+VxSb6t+cEDg/+Xh1mmFG +GJx/kF0yMDsyAs43FGyY9rIkCs5P+Gyr45cTA+cvnHdU5ntvHJy/uc/q9qWg +BDi/ZJdtwFyfRDh//6mlnzqjk+D8THfLvZkRyXD+nBWGW7OzUuD8iZ/3NhaU +p8L5z1aVlmUUpcH5R9wmzWhqSofzGf1vPepvyIDzGRy3MS6ozITzO8S/+15q +z4LzC6KSD31vzobzHzaapNhPzYHzRSbPvNW5MBfOXyagVXl8dh4ivIrkXdVX +58P58xQWyNiGFMD5e2t+MWRcQPAVvdn/KIcXwvlbzmt237yC4Pcc+2egEFsE +508ufpmVcAfBrxGV41eKLIbzV2qynip5gOCzfWGUPBhXAucvN9hYN+85gq+Z +tMrvb24pnH/bc+em0NcI/qXFVbr2xWVw/o/NgTZKnxD8/zuKtrbllcP53gZu +rjVfEfzjsfqZ2cUVcL4Ve8CGrTsR/HUbCr7//4/gAwC5L9RY + "]]}}, {{}, {}, + {RGBColor[0.5, 0, 0.5], LineBox[{{10., 0.}, {10., 400.}}]}}}, + AspectRatio->1, + Frame->True, + ImageMargins->0., + ImageSize->Automatic, + Method->{"TransparentPolygonMesh" -> True}, + PlotRange->{{-1.0878130721773847`, + 51.08781307217738}, {-1.0878130721773847`, 51.08781307217738}}, + PlotRangeClipping->True, + PlotRangePadding->{ + Scaled[0.02], + Scaled[0.02]}]], "Output", + CellChangeTimes->{{3.514691009500609*^9, 3.514691043595607*^9}, { + 3.514691284220406*^9, 3.514691309255802*^9}, 3.514691371020177*^9, { + 3.514691806484208*^9, 3.514691852781773*^9}, {3.5146925917136087`*^9, + 3.514692607901375*^9}, {3.514692651415642*^9, 3.5146927219682283`*^9}, + 3.514694059585609*^9, {3.514694134622994*^9, 3.514694166586899*^9}, { + 3.514694244337266*^9, 3.5146942492190037`*^9}, + 3.620425594083934*^9},ExpressionUUID->"e3f30246-b442-4a43-a6ca-\ +749e247ab6ff"] +}, Open ]], + +Cell["\<\ +In this case, we know that in the top right quadrant, both variables are \ +increasing, so there must be growth of the system. + +Similarly, in the bottom left quadrant, both variables are decreasing, \ +drawing the system toward extinction. + +But in the other two quadrants, predictions are off. For example, in the \ +bottom right, collecting species is decreasing (arrows move left) but \ +detecting species is increasing (arrows move up). The net result is that the \ +system can either cross the purple line first (doomed to extinction) or the \ +green line (growing indefinitely). + +Additional insight can be obtained by finding the eigenvectors along which \ +stretching/shrinking occurs near the equilibrium with both species present:\ +\>", "Text", + CellChangeTimes->{{3.514692810241274*^9, 3.514692840297978*^9}, { + 3.514692939946409*^9, 3.5146931373428993`*^9}, {3.514693383496572*^9, + 3.514693418206933*^9}, {3.514693495690125*^9, 3.514693496816024*^9}, { + 3.6204252932477503`*^9, 3.620425293327175*^9}, {3.787965590277645*^9, + 3.787965591859982*^9}},ExpressionUUID->"1092780b-2bde-4e19-82ee-\ +b6856863f111"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Eigenvectors", "[", "matrixPOLY", "]"}]], "Input", + CellChangeTimes->{{3.5146931401236477`*^9, 3.514693142169458*^9}, { + 3.514693202698778*^9, + 3.5146932047845078`*^9}},ExpressionUUID->"06ecc798-3bbf-49d7-91a3-\ +730569eaa574"], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"-", + FractionBox[ + RowBox[{ + SqrtBox["rd"], " ", "\[Rho]c"}], + RowBox[{ + SqrtBox["rc"], " ", "\[Rho]d"}]]}], ",", "1"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + FractionBox[ + RowBox[{ + SqrtBox["rd"], " ", "\[Rho]c"}], + RowBox[{ + SqrtBox["rc"], " ", "\[Rho]d"}]], ",", "1"}], "}"}]}], "}"}]], "Output",\ + + CellChangeTimes->{3.514693205212873*^9, + 3.620425615887199*^9},ExpressionUUID->"4840a3dc-397f-4ecc-939b-\ +d9780f67caa7"] +}, Open ]], + +Cell["\<\ +We can add and subtract these vectors from the equilibrium to draw the \ +eigenvectors (thick grey and black lines):\ +\>", "Text", + CellChangeTimes->{{3.514693503637001*^9, 3.514693547311564*^9}, { + 3.514693624880456*^9, + 3.514693625912467*^9}},ExpressionUUID->"80e7b0f8-ccb1-4f7a-95d1-\ +456522f7a303"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Show", "[", + RowBox[{"plot4", ",", + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"{", + RowBox[{ + FractionBox["rd", "\[Rho]d"], ",", + FractionBox["rc", "\[Rho]c"]}], "}"}], "-", + RowBox[{"50", + RowBox[{"{", + RowBox[{ + RowBox[{"-", + FractionBox[ + RowBox[{ + SqrtBox["rd"], " ", "\[Rho]c"}], + RowBox[{ + SqrtBox["rc"], " ", "\[Rho]d"}]]}], ",", "1"}], "}"}]}]}], + ",", + RowBox[{ + RowBox[{"{", + RowBox[{ + FractionBox["rd", "\[Rho]d"], ",", + FractionBox["rc", "\[Rho]c"]}], "}"}], "+", + RowBox[{"50", + RowBox[{"{", + RowBox[{ + RowBox[{"-", + FractionBox[ + RowBox[{ + SqrtBox["rd"], " ", "\[Rho]c"}], + RowBox[{ + SqrtBox["rc"], " ", "\[Rho]d"}]]}], ",", "1"}], "}"}]}]}]}], + "}"}], "//.", + RowBox[{"rc", "\[Rule]", "0.6"}]}], "/.", + RowBox[{"rd", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"\[Rho]c", "\[Rule]", "0.02"}]}], "/.", + RowBox[{"\[Rho]d", "\[Rule]", "0.03"}]}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Gray", ",", "Thick"}], "}"}]}]}], "]"}], ",", + "\[IndentingNewLine]", + RowBox[{"ListPlot", "[", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{ + RowBox[{"{", + RowBox[{ + FractionBox["rd", "\[Rho]d"], ",", + FractionBox["rc", "\[Rho]c"]}], "}"}], "-", + RowBox[{"50", + RowBox[{"{", + RowBox[{ + FractionBox[ + RowBox[{ + SqrtBox["rd"], " ", "\[Rho]c"}], + RowBox[{ + SqrtBox["rc"], " ", "\[Rho]d"}]], ",", "1"}], "}"}]}]}], ",", + RowBox[{ + RowBox[{"{", + RowBox[{ + FractionBox["rd", "\[Rho]d"], ",", + FractionBox["rc", "\[Rho]c"]}], "}"}], "+", + RowBox[{"50", + RowBox[{"{", + RowBox[{ + FractionBox[ + RowBox[{ + SqrtBox["rd"], " ", "\[Rho]c"}], + RowBox[{ + SqrtBox["rc"], " ", "\[Rho]d"}]], ",", "1"}], "}"}]}]}]}], + "}"}], "/.", + RowBox[{"rc", "\[Rule]", "0.6"}]}], "/.", + RowBox[{"rd", "\[Rule]", "0.3"}]}], "/.", + RowBox[{"\[Rho]c", "\[Rule]", "0.02"}]}], "/.", + RowBox[{"\[Rho]d", "\[Rule]", "0.03"}]}], ",", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotStyle", "\[Rule]", + RowBox[{"{", + RowBox[{"Black", ",", "Thick"}], "}"}]}]}], "]"}]}], + "\[IndentingNewLine]", "]"}]], "Input", + CellChangeTimes->{{3.5146909556777983`*^9, 3.514691054042715*^9}, { + 3.51469178340476*^9, 3.514691854322139*^9}, {3.514692593586814*^9, + 3.5146926071386013`*^9}, {3.514692647146307*^9, 3.5146927211865273`*^9}, { + 3.5146932285875187`*^9, 3.514693364053667*^9}, {3.514693592192102*^9, + 3.5146936097570457`*^9}, 3.5146940703500357`*^9, {3.5146941902545643`*^9, + 3.514694198572339*^9}, {3.514694256093026*^9, 3.514694258736281*^9}, { + 3.620424834130555*^9, 3.6204248401878433`*^9}, {3.6204249746162033`*^9, + 3.6204249884252567`*^9}, {3.620425620415119*^9, + 3.620425622983164*^9}},ExpressionUUID->"c4b73d2b-2352-4706-b985-\ +b1f0135ce97e"], + +Cell[BoxData[ + GraphicsBox[{{{{{}, { + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{50., 5.255627689465548}, {49.07164643991514, + 5.49929454502681}, {48.101654752431905`, 5.768012892194103}, { + 47.16122726915955, 6.042593697561616}, {46.24934810020415, + 6.322803191864825}, {45.98853990724681, 6.407032564076382}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{45.889238795161646`, 6.43910237843306}, { + 45.36500135567175, 6.608407605839203}, {44.58598393311282, + 6.871537687447511}, {43.826982442039586`, 7.138509574582958}, { + 43.08753418321806, 7.4092143791227985`}, {42.36717645741425, + 7.683543212944289}, {41.95989638425604, 7.844802289610991}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{41.86287349110899, 7.88321767792867}, {41.66544656539418, + 7.9613871879246805`}, {40.981881807923834`, 8.242637415941228}, { + 40.316019485769246`, 8.527185008871188}, {39.70688056766348, + 8.824212865066134}, {39.089918510465075`, 9.118531091403003}, { + 38.489733490114446`, 9.415928906407792}, {38.0742600869078, + 9.62991358440455}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{37.9814901997972, 9.677693621027696}, {37.90632550661159, + 9.716406310080501}, {37.3396945599565, 10.019963302421127`}, { + 36.78984065014919, 10.32659988342967}, {36.25676377718965, + 10.636316053106134`}, {35.740463941077884`, 10.949111811450518`}, { + 35.2409411418139, 11.264987158462816`}, {34.75670439677487, + 11.583629558431436`}, {34.40465234828942, 11.823920403928765`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{34.31846359879082, 11.882747976665446`}, {34.286262723338, + 11.904726475644786`}, {33.829616121503285`, 12.228277910102857`}, { + 33.38676459127073, 12.554283861805654`}, {32.54244674561208, + 13.213659316945424`}, {31.75330918636206, 13.882852841064095`}, { + 31.21003027705684, 14.377806997593897`}, {31.077247248736626`, + 14.506056736923023`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{31.00218964042387, 14.578551835299333`}, { + 30.692638150616993`, 14.877535059126219`}, {29.975257805378966`, + 15.62215230541692}, {29.309812325343447`, 16.37682786720651}, { + 28.69413730331939, 17.141603879322957`}, {28.26741617616755, + 17.723705972626668`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{28.205721092727792`, 17.807865942526753`}, { + 28.12606833211576, 17.916522476594224`}, {27.618068132766822`, + 18.67887970316737}, {27.150334054790395`, 19.452211247189897`}, { + 26.722866098186476`, 20.236517108661797`}, {26.33566426295506, + 21.031797287583075`}, {26.160672214451445`, 21.43732678808643}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{26.119328106854564`, 21.533138314643725`}, { + 25.986887720780615`, 21.840057880820073`}, {25.674695643347604`, + 22.66330498523914}, {25.399088030656024`, 23.501538600840274`}, { + 25.160064882705875`, 24.354758727623476`}, {25.077623137676905`, + 24.67623029415256}, {25.000130980593386`, 25.000173926194417`}, { + 24.90713673871171, 25.517801018623775`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{24.888684934653096`, 25.620507955006886`}, { + 24.849004956355706`, 25.841375735399907`}, {24.729767986718073`, + 26.70365873558932}, {24.630530483798537`, 27.542736266356243`}, { + 24.56160354012163, 28.405466030731965`}, {24.52298715568735, + 29.291848028716487`}, {24.518592434839327`, 29.77335905473906}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{24.517640067189014`, 29.877705961018453`}, { + 24.514681330495694`, 30.2018822603098}, {24.538789509441692`, + 31.141564545156765`}, {24.597415137420363`, 32.11689070290223}, { + 24.690558214431714`, 33.12786073354619}, {24.80165046951396, + 34.0386410847478}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{24.814285052363417`, 34.14222463156119}, { + 24.818218740475743`, 34.17447463708866}, {24.97467432311375, + 35.24437486775083}, {25.07876922741073, 35.820598892969294`}, { + 25.19235185283169, 36.40758751827921}, {25.315708318998553`, + 37.0059586209695}, {25.44912474553326, 37.61633007832912}, { + 25.59288725205775, 38.239319767647004`}, {25.59330124435526, + 38.241025736631784`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{25.617910209544327`, 38.34243373772906}, { + 25.747281958193952`, 38.87554556621209}, {25.940101598568962`, + 39.628438210109316`}, {26.150846742815112`, 40.406028023594665`}, { + 26.380551777227023`, 41.210330103819174`}, {26.630251088099318`, + 42.04335954793386}, {26.730898099824202`, 42.36447915704206}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{26.76210739782475, 42.46405407141579}, { + 26.900979061726613`, 42.90713145308976}, {27.193770084403532`, + 43.803660916437906`}, {27.50965854242469, 44.73496303512932}, { + 27.849678822084716`, 45.70305290631504}, {28.108387715178683`, + 46.414587587559254`}}]}, + {Arrowheads[{{0.017918567746579475`, 1.}}], + ArrowBox[{{28.144045259149596`, 46.51265757997378}, { + 28.216935285765725`, 46.71312916498169}, {28.412055705910014`, + 47.23601123263495}, {28.61516921156907, 47.77136999621915}, { + 28.826524522727077`, 48.319641008522545`}, {29.046370359368215`, + 48.881259822333355`}, {29.27495544147667, 49.45666199043983}, { + 29.493879886714133`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{50., 3.046754492416481}, {49.30691551877229, + 3.1421248170699143`}, {48.549210363966736`, 3.249990429378931}, { + 47.80628351324313, 3.359339012067691}, {47.07786923727012, + 3.4701203299368584`}, {46.36370180671632, 3.582284147787095}, { + 45.87167489311794, 3.662029101277047}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{45.76866777190582, 3.678723915855624}, {45.6633042957297, + 3.695800635187409}, {44.9762365082879, 3.8106364130514456`}, { + 44.30228780980407, 3.9267359231968193`}, {43.641247565691394`, + 4.044043607441145}, {42.99290514136307, 4.162503907602034}, { + 42.35704990223227, 4.282061265497096}, {41.73347121371217, + 4.4026601229439475`}, {41.66063423036925, 4.417142028088762}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{41.55828637224961, 4.437491470158391}, {41.12195844121596, + 4.524244921760202}, {40.522300950156804`, 4.646760103763471}, { + 39.934288105947914`, 4.770150110771365}, {39.35770927400245, + 4.8943593846015}, {38.792353819733584`, 5.019332367071488}, { + 38.23801110855452, 5.145013499998943}, {37.694470505878414`, + 5.271347225201477}, {37.479558112687755`, 5.323145855371648}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{37.37811185657169, 5.3475966421536025`}, { + 36.638953087687874`, 5.525750219702228}, {35.62389307929084, + 5.782090005760034}, {34.64746323451677, 6.039917740144682}, { + 33.708100336221975`, 6.2987927097723135`}, {33.34043127306272, + 6.404343795902534}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{33.240131355765655`, 6.433138073883139}, { + 32.804241167262745`, 6.558274201559078}, {31.93432251049537, + 6.817921502421122}, {31.096781148776145`, 7.077293899274592}, { + 30.290053864961354`, 7.335950679035637}, {29.512577441907304`, + 7.593451128620401}, {29.25733037242637, 7.680680108899937}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.158586035090803`, 7.714425326314875}, { + 28.511300778753974`, 7.9356307371157095`}, {27.5533564203355, + 8.273029929405732}, {26.636332618351013`, 8.605011992601364}, { + 25.783542939708855`, 8.937731817963966}, {25.240519622252435`, + 9.151871130418568}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{25.143443822445573`, 9.190152626550253}, { + 24.960820950146804`, 9.262169306231199}, {24.174196020417014`, + 9.579916239625828}, {23.42366815051949, 9.890972618147854}, { + 22.709237340454223`, 10.195338441797277`}, {22.02708273344312, + 10.492132512118648`}, {21.373383472708078`, 10.780473630656516`}, { + 21.298560537511758`, 10.813967845760393`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{21.203316680414655`, 10.85660341236257}, { + 20.748139558249093`, 11.060361797410883`}, {20.151350990066174`, + 11.331797012381745`}, {19.474857884757967`, 11.643480355238204`}, { + 18.831665723816883`, 11.941936884140334`}, {17.889821661434798`, + 12.37886126421555}, {17.410684364456777`, 12.599672002780904`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{17.315912879115317`, 12.643347504156335`}, { + 17.015519686801376`, 12.781783904480829`}, {16.20218071411488, + 13.150189024441007`}, {15.44322565757358, 13.483560843600925`}, { + 14.54590587797527, 13.85748882834175}, {13.717912173088807`, + 14.174718438279013`}, {13.58614702264218, 14.222698900770094`}, { + 13.470835248789541`, 14.263855968418307`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{13.371651504542532`, 14.296265258562856`}, { + 13.017694469461, 14.410053144819937`}, {12.596846456225402`, + 14.532352313975206`}, {11.859950820294307`, 14.723971973931429`}, { + 11.173288862944805`, 14.855946636067003`}, {10.531131397563858`, + 14.930933414451436`}, {9.92774923753843, 14.951589423154232`}, { + 9.35975694271045, 14.920495792063443`}, {9.276367203284325, + 14.908390923012659`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{9.173098293260882, 14.893400390107127`}, { + 8.821060720795387, 14.842298554977567`}, {8.066659539361678, + 14.637970703786886`}, {7.366263444900198, 14.344221402127282`}, { + 6.711521814512744, 13.973892822186267`}, {6.100322506916809, + 13.537647643011448`}, {5.529251860062621, 13.0468851667233}, { + 5.514332818344818, 13.031918620930668`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{5.4406627207951255`, 12.958013948674845`}, { + 4.996713931940981, 12.512651571945206`}, {4.500855089220485, + 11.945702274813412`}, {4.0404728672678, 11.35632536722847}, { + 3.670711747917073, 10.836353765561283`}, {3.325970938073047, + 10.311000265948131`}, {3.0055039585738204`, 9.785939084975231}, { + 2.9247666496529856`, 9.64479825776259}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{2.872952616238303, 9.55421961902517}, {2.708564330257488, + 9.266844439228795}, {2.4343708708490444`, 8.756721478898363}, { + 2.18212256772314, 8.257050173375378}, {1.9510431961923551`, + 7.771216968048902}, {1.7403565315692708`, 7.302608308308005}, { + 1.3754465083471559`, 6.4199885973137185`}, {1.1337458433457925`, + 5.765980003531753}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{1.0975722251644244`, 5.668099192328073}, { + 1.0779628686587033`, 5.615038983854077}, {0.8387603087711567, + 4.891910419754798}, {0.648172892642414, 4.247745960293024}, { + 0.49777222254129183`, 3.6795828400670922`}, {0.38010712289285203`, + 3.1808485247222476`}, {0.21821852342122994`, 2.3670752012957825`}, { + 0.12319313918665568`, 1.7547993248906482`}, {0.10716134137378217`, + 1.6211922973337174`}}]}, + {Arrowheads[{{0.006901193386245247, 1.}}], + ArrowBox[{{0.09472918763697008, 1.5175842599636071`}, { + 0.07030775321242456, 1.3140590346442143`}, {0.03980150451054112, + 0.982829355931863}, {0.022364466090688092`, 0.7345808087588179}, { + 0.012475050897473553`, 0.5488158092569115}, {0.0070971341252142545`, + 0.41482425570352494`}, {0.004042384116633057, + 0.31351763341181166`}, {0.002296973446982666, + 0.23693643132798137`}, {0.0012989393312688657`, + 0.1790536109198805}, {0.000576397485540716, 0.12064568500470597`}, { + 0.000215303600311363, 0.08121294442028855}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{50., 9.467092475873057}, {49.807348435733154`, + 9.57162462921928}, {49.0682298090966, 9.998001889687844}, { + 48.35637340268402, 10.434920491978248`}, {47.67177921649541, + 10.882380436090495`}, {47.111981052667645`, 11.271838386982596`}, { + 46.57021741408454, 11.669178906329964`}, {46.49514432783939, + 11.726867108256133`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{46.41240090003064, 11.790449409320821`}, { + 46.09485542211006, 12.034459993769223`}, {45.63372685980081, + 12.406100191279108`}, {45.18671336128773, 12.784203076096052`}, { + 44.753696560701755`, 13.168872225456479`}, {44.33455809217379, + 13.560211216596821`}, {43.92917958983478, 13.958323626753511`}, { + 43.53744268781565, 14.363313033162978`}, {43.32671368808493, + 14.592850009817711`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{43.25614274523294, 14.669719547862398`}, { + 43.159229020247324`, 14.77528301306165}, {42.79423229500632, + 15.193942246371215`}, {42.44221455678894, 15.619143012036906`}, { + 42.103159944955785`, 16.051204285830465`}, {41.77705259886748, + 16.49044504352364}, {41.463876657884605`, 16.937184260888166`}, { + 41.163616261367785`, 17.391740913695795`}, {40.87625554867761, + 17.854433977718266`}, {40.779597110659154`, 18.020351310255176`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{40.72706890854821, 18.110517666714856`}, { + 40.601778659174705`, 18.325582428727333`}, {40.221572001861695`, + 19.033996670486225`}, {39.868795929002914`, 19.762457386972137`}, { + 39.543577668418564`, 20.511926077563757`}, {39.24468735117998, + 21.273108248267175`}, {39.02431433389426, 21.913258616073758`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{38.99034756293841, 22.011926961175188`}, { + 38.97392737140676, 22.059625140280357`}, {38.73097965954838, + 22.8690730051566}, {38.51584421560486, 23.701451842895906`}, { + 38.328521039576174`, 24.556761653498278`}, {38.169912156873075`, + 25.437861075016585`}, {38.07895536317184, 26.07935333348483}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{38.06430598757423, 26.182671190841734`}, { + 38.04091959290628, 26.3476087455037}, {37.94154334767579, + 27.28600466495962}, {37.87178342118161, 28.25304883338435}, { + 37.83923092998787, 28.834394700560594`}, {37.817533088819154`, + 29.42701002563941}, {37.82903198982552, 30.345931668700178`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{37.831161711623764`, 30.450252390569048`}, { + 37.8730242934231, 31.452433909680416`}, {37.92994341213175, + 32.463528122199165`}, {38.01781164150515, 33.51246227009787}, { + 38.07335167269113, 34.0511193198147}, {38.136628981543296`, + 34.599236353376526`}, {38.13819831135887, 34.61155807882468}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{38.15138228174712, 34.715073134633116`}, { + 38.20764356806165, 35.15681337078334}, {38.286395432246195`, + 35.723850372035145`}, {38.373748505041405`, 36.30197529694237}, { + 38.47056671739176, 36.892816085315474`}, {38.576850069297265`, + 37.496372737154445`}, {38.69259856075791, 38.11264525245929}, { + 38.8178121917737, 38.741633631229995`}, {38.836633570134346`, + 38.831311895202624`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{38.85806749072204, 38.93343814502343}, {38.95249096234463, + 39.38333787346657}, {39.096634872470716`, 40.03775797916902}, { + 39.250243922151945`, 40.704893948337336`}, {39.39441174651897, + 41.351147680618716`}, {39.57874532800328, 42.0646746932398}, { + 39.7732552602604, 42.79218144770993}, {39.828514777014036`, + 42.9921850001184}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{39.85630504749751, 43.09276772587525}, {39.97829714889914, + 43.53429988322069}, {40.19422659952834, 44.29166193896368}, { + 40.42139921775683, 45.064899554130484`}, {40.66017060919343, + 45.85464466791269}, {40.91089637944697, 46.66152921950189}, { + 41.04903944587308, 47.0924503155271}}]}, + {Arrowheads[{{0.014192803458930205`, 1.}}], + ArrowBox[{{41.08089511278807, 47.19182033283425}, {41.23672796035694, + 47.67792262669803}, {41.408047187287615`, 48.1986055906829}, { + 41.585193469766295`, 48.72799998297205}, {41.76833538121613, + 49.26639624460025}, {41.95764149506027, 49.814084816602296`}, { + 42.02290995321195, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{4.319580651254556, 50.}, {4.327294726395148, + 49.961050346695416`}, {4.508291058260853, 49.090026080138}, { + 4.688673087110341, 48.26216167065276}, {4.868220134920151, + 47.475773065346814`}, {5.046400967307639, 46.728234957370844`}, { + 5.222797279475323, 46.01726431404149}, {5.245261065603621, + 45.930326289162316`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{5.271366838167764, 45.82929326241833}, {5.397357787777473, + 45.34169049371491}, {5.570031208568362, 44.70034285474721}, { + 5.74076625820226, 44.09205075549455}, {5.909511653033442, + 43.51564355431306}, {6.076216109416176, 42.96995060955888}, { + 6.240828343704737, 42.453801279588134`}, {6.452787708843304, + 41.82718241251142}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.48622434252224, 41.72833315665968}, {6.56264038219542, + 41.502423194270456`}, {6.8743513734954655`, 40.65153862457891}, { + 7.176667803504246, 39.89541568114387}, {7.470296158121136, + 39.22832247459571}, {7.754946766863427, 38.64214477799765}, { + 8.031126884354078, 38.130674234466646`}, {8.170608497690745, + 37.91923976141991}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{8.228070877858805, 37.83213488945718}, {8.565683139811934, + 37.320362269449696`}, {9.03648788685305, 36.814490656654584`}, { + 9.504124087901678, 36.509899769853384`}, {9.980663685682348, + 36.40305888896133}, {10.226230151583158`, 36.42459116611594}, { + 10.479717559965424`, 36.497822658764164`}, {10.849610640874653`, + 36.68974939129246}, {11.247205725572076`, 36.99443201211079}, { + 11.519955477592566`, 37.28075142271622}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{11.591930796959485`, 37.3563076088048}, { + 11.950943499452919`, 37.73318166502781}, {12.008786234130866`, + 37.80229313541391}, {12.06742837982083, 37.87358400008452}, { + 12.334747992595185`, 38.226164684386646`}, {12.621569486823308`, + 38.62619322141192}, {12.919844979548898`, 39.05283114060843}, { + 13.241028469269423`, 39.53268782414744}, {13.588734824614159`, + 40.071956126263174`}, {13.966578914212386`, 40.67682890118988}, { + 14.010013795312366`, 40.74825387626535}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{14.064233388003805`, 40.83741339411172}, { + 14.378813248186738`, 41.354713271624746`}, {14.833092344757956`, + 42.118942058422704`}, {15.246751280600575`, 42.82692717567917}, { + 15.698379505284956`, 43.61029155354303}, {16.171574819420517`, + 44.44022392736655}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{16.22310245881298, 44.53096566157733}, {16.45845409577451, + 44.94664303451333}, {16.736462380053844`, 45.43967246921526}, { + 17.02894101591767, 45.960222537391246`}, {17.337924369326622`, + 46.51182656960474}, {17.664553437361693`, 47.09646996590635}, { + 18.009969217103894`, 47.71613812634668}, {18.263697901959542`, + 48.172196966622565`}}]}, + {Arrowheads[{{0.009516783655673752, 1.}}], + ArrowBox[{{18.31443075234337, 48.26338557197518}, {18.37531270563422, + 48.372816450976316`}, {18.761724900033666`, 49.06849033984588}, { + 19.170346797383242`, 49.80514519300596}, {19.278311967134666`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{48.70808172879087, 4.093956838965128}, { + 48.015600704368715`, 4.2266725384361745`}, {47.33631377568077, + 4.361166718624578}, {46.67001711655772, 4.497388816191737}, { + 46.01650690083028, 4.635288267799045}, {45.375579302329086`, + 4.774814510107904}, {44.747030494884804`, 4.915916979779714}, { + 44.62195400884334, 4.9448595216944895`}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{44.520289107875335`, 4.968384652201853}, { + 44.13065665232814, 5.058545113475872}, {43.526253948489796`, + 5.202648347857767}, {42.933618557200425`, 5.348176119586805}, { + 42.35254665229069, 5.495077865324387}, {41.782834407591295`, + 5.643303021731904}, {41.224277996932926`, 5.792801025470751}, { + 40.67667359414625, 5.94352131320233}, {40.47622268155968, + 6.000234620228982}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{40.37581290252111, 6.028643423928659}, { + 40.139817373061945`, 6.095413321588043}, {39.459911962069974`, + 6.293701864208629}, {38.796572043056074`, 6.4936692636423645`}, { + 38.14948481624552, 6.695223355905408}, {37.51833748186357, + 6.898271977013918}, {36.902817240135484`, 7.1027229629840525`}, { + 36.393520684589326`, 7.277318806173719}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{36.29483513929001, 7.311234473907843}, { + 35.717406835542015`, 7.515463373573829}, {35.146891073127144`, + 7.723568470225793}, {34.59075120426723, 7.93270727580401}, { + 34.048674429187514`, 8.142787626324644}, {33.520347948113276`, + 8.353717357803855}, {33.00545896126979, 8.565404306257795}, { + 32.405245970933784`, 8.823052852566216}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{32.309356023355036`, 8.864214750087669}, { + 32.014742271176104`, 8.990681198154508}, {31.07402196070858, + 9.417880990144054}, {30.17918584270716, 9.845633102427938}, { + 29.326707107816212`, 10.272797234454115`}, {28.552052516926214`, + 10.67950785752588}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{28.460229845761305`, 10.729074097524581`}, { + 27.742324461400884`, 11.123793985729197`}, {27.007171886894103`, + 11.546842818976005`}, {26.30787936953296, 11.967736099960934`}, { + 25.64282257782625, 12.386081935682936`}, {25.010377180282784`, + 12.801488433140966`}, {24.888128885413025`, 12.885001004092336`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{24.80196403156696, 12.94386357127988}, { + 24.407850358601106`, 13.213097969285446`}, {23.83293783513804, + 13.620222277448084`}, {23.28459808938979, 14.022723499199762`}, { + 22.761789600852552`, 14.420463776111358`}, {22.26347084902251, + 14.813305249753759`}, {21.788600313395868`, 15.201110061697849`}, { + 21.477426391746473`, 15.464257208364062`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{21.39774665257445, 15.531639127449974`}, { + 21.336136473468812`, 15.583740353514509`}, {20.905037808737546`, + 15.96105826677462}, {20.49376146727513, 16.332634273150287`}, { + 20.100946899490324`, 16.69814490609498}, {19.367630816952396`, + 17.41105498866324}, {18.6989450251215, 18.099958388422962`}, { + 18.39686698830514, 18.42919797856758}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{18.326319375369238`, 18.506088928381377`}, { + 18.088744987995376`, 18.76502497931771}, {17.602254806405167`, + 19.320908039731595`}, {17.15298803393434, 19.85857246085529}, { + 16.73682398254914, 20.378456172700123`}, {16.3514733811197, + 20.88080246971684}, {15.994684674556558`, 21.366052562182006`}, { + 15.71693624414, 21.759880316442757`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{15.65700704782492, 21.84530396883594}, { + 15.358596897028146`, 22.287009177393045`}, {15.075570069813962`, + 22.723859013899304`}, {14.594829123835861`, 23.509699672907118`}, { + 14.179832089842215`, 24.24642089136489}, {13.823430137262502`, + 24.938746513129637`}, {13.580018479139605`, 25.459686307046468`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{13.535844191913988`, 25.554226331387117`}, { + 13.518474435526207`, 25.591400382058378`}, {13.480966901733915`, + 25.67640279313711}, {13.444284613175178`, 25.760778393771126`}, { + 13.275610911300683`, 26.189621036069482`}, {13.127021215791121`, + 26.60550237872598}, {12.867586708200312`, 27.414259588961812`}, { + 12.680065344170375`, 28.1846094265204}, {12.558712089105702`, + 28.93201935880526}, {12.513830615561275`, 29.576719947463232`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{12.506583638809852`, 29.680819251890238`}, { + 12.49834548964454, 29.799156267074707`}, {12.523880352172746`, + 30.686027996236586`}, {12.63837034246668, 31.627799152088937`}, { + 12.852545111510091`, 32.661841593843}, {13.001451961853148`, + 33.22796485133233}, {13.166744083068592`, 33.78194477868995}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{13.197795621150187`, 33.88155821706151}, { + 13.402221224260959`, 34.5018913934377}, {13.659722031857633`, + 35.22418999059383}, {13.964043211601997`, 36.0216307440609}, { + 14.325835946904315`, 36.91495736287581}, {14.53050014474458, + 37.4021432279129}, {14.691507637219605`, 37.777359731358345`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{14.7326568788365, 37.87325511064523}, { + 14.752191427700177`, 37.91877898663597}, {14.991796194513057`, + 38.466690781494705`}, {15.250200843925166`, 39.047704754938785`}, { + 15.63541493674554, 39.89663309831635}, {16.070615644046338`, + 40.83445138669106}, {16.30887934079907, 41.340249155511934`}, { + 16.46576757537701, 41.67024458702501}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{16.510572904798224`, 41.76448717988874}, { + 16.56194172637851, 41.87253528489361}, {16.83057014585352, + 42.43273173293991}, {17.115531944292986`, 43.02226045775469}, { + 17.36145691760367, 43.527251190701676`}, {17.621609851328984`, + 44.05767042414354}, {17.896896837752735`, 44.6151339978141}, { + 18.18822396915872, 45.20125775144718}, {18.344606891439625`, + 45.513949043146454`}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{18.39128309078776, 45.607279189769265`}, { + 18.496497337830743`, 45.81765752477659}, {18.822623036052608`, + 46.46594915753615}, {19.167507156108115`, 47.14774848945969}, { + 19.532055790281067`, 47.864671360281}, {19.839183610360138`, + 48.46567286019579}, {20.162741532737172`, 49.09575387135}, { + 20.28266629551243, 49.32818672560848}}]}, + {Arrowheads[{{0.003123479124210378, 1.}}], + ArrowBox[{{20.330513472909036`, 49.42092200190289}, { + 20.503760459119256`, 49.75670162376452}, {20.629867991294255`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{50., 1.7511359116089673`}, {49.960134284961434`, + 1.7540651154278804`}, {49.22221194306671, 1.8099221158901446`}, { + 48.49665648317355, 1.866465206294774}, {47.783278664612, + 1.923666206718645}, {47.08188924671209, 1.9814969372386337`}, { + 46.392298988803866`, 2.039929217931617}, {45.839598440772846`, + 2.0880315798393907`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{45.73564016087489, 2.0970792256591313`}, { + 45.71431865021737, 2.098934868874471}, {45.04775899028265, + 2.158485710144072}, {44.392430768329746`, 2.2185535618172976`}, { + 43.74799858866116, 2.2791138280660452`}, {43.11415247384506, + 2.340141289741341}, {42.49074131060996, 2.401606831938752}, { + 41.87761398568441, 2.463481339753843}, {41.58055902877077, + 2.494149882712226}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{41.476759504917254`, 2.5048663514405587`}, { + 41.27461938579694, 2.5257356982821815`}, {40.68160639767606, + 2.588340792619332}, {40.098423908050314`, 2.651267507860863}, { + 39.52492080364824, 2.7144867291023376`}, {38.96094597119837, + 2.7779693414393227`}, {38.406348297429226`, 2.841686229967386}, { + 37.86097666906934, 2.9056082797820912`}, {37.32867005149847, + 2.9692294824105367`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{37.22509711996872, 2.9819506099958533`}, { + 36.27870692373057, 3.098314247901725}, {35.26722024390743, + 3.2272769265000725`}, {34.28892882092955, 3.3563449767732725`}, { + 33.34257143554012, 3.4852749694533856`}, {33.086097904959004`, + 3.5212893298954975`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{32.98276049097098, 3.535800109491692}, { + 32.426984021354585`, 3.613842993904198}, {31.54100251198838, + 3.741825139489496}, {30.68346284105696, 3.8689974955730637`}, { + 29.85320094217578, 3.9951361515186856`}, {29.04905274896027, + 4.120017196690148}, {28.854330464681183`, 4.150854827258613}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{28.75126367556069, 4.167177230102966}, { + 28.269854195025882`, 4.243416720451237}, {27.20679901243413, + 4.414611358620885}, {26.18584056161639, 4.581255495348989}, { + 25.20487771691266, 4.742993054384105}, {24.63227596365705, + 4.84267479744279}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{24.529470880009804`, 4.860571686292651}, { + 24.28422135970308, 4.903266106156867}, {23.39410554313743, + 5.057030237105138}, {22.539783081365762`, 5.205175637857531}, { + 21.72125397438806, 5.347702308414046}, {20.93851822220433, + 5.484610248774683}, {20.41711286864374, 5.57555160246802}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{20.314313525703067`, 5.593481436410019}, { + 20.188212975061155`, 5.615475370109662}, {19.466975383205117`, + 5.739873583589205}, {18.774805446636215`, 5.857804889213312}, { + 18.11170316535444, 5.969269286981984}, {17.511607102258267`, + 6.068314585996544}, {16.93367662775631, 6.161354991358417}, { + 16.331925585807774`, 6.255110053401209}, {16.196421903476818`, + 6.275379995241686}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{16.093218951584223`, 6.2908180836880145`}, { + 15.752588791268925`, 6.34177281362546}, {15.195666244139757`, + 6.421343272031169}, {14.66115794442027, 6.493821428618338}, { + 13.651403335580103`, 6.6179793006386465`}, {12.715344213118183`, + 6.71472489398798}, {11.948538853035643`, 6.775970877649539}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{11.844518869704418`, 6.784279121867986}, { + 11.762456164560819`, 6.7908336027833345`}, {10.883040045659525`, + 6.836382153963504}, {10.736207864590448`, 6.841656261576708}, { + 10.591389697545472`, 6.846056752660993}, {10.23713261896957, + 6.849706550621802}, {9.894701809328478, 6.848097646452643}, { + 9.117360737405736, 6.830890765822442}, {8.400166188720421, + 6.786857363461106}, {7.738128133578678, 6.718574564403359}, { + 7.677794488865157, 6.709704537825551}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{7.5745529916176455`, 6.694526359400124}, { + 7.126256542286653, 6.6286194936839244`}, {6.561285704708233, + 6.51910031378486}, {6.037337342598416, 6.3938117171738655`}, { + 5.30157012415421, 6.167715962877219}, {4.649703319574725, + 5.915600277989436}, {4.070293411341426, 5.6461960322187}, { + 3.632676908492608, 5.40620584902936}}]}, + {Arrowheads[{{0.009018488526614476, 1.}}], + ArrowBox[{{3.5420743658215295`, 5.354565090028833}, { + 2.704278109852364, 4.788692615883016}, {2.0432355837584906`, + 4.221255216724478}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{6.520942316078481, 38.929339855472676`}, { + 6.747524110405924, 38.14081512371605}, {6.961001825179257, + 37.41764365197272}, {7.161375460398483, 36.75982544024268}, { + 7.349055095733886, 36.1569686465526}, {7.5244508108557495`, + 35.598681428929154`}, {7.736023597766242, 34.93630054198494}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{7.767774354128731, 34.83689695389763}, {7.838390480458867, + 34.61581572188215}, {8.016510119192894, 34.06190121194002}, { + 8.17713297780455, 33.55444364059277}, {8.445888354660749, + 32.678899313682955`}, {8.651342670652985, 31.94788438137426}, { + 8.800181985406788, 31.320100483888233`}, {8.884484583035121, + 30.819696170423114`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{8.901820243325743, 30.716794961797998`}, { + 8.906353824221085, 30.689884480990816`}, {8.950274465078182, + 30.11185991349578}, {8.933361050030085, 29.552482820019254`}, { + 8.857030721128801, 28.97820923917736}, {8.719082795565011, + 28.360662271193995`}, {8.5173165905294, 27.67146501629304}, { + 8.305589859238136, 27.049375368300986`}, {8.16008913796415, + 26.655289079102204`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{8.123946331127387, 26.557396886521886`}, { + 8.04838929278722, 26.352751901936166`}, {7.744418339148343, + 25.57122665446563}, {7.5747323371208175`, 25.146220186483145`}, { + 7.393337350207783, 24.69723191209402}, {7.004260226696846, + 23.74466442495637}, {6.794018153296074, 23.23298003055406}, { + 6.573963473675769, 22.697986476192686`}, {6.568319785750554, + 22.684272491493292`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{6.528609454919318, 22.587772369871306`}, { + 6.513581441497226, 22.551249580272515`}, {6.266531700514734, + 21.949324744657638`}, {6.011151532141602, 21.32452646794287}, { + 5.615226128836256, 20.350135622059245`}, {5.412497157698578, + 19.84697224659695}, {5.206590673570895, 19.33316356945433}, { + 4.998904656112411, 18.811128860566395`}, {4.962474019194867, + 18.71870887957374}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{4.924206026373197, 18.621627755869785`}, { + 4.790837084982328, 18.28328738986814}, {4.582387960180644, + 17.749639157359567`}, {4.3735572817073605`, 17.210184163040676`}, { + 4.162525160380449, 16.661346305394304`}, {3.9596043015647355`, + 16.12339015968438}, {3.7577578004230445`, 15.582488133377872`}, { + 3.557713612628187, 15.040070667081643`}, {3.4416454168170247`, + 14.719900787821603`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{3.4060807892399114`, 14.621797061493174`}, { + 3.2274111848916682`, 14.128943483027241`}, {2.909215559479851, + 13.229542311586256`}, {2.6070886820923276`, 12.350413885049615`}, { + 2.3249924984286907`, 11.500104935708245`}, {2.147390147086162, + 10.947112548534534`}, {2.060833320365299, 10.67086336691861}}]}, + {Arrowheads[{{0.0034302695058375954`, 1.}}], + ArrowBox[{{2.0296327720313254`, 10.57128571060013}, { + 1.9787952509239446`, 10.409035959386559`}, {1.8193978369665709`, + 9.886948464805657}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{50., 6.874827243658772}, {49.203620389034064`, + 7.163263041922101}, {48.333322841780536`, 7.49686322046547}, { + 47.49223374284091, 7.8382770728481885`}, {46.68035309221518, + 8.187504599070254}, {46.13094238141069, 8.437118439378569}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{46.035936794583485`, 8.480282340104056}, { + 45.89518917003137, 8.544228226829274}, {45.1342502564175, + 8.908130383822861}, {44.39753635137357, 9.27921107005101}, { + 43.685047454899575`, 9.657470285513723}, {42.996783566995525`, + 10.042908030211}, {42.34638784663161, 10.427457718877667`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{42.25769063850247, 10.482422660339001`}, { + 41.69293081689724, 10.835319107309243`}, {41.077341954703, + 11.242292439710209`}, {40.48403073301128, 11.65633346288698}, { + 39.911049783754635`, 12.077331338380796`}, {39.35839910693308, + 12.50528606619166}, {38.86537331414647, 12.90809351978114}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{38.785493966967316`, 12.975223933688156`}, { + 38.3140885705952, 13.382066078764527`}, {37.82242871107889, + 13.83089136352653}, {37.351099123997656`, 14.286673500605577`}, { + 36.90009980935151, 14.74941249000167}, {36.427632965334816`, + 15.268065437920663`}, {35.977437968591566`, 15.79550532888168}, { + 35.85931988760107, 15.942778373419962`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{35.79403123560978, 16.024182155736156`}, { + 35.52930710200576, 16.35424787295483}, {35.10448668176217, + 16.922698621587035`}, {34.70266314735557, 17.50114935904269}, { + 34.323522938280746`, 18.089891869586193`}, {33.96657014313624, + 18.688693750370863`}, {33.63145473123757, 19.297741948238876`}, { + 33.52122594952762, 19.515902511305697`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{33.474166806511974`, 19.609040156288028`}, { + 33.31808196315501, 19.917957271987934`}, {33.026357099458814`, + 20.55026053041572}, {32.73390691361097, 21.25154698730158}, { + 32.46655059539791, 21.96949424418804}, {32.22438463830975, + 22.705098267695945`}, {32.00647627194189, 23.44873138049053}, { + 31.992763310045042`, 23.503343362304825`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{31.967349832051884`, 23.604552744234137`}, { + 31.81419248740453, 24.21450310970032}, {31.64729205097233, + 24.999923538773224`}, {31.505774962645294`, 25.804992667709243`}, { + 31.38964122242342, 26.629710496508377`}, {31.299789965554968`, + 27.47707453405408}, {31.282618054763265`, 27.716284647706317`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{31.275146334243594`, 27.820368062555648`}, { + 31.23712032728819, 28.350082289229803`}, {31.201632307623083`, + 29.248733762035556`}, {31.193325906559647`, 30.17302895247133}, { + 31.196237980568633`, 30.68944518677864}, {31.207823904826466`, + 31.214772490868395`}, {31.261258053382626`, 31.99034278318651}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{31.268430496134407`, 32.09444724956137}, { + 31.280624910293685`, 32.27144315217633}, {31.3392793354549, + 32.82572313182294}, {31.389032191645075`, 33.3696252518725}, { + 31.49698521092545, 34.33338576344629}, {31.634158226167248`, + 35.33350954852206}, {31.779002991315153`, 36.23576934593132}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{31.795543296346978`, 36.338801390284885`}, { + 31.80055123737047, 36.36999660709981}, {31.89470524145762, + 36.90187636395193}, {31.996164244535123`, 37.44284693917954}, { + 32.10586027333454, 37.9946721297735}, {32.22472535458742, + 38.55911573272466}, {32.35275948829376, 39.136177748033035`}, { + 32.48996267445358, 39.725858175698605`}, {32.636334913066854`, + 40.32815701572138}, {32.65990111511854, 40.42132368622584}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{32.685490481910925`, 40.52248874027805}, { + 32.791876204133594`, 40.94307426810136}, {32.95658654765381, + 41.57060993283855}, {33.13046594362748, 42.21076400993294}, { + 33.29267330664639, 42.8263650157106}, {33.49789198619859, + 43.51494439793041}, {33.71306370887791, 44.21754049283371}, { + 33.81448092796259, 44.54012309646097}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{33.84577779000505, 44.639670523753274`}, { + 33.93858047002119, 44.93485245058366}, {34.17483426496527, + 45.66757942134339}, {34.422217089046974`, 46.41642055527606}, { + 34.68112093760313, 47.18207500254481}, {34.95193780597058, + 47.96524191331279}, {35.17564521405926, 48.595935001149904`}}]}, + {Arrowheads[{{0.006656836429678303, 1.}}], + ArrowBox[{{35.210529262610564`, 48.694282787148836`}, { + 35.29346894313344, 48.928112697656154`}, {35.6569807278478, + 49.92446064885173}, {35.68510583913165, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{50., 14.317042278784916`}, {49.79846536476008, + 14.537376612102017`}, {49.40644030887509, 14.990385375837368`}, { + 49.028918643930055`, 15.452469502978406`}, {48.665968349402526`, + 15.924071796750399`}, {48.31765740477005, 16.405635060378618`}, { + 47.98405378951019, 16.897602097088335`}, {47.665225483100485`, + 17.40041571010482}, {47.51229945365775, 17.659045986922834`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{47.45918741805998, 17.7488696782792}, {47.36124046501849, + 17.914518702653346`}, {46.974658029572694`, 18.62681614545136}, { + 46.61517531489776, 19.361681432778937`}, {46.28306297024403, + 20.120135742567584`}, {45.97570471952488, 20.892307688146037`}, { + 45.747425333746826`, 21.54770412339392}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{45.71310149216061, 21.64624882265769}, { + 45.696934760453466`, 21.692663956877354`}, {45.446076469903936`, + 22.518651603932764`}, {45.2231298478763, 23.370270629312262`}, { + 45.02809489437055, 24.247521033015854`}, {44.86210358164024, + 25.153329884018632`}, {44.78154217075229, 25.709302108225703`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{44.76657776427871, 25.81257480739211}, {44.72628788193894, + 26.090624251295694`}, {44.620647795266635`, 27.059404134847036`}, { + 44.545183321623334`, 28.059669534672665`}, {44.50654835123847, + 28.70981216361135}, {44.480885425224315`, 29.374275143590665`}, { + 44.48709091384877, 29.973461198971894`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{44.48817157281706, 30.077806855471895`}, { + 44.49117162165552, 30.367483871780426`}, {44.530404031511395`, + 31.395478307774827`}, {44.58594872962269, 32.4513471914469}, { + 44.625734967197104`, 32.99441429266528}, {44.67353046378401, + 33.547569833471904`}, {44.72933521938342, 34.110813813866756`}, { + 44.74399742622041, 34.24254535558632}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{44.75554082311682, 34.34625617393385}, {44.79314923399534, + 34.684146233849845`}, {44.864972507619754`, 35.267567093421164`}, { + 44.944805040256675`, 35.86107639258071}, {45.03351531846789, + 36.46626178265941}, {45.13197182881522, 37.08471091498816}, { + 45.24017457129864, 37.71642378956696}, {45.35812354591816, + 38.36140040639582}, {45.37962828448109, 38.472252545588915`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{45.39950138644366, 38.57469396139623}, {45.48581875267378, + 39.01964076547473}, {45.62326019156551, 39.691144866803704`}, { + 45.77044786259332, 40.37591271038272}, {45.92738176575725, + 41.0739442962118}, {46.07566535677869, 41.75314698560655}, { + 46.26356793835725, 42.497726228657335`}, {46.30310678749583, + 42.649041366727204`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{46.32948814192834, 42.75000278506376}, {46.46190878508551, + 43.256776460554455`}, {46.6710339134703, 44.03090130459605}, { + 46.891289340018425`, 44.82070438408026}, {47.12302108123667, + 45.62678932230521}, {47.366575153631864`, 46.44975974256904}, { + 47.463059792993334`, 46.76686699581841}}]}, + {Arrowheads[{{0.015764013498501508`, 1.}}], + ArrowBox[{{47.49343530465901, 46.866699416130004`}, { + 47.62229757371081, 47.29021926816991}, {47.78953620961886, + 47.82755288342334}, {47.96255904674318, 48.3734357558464}, { + 48.14153700647821, 48.92815846373074}, {48.32664101021842, + 49.49201158536796}, {48.49624482199345, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{36.66146237085959, 8.263914813368329}, {35.71546705206069, + 8.667343199075988}, {34.81159710940318, 9.075345179120824}, { + 33.948178062770246`, 9.487460304503008}, {33.1232031285105, + 9.902981563513073}, {32.88160788488025, 10.03116467702101}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{32.7894276842507, 10.080072697489191`}, { + 32.33478636062148, 10.321291603608696`}, {31.58143453545975, + 10.742064464540771`}, {30.86165442938186, 11.16497418606019}, { + 30.173952818744354`, 11.589694807917848`}, {29.516836479903773`, + 12.015900369864646`}, {29.21082587198215, 12.224137670834732`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.12455473587262, 12.282844356387516`}, { + 28.888812189216672`, 12.443264911651475`}, {28.288386723039608`, + 12.871462473029224`}, {27.812745077771755`, 13.224225683822695`}, { + 27.352560046544344`, 13.57668358637938}, {26.907364449599033`, + 13.928775227887105`}, {26.476691107177487`, 14.280439655533701`}, { + 25.82647979178595, 14.837166637098147`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{25.7472144643065, 14.905035567499304`}, { + 25.65704246687232, 14.982243057994816`}, {24.929742693607217`, + 15.686807477903953`}, {24.241844748103517`, 16.387224929881725`}, { + 23.60269222552805, 17.084714470171555`}, {23.0122851258808, + 17.77927609877344}, {22.886893790914343`, 17.939385035401497`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{22.822553033364425`, 18.02154007646487}, { + 22.470623449161778`, 18.470909815687385`}, {21.972560967103952`, + 19.159892670674193`}, {21.512951451440298`, 19.846501713494664`}, { + 21.091794902170815`, 20.5307369441488}, {20.709091319295503`, + 21.212598362636598`}, {20.554650334885732`, 21.517176239641298`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{20.507457695744282`, 21.61024631359145}, { + 20.32860457317984, 21.96296812881766}, {19.988119739213047`, + 22.712820832827653`}, {19.600813081410717`, 23.69184470726316}, { + 19.275231798499632`, 24.675144345818538`}, {19.050793405472263`, + 25.511958598471697`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{19.023761188874364`, 25.612747700660506`}, { + 19.009247426095087`, 25.666861987389716`}, {18.800731499812372`, + 26.671139870872633`}, {18.698038643681045`, 27.317662178776402`}, { + 18.61813103801594, 27.974673710954345`}, {18.561008682817057`, + 28.642174467406463`}, {18.526671578084397`, 29.320164448132747`}, { + 18.51893932036319, 29.550413556907138`}, {18.514604880965038`, + 29.74703412180877}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{18.515577538831486`, 29.851354677503736`}, { + 18.53292501704715, 30.5365847327041}, {18.57995578282932, + 31.314368299999444`}, {18.641662638120913`, 32.10582057800698}, { + 18.732721672431342`, 32.9246102774389}, {18.85477093563476, + 33.77497554349018}, {18.89476965370882, 34.00413630365761}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{18.912712308706062`, 34.106933409579284`}, { + 19.00944847760532, 34.66115452135578}, {19.198793648023983`, + 35.587749330379765`}, {19.426477276316493`, 36.5630437853814}, { + 19.561173517589673`, 37.09353545256812}, {19.70778272716713, + 37.640010445114925`}, {19.857486575610498`, 38.17035049938011}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{19.886672783363053`, 38.27053518143277}, { + 20.039153109372382`, 38.78594490575548}, {20.225120811068916`, + 39.387921623582564`}, {20.425414539207225`, 40.01091616623641}, { + 20.64063755832167, 40.6561871585837}, {20.87139313294664, + 41.32499322549109}, {21.119496113481485`, 42.020505826927334`}, { + 21.19765531514149, 42.232515873047646`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{21.23375052915746, 42.33042562424416}, { + 21.387134145976336`, 42.74648498750797}, {21.675469688441716`, + 43.50507217906986}, {21.985665198888142`, 44.298408873449866`}, { + 22.318883135326143`, 45.12863654248485}, {22.676285955766232`, + 45.99789665801166}, {22.766502945160617`, 46.21249256321073}}]}, + {Arrowheads[{{0.019295018806835394`, 1.}}], + ArrowBox[{{22.806944177921398`, 46.308688667846056`}, { + 23.059036118218938`, 46.908330691867164`}, {23.468296080694778`, + 47.86208011588822}, {23.79270785106708, 48.604754647815916`}, { + 24.136415647290978`, 49.379289607909726`}, {24.41602856885353, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{6.065923617017819, 50.}, {6.337651605127494, + 49.366768500200685`}, {6.632376243683451, 48.748239313220616`}, { + 6.931135104593402, 48.18860224396082}, {7.233928187857343, + 47.687857292421306`}, {7.505392647270676, 47.29312017236674}, { + 7.780932135147687, 46.942191372141174`}, {8.188857130920077, + 46.5107445524898}, {8.236416266572492, 46.472146956181426`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{8.317441576773264, 46.40638919647893}, {8.607999853016935, + 46.170580641578525`}, {9.489390127522537, 45.768827737528376`}, { + 10.52700470705095, 45.7723042368643}, {10.627875123563744`, + 45.79428797065904}, {10.72985404873297, 45.82049177984651}, { + 11.118168251342006`, 45.98874585596824}, {11.526542968550174`, + 46.2196702284124}, {12.101508577216016`, 46.595917698652755`}, { + 12.10584355132604, 46.59944102174456}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{12.186821443903355`, 46.66525716541736}, { + 12.721666394581243`, 47.09996139142419}, {13.39746264217288, + 47.74841523623559}, {13.760142510376234`, 48.133026189222115`}, { + 14.139343541517947`, 48.55789316259586}, {14.529824353417094`, + 49.01433124179023}, {14.961286111765588`, 49.551554942682586`}, { + 15.059447679183357`, 49.67842662765621}}]}, + {Arrowheads[{{0.001448163833233887, 1.}}], + ArrowBox[{{15.123303631271027`, 49.76095905302466}, { + 15.308251391971183`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{2.4920982917921206`, 50.}, {2.492355221430933, + 49.99707541494844}, {2.5697093403475773`, 49.12990136806211}, { + 2.6458802042681198`, 48.28654893619036}, {2.72075093018016, + 47.46617217705798}, {2.794204635071296, 46.66792514838975}, { + 2.8661244359291285`, 45.89096190791045}, {2.8705657177562873`, + 45.8431464867968}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{2.880216724716865, 45.7392424834145}, { + 2.9363934497412556`, 45.13443651334489}, {3.0048947934952763`, + 44.39750302241782}, {3.0715115841787903`, 43.67931549285405}, { + 3.1706826577739724`, 42.599660168163545`}, {3.2629039954457433`, + 41.582773909551236`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{3.2721605233403093`, 41.47883405465382}, { + 3.353360181769914, 40.56288082598207}, {3.4361716109979366`, + 39.60003085896253}, {3.5129928471190572`, 38.67130155462539}, { + 3.583601326155475, 37.77446876693039}, {3.6173802773864705`, + 37.319128942476624`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{3.625100262211921, 37.21506364716394}, { + 3.6478796264146296`, 36.907998113178024`}, {3.705654291879761, + 36.069401945963776`}, {3.755235599296461, 35.28186548132726}, { + 3.798540740025106, 34.515700512460796`}, {3.8355697140656977`, + 33.77090703936439}, {3.86629213494708, 33.0481998664068}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{3.869929695191671, 32.94391205481668}, {3.890861572824205, + 32.3428937370531}, {3.9092492790250954`, 31.65459222098092}, { + 3.921485640020906, 30.982580513821492`}, {3.927570655811637, + 30.326858615574814`}, {3.92837020934439, 30.154803638546454`}, { + 3.928748941428379, 29.983747315327125`}, {3.9216617408297934`, + 29.296417945809083`}, {3.9108605450049225`, 28.77076132233014}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{3.908716787294552, 28.66643209269098}, { + 3.9078315846436262`, 28.623352359286947`}, {3.8907521865259196`, + 27.95698378751941}, {3.867174304545133, 27.30400924526106}, { + 3.8373572233377327`, 26.663594477765482`}, {3.8015602275401847`, + 26.034905230286256`}, {3.7600248719971905`, 25.417397198317364`}, { + 3.7131859554292124`, 24.810090633747972`}, {3.6850732969684383`, + 24.49921494158346}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{3.67567510576252, 24.395287765848337`}, {3.62500256903564, + 23.834940193217292`}, {3.5244561774069973`, 22.885828473935085`}, { + 3.413141763048003, 21.96012894071209}, {3.2926543084633773`, + 21.055215058359032`}, {3.1762412267695304`, 20.251880951377164`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{3.1610406659772488`, 20.148643747354644`}, { + 3.030094523850258, 19.307924827513055`}, {2.8909753887887213`, + 18.46597272970803}, {2.7486453140336957`, 17.644318943897805`}, { + 2.60436795946291, 16.84338830972699}, {2.4592654096800084`, + 16.06420430367305}, {2.4537240531095224`, 16.03519411433671}}]}, + {Arrowheads[{{0.013483247334737701`, 1.}}], + ArrowBox[{{2.434145463922294, 15.932696003624075`}, { + 2.31463671838124, 15.307042106172382`}, {2.1717809392628533`, + 14.572176897661388`}, {2.0312107219629225`, 13.860075186099031`}, { + 1.8944329264314093`, 13.1709615938717}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{32.60418249978299, 7.73945746609291}, { + 31.626987959007483`, 8.10203082157432}, {30.694175687271834`, + 8.464613223653483}, {29.80251519835569, 8.82619531000804}, { + 28.95044545716806, 9.186366225633893}, {28.727393557614718`, + 9.284555992463714}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{28.631886696912428`, 9.326599106204439}, { + 28.136405428617955`, 9.544715115526941}, {27.358834077614397`, + 9.900831124683087}, {26.616170369066396`, 10.254303398098234`}, { + 25.906853267882973`, 10.604721080768279`}, {25.229321738973127`, + 10.951673317689128`}, {24.873388103418627`, 11.139818136326847`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{24.781132596104932`, 11.188583956575403`}, { + 24.58104691705507, 11.29434829025012}, {23.95985187509821, + 11.632079984788435`}, {23.364703485388358`, 11.964676253721736`}, { + 22.79456862021134, 12.291944949467686`}, {22.248414151852977`, + 12.613693924443945`}, {21.725206952599088`, 12.929731031068176`}, { + 21.223913894735492`, 13.239864121758039`}, {21.167389770133415`, + 13.275636374687782`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{21.07921325936831, 13.331440378159874`}, { + 20.743501850548018`, 13.543901048931197`}, {19.839576325779618`, + 14.132040108052182`}, {19.004842963267436`, 14.692435484903253`}, { + 18.23297110117612, 15.22460325604074}, {17.615230504942797`, + 15.659368422414197`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{17.5298952053702, 15.719427314354329`}, { + 17.51763007767032, 15.728059498020976`}, {16.922035882888594`, + 16.15137091937015}, {16.364190195685644`, 16.55095396681119}, { + 15.83943758250957, 16.926710666595632`}, {15.345191691387095`, + 17.278586588863227`}, {14.87888084156338, 17.606676657191496`}, { + 14.437933352283583`, 17.91107579515795}, {14.119336084497675`, + 18.125546664851374`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{14.032771390609014`, 18.183819622783712`}, { + 14.020686912711152`, 18.19195455910177}, {13.624512265571033`, + 18.449605907886507`}, {13.162927955817471`, 18.7353171834392}, { + 12.494265459904154`, 19.111856304905178`}, {11.878169376194116`, + 19.408232831903714`}, {11.306653828466967`, 19.62728493439558}, { + 10.771732940502316`, 19.771850782341545`}, {10.703233262099188`, + 19.786080818383116`}, {10.635263880683283`, 19.79905710098755}, { + 10.28047833250874, 19.827527824428625`}, {10.248765140504853`, + 19.82695943576839}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{10.144430644355005`, 19.82508947122885}, { + 9.937333575490864, 19.821377715392483`}, {8.89015653732592, + 19.63427485552094}, {7.924869009184266, 19.13396031501206}, { + 7.464683943297934, 18.78030182013262}, {7.016582902540748, + 18.365397246175977`}, {6.596879459262006, 17.90249235280233}}]}, + {Arrowheads[{{0.018522790985394364`, 1.}}], + ArrowBox[{{6.52678760667327, 17.82518571625086}, {6.39002147396624, + 17.67434179754651}, {5.786165688148222, 16.887014650816926`}, { + 5.206467259413866, 16.023444733800467`}, {4.652377902090347, + 15.103660974310372`}, {4.383974601218351, + 14.616711696950205`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{38.04738862120897, 4.185894000418275}, { + 37.467493807026365`, 4.29117337086192}, {36.89851937346901, + 4.396776813064768}, {36.340285799099576`, 4.502659245591524}, { + 35.79261356248076, 4.608775587006894}, {34.72823501674582, + 4.8215296707622874`}, {33.95039169626236, 4.983394706774173}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{33.84822899744271, 5.004654218153966}, { + 33.703947564765734`, 5.034678412848586}, {32.71831503504209, + 5.247861161783424}, {31.769901256076466`, 5.460717266084436}, { + 30.857270056370425`, 5.67288607426926}, {29.978985264425546`, + 5.884006934855529}, {29.77905654227884, 5.933549318289316}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{29.677768748849527`, 5.958648456849083}, { + 29.13331289014547, 6.0935647441391865`}, {28.31862724110582, + 6.301100562860422}, {27.533654592316132`, 6.506337986203251}, { + 26.777121218785936`, 6.709000609351691}, {26.04775339552477, + 6.908812027489755}, {25.641711890674458`, 7.022336568107484}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{25.541214659495147`, 7.050434439548462}, { + 25.344277397542175`, 7.105495835801455}, {24.66541949984768, + 7.298775629470811}, {24.009905977450824`, 7.488375003681834}, { + 23.148208836877217`, 7.740486277153068}, {22.32209740641028, + 7.983823704355556}, {21.533495492945075`, 8.216870669059556}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{21.433780440426805`, 8.24762825845424}, { + 20.79012690859723, 8.446509549985405}, {20.075158559110577`, + 8.664283510641763}, {19.389703064970227`, 8.87223398651537}, { + 18.733760426176186`, 9.070360977606228}, {18.107330642728453`, + 9.258664483914334}, {17.507291293289878`, 9.43682532109176}, { + 17.43872507382144, 9.45676127246096}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{17.338523344220626`, 9.485895397456012}, { + 16.9305199565233, 9.604524304790578}, {16.377016632428727`, + 9.761761435010788}, {15.846781321006157`, 9.908536711752387}, { + 15.315404779113406`, 10.05079559595937}, {14.805287045410859`, + 10.181549198491028`}, {14.013108261210721`, 10.370643339126197`}, { + 13.296834760644275`, 10.52367668482355}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{13.194373614364062`, 10.543406857001452`}, { + 12.570970589643531`, 10.658715186436451`}, {11.912819404013131`, + 10.75904231444263}, {11.065074496823504`, 10.852201311192127`}, { + 10.28020294029533, 10.894964449119497`}, {10.162866815735214`, + 10.897699965546765`}, {10.046886547930084`, 10.899290285896486`}, { + 9.709117433500413, 10.890658511444546`}, {9.382401999689897, + 10.872341309348814`}, {9.04678046343293, 10.842251332650026`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{8.942846083605277, 10.832933149132677`}, { + 8.671164729309828, 10.808575696653863`}, {8.011025970770946, + 10.699894286596136`}, {7.397584577192774, 10.550854280657987`}, { + 6.826439401694834, 10.366012880321776`}, {6.294943034315532, + 10.14909750592898}, {5.798330137123992, 9.906817514094255}, { + 5.121296735164822, 9.498634570724175}, {5.0538865149316825`, + 9.449398105771877}}]}, + {Arrowheads[{{0.012638712578083364`, 1.}}], + ArrowBox[{{4.969619444643511, 9.387849387513327}, {4.511707966607465, + 9.053390571600833}, {3.962028766022461, 8.584892690184596}, { + 3.468925591271482, 8.101814216812416}, {3.0278376262222397`, + 7.613364237702503}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{49.23421804558305, 0.8316664813545216}, { + 48.51101982045465, 0.8566509582387026}, {47.79915966134927, + 0.8818957332494143}, {47.09833028252699, 0.9073954298493504}, { + 46.40824735226441, 0.9331435098348084}, {45.72877000144163, + 0.9591261745871047}, {45.06299789459429, 0.9852027023781942}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{44.958730302279925`, 0.9893803531077733}, { + 44.40106856163575, 1.0117400639174792`}, {43.75256273441282, + 1.0383436912581903`}, {43.114099010149985`, 1.065126708891007}, { + 42.485536519727304`, 1.0920753181972462`}, {41.86673439402487, + 1.1191757205582245`}, {41.25755176392275, 1.1464141173552584`}, { + 40.78850246109985, 1.1678153501496118`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{40.68425965912677, 1.1725716187523691`}, { + 40.657847760301024`, 1.173776709969665}, {40.067481514039784`, + 1.2012496997827604`}, {39.48631215601908, 1.228819288175862}, { + 38.91419881711899, 1.2564716765302868`}, {38.35100062821959, + 1.2841930662273513`}, {37.79657672020095, 1.3119696586483724`}, { + 36.713460321076866`, 1.367635887312342}, {36.5152831277517, + 1.378156027799674}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{36.41107859458342, 1.3836876750591467`}, { + 35.663704880901335`, 1.4233616472885051`}, {34.64619869176009, + 1.4790351150138743`}, {33.65983004573886, 1.5345444669254624`}, { + 32.703487234923394`, 1.5897778794602806`}, {32.24356066634335, + 1.61697670549179}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{32.13939140664019, 1.6231369966470601`}, { + 31.776058551399444`, 1.6446235290553408`}, {30.876432287252744`, + 1.6989695921476553`}, {30.003496734569026`, 1.7527042451742365`}, { + 29.405692695819834`, 1.789955808501504}, {28.819480003418875`, + 1.8267349197805682`}, {28.244607992947174`, 1.8630193633547578`}, { + 27.973270007730587`, 1.8802336373921977`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{27.86912812585858, 1.8868406256908998`}, { + 27.68082599998575, 1.8987869235674026`}, {27.127883360115614`, + 1.9340153847618324`}, {26.5855294089178, 1.9686825312813758`}, { + 25.552974945282806`, 2.0381397537050145`}, {24.55475397492972, + 2.1046408164156496`}, {23.70412265418931, 2.1614065861825535`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{23.600002986878568`, 2.1683548761392686`}, { + 23.59587978623814, 2.1686300325466927`}, {22.67635237920806, + 2.2301074020981444`}, {21.796171753839484`, 2.289072925070005}, { + 20.95203716839443, 2.3453151883986934`}, {20.14064788113491, + 2.3986227790206285`}, {19.435083526714784`, 2.4442679465269648`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{19.330947785798966`, 2.450970827341683}, { + 18.616105201172488`, 2.496433942144239}, {18.002626383969353`, + 2.5346459778409858`}, {17.410148971334863`, 2.570608221642296}, { + 16.614216322693593`, 2.617129773469813}, {15.855851598895057`, + 2.659202369632701}, {15.164083814979126`, 2.6952386266731256`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{15.059859785893886`, 2.7003866714439924`}, { + 14.444372621614194`, 2.730088259651493}, {13.862994411619322`, + 2.7558393425949537`}, {13.304444661273038`, 2.778325497332481}, { + 12.255830539526233`, 2.8135030221897366`}, {11.291035103044868`, + 2.8362826319066285`}, {10.888438256837626`, 2.8412868139547105`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{10.784095064693158`, 2.842583774757777}, { + 10.402563198500038`, 2.847326124166525}, {10.242401412705563`, + 2.8483009528073273`}, {10.084711198244852`, 2.848888105358699}, { + 9.745923882541744, 2.847501297711473}, {9.41848089887902, + 2.844327527556718}, {8.646481286148136, 2.8316578528546787`}, { + 7.93728238657567, 2.809222879634646}, {7.285830078242592, + 2.7780381648152788`}, {6.687070239229876, 2.7391192653152365`}, { + 6.612878458040452, 2.732291395190102}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.5089663210109405`, 2.7227283605158}, {5.630927116849549, + 2.6419224066125797`}, {4.902061320825722, 2.547617296684414}, { + 4.265843246427178, 2.4439054882570947`}, {3.221378058167581, + 2.220748895938165}, {2.426380730132568, 1.9901834985655629`}, { + 2.4105078953076413`, 1.984243226294471}}]}, + {Arrowheads[{{0.005629882578595802, 1.}}], + ArrowBox[{{2.312776420891829, 1.9476680603654792`}, { + 1.8238352430992246`, 1.7646860188668028`}, {1.2357375630633354`, + 1.4810766224636773`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{5.422804138815669, 49.06237784513235}, { + 5.7180125415408005`, 48.133769060446994`}, {6.014336342928001, + 47.28615002998856}, {6.311698936632197, 46.513273102085286`}, { + 6.610023716308318, 45.80889062506539}, {6.909310681956363, + 45.17300259892887}, {6.912053336794484, 45.16781968758377}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.960860777942236, 45.075586192893226`}, { + 7.209559833576332, 44.605609023675726`}, {7.483906494512723, + 44.146652133038145`}, {7.759958768910425, 43.73929533460663}, { + 8.335785207985936, 43.059172850025035`}, {8.926926102444082, + 42.58849496636557}, {9.847123551312599, 42.28562331774599}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{9.950103394162635, 42.27291046265703}, { + 10.019922948842948`, 42.2709011462738}, {10.382896418236934`, + 42.339410749903585`}, {10.763334442566057`, 42.476789676779525`}, { + 11.26829736297392, 42.714511728431034`}, {11.809766888230172`, + 43.07616914481139}, {12.39763034537957, 43.57653615607823}, { + 13.041775061466872`, 44.23038699238919}, {13.330011975063499`, + 44.55115918224427}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{13.398873335225309`, 44.62954192432216}, { + 13.755564037444334`, 45.05943886363038}, {14.14926552365368, + 45.5570389552587}, {14.563050675026018`, 46.102782747596784`}, { + 15.072901269461736`, 46.80456011431776}, {15.625697769140709`, + 47.59766554212114}, {15.883495936148474`, 47.98090219291252}}]}, + {Arrowheads[{{0.011063788351635493`, 1.}}], + ArrowBox[{{15.941739949700994`, 48.0674863643269}, { + 16.227985067083072`, 48.493011577962676`}, {16.549733044471818`, + 48.98243499482141}, {16.886308056308966`, 49.50151076879809}, { + 17.205344462523815`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{22.222492756922126`, 13.72251761101824}, { + 21.66929228011176, 14.113318870339784`}, {21.142564235439213`, + 14.49672133070915}, {20.640011337705104`, 14.872129011079782`}, { + 20.16065016729063, 15.239479707064227`}, {19.70349730457699, + 15.598711214275042`}, {19.267569329945385`, 15.949761328324776`}, { + 18.90272055134584, 16.25064321163222}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{18.822623251580477`, 16.31752303899174}, { + 18.077300538354766`, 16.953201267633034`}, {17.37014221868529, + 17.57925159667856}, {16.72219233328327, 18.170048746679374`}, { + 16.127672572407757`, 18.72612978363757}, {15.72321280012335, + 19.112124906420206`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{15.647722275241327`, 19.184169090829904`}, { + 15.580804626317798`, 19.248031773555244`}, {15.072466396313434`, + 19.737848990112823`}, {14.603636647296515`, 20.193344972746964`}, { + 14.168525878325624`, 20.615502995050935`}, {13.763917699988866`, + 21.00486932013211}, {13.033859609411712`, 21.688223719336833`}, { + 12.703376992889382`, 21.98358466362569}, {12.618989081820196`, + 22.055645316505284`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{12.539633529628224`, 22.123408729867727`}, { + 12.392201857783952`, 22.24930380646843}, {11.55646217873036, + 22.873509680976852`}, {10.828553749993715`, 23.25916605743531}, { + 10.782732246394643`, 23.27731235231735}, {10.737227466659883`, + 23.294468469578415`}, {10.474773473670641`, 23.357407149545708`}, { + 10.219843328184421`, 23.38669263645188}, {9.72221989622388, + 23.37922827640576}, {9.244038857934463, 23.243058776821357`}, { + 8.811694353927784, 23.00404400122332}}]}, + {Arrowheads[{{0.015757229165579895`, 1.}}], + ArrowBox[{{8.727151169542925, 22.9436239632191}, {8.249087343926496, + 22.546564053748188`}, {7.719829863785956, 21.966740141979948`}, { + 7.1832687862815385`, 21.256369245500245`}, {6.639725907738225, + 20.42673827847845}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{50., 11.46237682901988}, {49.88912467024407, + 11.54287682992053}, {49.25623860318609, 12.033250972594347`}, { + 48.648364699713916`, 12.536329915833266`}, {48.065187743679964`, + 13.052353449233644`}, {47.50641146893203, 13.581532094528852`}, { + 46.97177277180982, 14.124025154692017`}, {46.87881788721517, + 14.225206532213788`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{46.80822049649411, 14.302051781107908`}, {46.461008548653, + 14.679991932696266`}, {46.07297034319253, 15.129707180118553`}, { + 45.69935357310561, 15.587521199686858`}, {45.340201495431835`, + 16.053864744570316`}, {44.995557367210786`, 16.52916856793806}, { + 44.66546444548206, 17.01386342295924}, {44.349965987285245`, + 17.508380062802974`}, {44.28484174168989, 17.617642282146665`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{44.23141494137347, 17.70727910974655}, {44.04910524965994, + 18.013149240638413`}, {43.762925489645724`, 18.528601709634685`}, { + 43.399137500753675`, 19.243569870713735`}, {43.06213999586156, + 19.980034893791803`}, {42.752167766312844`, 20.7390106592554}, { + 42.47604906510501, 21.486080922461145`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{42.443016317651974`, 21.585047099552863`}, { + 42.20981639498403, 22.30945519160593}, {41.98017648554454, + 23.132752563002157`}, {41.778031434135414`, 23.980588437556936`}, { + 41.60338124075667, 24.85296281527026}, {41.4756787296126, + 25.639687107466084`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{41.45895908108163, 25.742690200658583`}, { + 41.457314387332445`, 25.75282250357195}, {41.34091935578689, + 26.68311430989181}, {41.25419614612001, 27.64383823422985}, { + 41.197144758331795`, 28.634994276586063`}, {41.17077797668167, + 29.263550328445145`}, {41.1566170833663, 29.903098093408616`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{41.159225073015406`, 30.0074141801061}, { + 41.18290278128267, 30.916477862011032`}, {41.239470154571414`, + 31.96373594165704}, {41.310524231197896`, 33.00682029690799}, { + 41.41314628077346, 34.08959161499589}, {41.42248237616456, + 34.1718315939104}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{41.43425299715218, 34.27551686931529}, { + 41.476295295417145`, 34.645859885103704`}, {41.54733630329811, + 35.21204989592076}, {41.62626930441633, 35.78816164744705}, { + 41.713094298771836`, 36.37419513968258}, {41.808699349169395`, + 36.97178450283095}, {41.91397251841377, 37.58256386709577}, { + 42.028913806504974`, 38.20653323247704}, {42.066788708726065`, + 38.400197172450326`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{42.08681727815155, 38.50260830593195}, {42.15352321344301, + 38.84369259897476}, {42.28780073922787, 39.49404196658893}, { + 42.43174638385956, 40.15758133531955}, {42.58536014733808, + 40.834310705166615`}, {42.74864202966342, 41.524230076130124`}, { + 42.902547693371, 42.193979072960275`}, {43.002900928586094`, + 42.574297861926645`}}]}, + {Arrowheads[{{0.020000000000000018`, 1.}}], + ArrowBox[{{43.029524445517225`, 42.67519569243077}, { + 43.097046136761335`, 42.931089463945746`}, {43.30192910040782, + 43.68264479179374}, {43.51755478501513, 44.4492725243773}, { + 43.74428139128791, 45.23160012956945}, {43.982467119930845`, + 46.03025507524323}, {44.1835404360481, 46.68623649936296}}]}, + {Arrowheads[{{0.016199078980985673`, 1.}}], + ArrowBox[{{44.21412206270687, 46.78600597347767}, {44.23247017164858, + 46.84586482927169}, {44.49464874714579, 47.679056859527854`}, { + 44.66394023488933, 48.20566914183808}, {44.83892860311367, + 48.74074678767328}, {45.01978687836011, 49.28458485565135}, { + 45.20668808716997, 49.83747840439018}, {45.26251030228074, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{48.5151686627396, 6.445255918115043}, { + 47.649670000756565`, 6.734681197013667}, {46.78858005312277, + 7.037906999039333}, {45.95225028413573, 7.346977339326902}, { + 45.14068069379543, 7.6618922178763755`}, {44.597685680959884`, + 7.883255563383042}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{44.50105568739623, 7.922648814049999}, {44.35387128210187, + 7.9826516346877545`}, {43.59182204905506, 8.309255589761037}, { + 42.85453299465499, 8.641704083096224}, {42.14200411890167, + 8.979997114693315}, {41.45423542179509, 9.324134684552309}, { + 40.78898836464187, 9.673702180867823}, {40.72946927608399, + 9.706424080338618}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{40.638026227600164`, 9.756696863613532}, { + 40.144024408748606`, 10.028284991834468`}, {39.519343554115316`, + 10.387883117452244`}, {38.914945800742, 10.752496557721152`}, { + 38.33083114862863, 11.122125312641192`}, {37.76699959777524, + 11.496769382212364`}, {37.223451148181816`, 11.876428766434667`}, { + 37.10061479935517, 11.966731011072298`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{37.01653803166484, 12.028539432739311`}, { + 36.700185799848356`, 12.261103465308103`}, {36.19547103156106, + 12.650600022169911`}, {35.70757432210614, 13.04472498035733}, { + 35.23649567148359, 13.443478339870362`}, {34.7822350796934, + 13.846860100709005`}, {34.34479254673558, 14.254870262873261`}, { + 33.924168072610144`, 14.66750882636313}, {33.85145100854384, + 14.742649853013779`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{33.77888294186041, 14.817636915578268`}, { + 33.52036165731707, 15.084775791178611`}, {33.133373300856356`, + 15.506671157319705`}, {32.664784329928494`, 16.052416659563114`}, { + 32.22060981863194, 16.605916986572577`}, {31.69018511154382, + 17.315825970278464`}, {31.196741637946694`, 18.037629092949565`}, { + 31.17546955434721, 18.071822146928035`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{31.120347305636216`, 18.160426444517174`}, { + 30.739513687939585`, 18.77258389424782}, {30.31773555162152, + 19.521947913835163`}, {29.966400820102244`, 20.211927889342782`}, { + 29.642298400859875`, 20.915646369943257`}, {29.34525434268344, + 21.633992407772915`}, {29.25258426489671, 21.884187169646278`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.21633973648338, 21.982041745493895`}, { + 29.07695017394571, 22.35837183218061}, {28.83492158582452, + 23.101379548430952`}, {28.619603456347306`, 23.860792926183127`}, { + 28.43099578551407, 24.636611965437133`}, {28.269098573324815`, + 25.428836666192975`}, {28.17163106156758, 26.01573783387062}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{28.15453544340601, 26.118679194333243`}, { + 28.13434409265668, 26.24026152590325}, {28.0271646163868, + 27.073681042020564`}, {27.947560144515183`, 27.929095214544912`}, { + 27.895530677041823`, 28.80650404347629}, {27.876841465838986`, + 29.240676560122132`}, {27.864960647756902`, 29.680932878497988`}, { + 27.878765470837422`, 30.278241465498656`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{27.881176562902063`, 30.382564859276265`}, { + 27.88816919127769, 30.6851226646249}, {27.94692749720561, + 31.72679844192237}, {28.011034837116327`, 32.629532214216155`}, { + 28.10334543037533, 33.564716444154136`}, {28.223859276982616`, + 34.53235113173631}, {28.225070250223766`, 34.540494622633474`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{28.24041896934092, 34.64371090369264}, { + 28.372576376938188`, 35.532436276962684`}, {28.552886852606758`, + 36.57178034826968}, {28.656160902220186`, 37.108727656867075`}, { + 28.768180826353046`, 37.65719181409373}, {28.88894662500533, + 38.21717281994965}, {29.00857095469376, 38.745040664499236`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.032214035756287`, 38.84667689105597}, { + 29.156715845868195`, 39.371685377549284`}, {29.30371926807877, + 39.966216929293}, {29.439764481466057`, 40.53591400049635}, { + 29.61655154169731, 41.17615609747588}, {29.80282569588408, + 41.82928249120391}, {29.998957553744415`, 42.49597690574005}, { + 30.114390647733924`, 42.876882395124895`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{30.144655008685373`, 42.976748567127345`}, { + 30.20531772499636, 43.176923065143924`}, {30.422276819357954`, + 43.872804693475146`}, {30.650205446547247`, 44.584305514793336`}, { + 30.889474216282284`, 45.3121092531581}, {31.188332202941194`, + 46.195123239514565`}, {31.449093099805694`, 46.94138319331566}}]}, + {Arrowheads[{{0.01512400590771079, 1.}}], + ArrowBox[{{31.4835149977021, 47.039893684124664`}, { + 31.507645673424825`, 47.108952186248885`}, {31.848733468619592`, + 48.055929776770334`}, {32.212914429411924`, 49.03838969448818}, { + 32.40407698468418, 49.54365480211115}, {32.57901781468988, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{50., 19.16442344844397}, {49.706477758445516`, + 19.818188959844363`}, {49.389871011808275`, 20.591911864344176`}, { + 49.10206576003426, 21.394857633328577`}, {48.842263402555886`, + 22.22442292313457}, {48.61046393937317, 23.080607733762147`}, { + 48.60773112707541, 23.092445708006146`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{48.58425882886829, 23.194122819841102`}, { + 48.4066673704861, 23.963412065211315`}, {48.232079498493334`, + 24.87577676974791}, {48.087906125993534`, 25.820642699637773`}, { + 47.97414725298669, 26.7980098548809}, {47.93171908588279, + 27.312104119417537`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{47.92313616399198, 27.416101798747597`}, { + 47.8908028794728, 27.807878235477293`}, {47.84608234555539, + 28.481352352151365`}, {47.81513451712641, 29.170323629221468`}, { + 47.81940832124887, 30.156688155653644`}, {47.85184215946753, + 31.177306034106316`}, {47.87075797698969, 31.58567971682966}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{47.87558633692381, 31.689919204522994`}, { + 47.9014066349487, 32.2473537526776}, {47.93834963643672, + 32.79782495052778}, {47.98339981375637, 33.35859437408766}, { + 48.03655716690765, 33.92966202335723}, {48.09782169589055, + 34.51102789833649}, {48.16719340070508, 35.10269199902545}, { + 48.24467228135124, 35.7046543254241}, {48.26433133335004, + 35.844242617533}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{48.27888412581179, 35.94757412330828}, {48.33112025730474, + 36.31847463173155}, {48.42739924804128, 36.94571267214686}, { + 48.53350925356087, 37.586368446670065`}, {48.64945027386351, + 38.240441955301144`}, {48.77522230894919, 38.907933198040105`}, { + 48.91082535881792, 39.58884217488695}, {49.00876631543992, + 40.056428791832154`}}]}, + {Arrowheads[{{0.019797137831981355`, 1.}}], + ArrowBox[{{49.03015952525968, 40.15856357742369}, {49.05625942346969, + 40.28316888584167}, {49.21152450290451, 40.99091333090427}, { + 49.35860584479218, 41.680847365252156`}, {49.54477099678277, + 42.434908158843044`}, {49.741444834490466`, 43.203561412992826`}, { + 49.948966193382276`, 43.987394490926995`}, {50., + 44.17397522124705}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{50., 8.00659447809414}, {49.551585268260126`, + 8.20165550436517}, {48.732669981643205`, 8.579218405864788}, { + 47.94184350682008, 8.965896258791744}, {47.17910584379076, + 9.361689063146041}, {46.44445699255524, 9.766596818927678}, { + 46.26759995896502, 9.869919437641153}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{46.177498162532814`, 9.922558302882639}, { + 45.73578254263073, 10.180615410640526`}, {45.05096808353443, + 10.60374072278846}, {44.39001361526635, 11.03597275537148}, { + 43.752919137826474`, 11.477311508389585`}, {43.139684651214814`, + 11.927756981842776`}, {42.72027951485643, 12.254779192543133`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{42.6379874849117, 12.31894464790501}, { + 42.550310155431376`, 12.38730917573105}, {41.984795650476144`, + 12.855968090054409`}, {41.443141136349126`, 13.333733724812856`}, { + 40.94362640894774, 13.80452473925534}, {40.46436105413998, + 14.284153438354512`}, {39.80912140585641, 14.986800383757481`}, { + 39.62677441807408, 15.200520524520323`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{39.559043927007586`, 15.279904177964305`}, { + 39.19391878402458, 15.70784981009908}, {38.61820076101852, + 16.447981651547273`}, {38.08141490921222, 17.20787584227002}, { + 37.58248592463907, 17.98708142631499}, {37.17308640126758, + 18.695501630181173`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{37.120873195268885`, 18.785850758420242`}, { + 37.12075680440495, 18.786052159826088`}, {36.696302572492634`, + 19.60682504511563}, {36.309198252884904`, 20.451437084495943`}, { + 36.01905069441263, 21.164590767576065`}, {35.7539728043095, + 21.896471803001962`}, {35.519208237666376`, 22.632296873992228`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{35.49016766783572, 22.73251837673516}, {35.29770815368151, + 23.409533715600624`}, {35.10741095913884, 24.19536008809444}, { + 34.94277647695342, 25.003010809814725`}, {34.803804707125266`, + 25.832485880761478`}, {34.69049564965438, 26.6837853009347}, { + 34.67696841400582, 26.82068624107748}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{34.666707395813475`, 26.924531777138874`}, { + 34.60391999442763, 27.559964950786444`}, {34.54514843133188, + 28.46408071076875}, {34.51418096036715, 29.396132580881627`}, { + 34.51101758153343, 30.356120561125074`}, {34.51735362207428, + 30.930775198570107`}, {34.52193665493144, 31.092959998371985`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{34.52488424551125, 31.19726961232964}, {34.53390395990877, + 31.516460117705645`}, {34.613081163642576`, 32.58280928110656}, { + 34.67414084003737, 33.14181336751139}, {34.726612086621, + 33.69048565203447}, {34.842930430005026`, 34.69718648170021}, { + 34.934365996443184`, 35.34935245291421}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{34.9488546380153, 35.45269297313555}, {34.98946297256155, + 35.742332715856996`}, {35.074059568529485`, 36.279322859619526`}, { + 35.166209714290545`, 36.82592435450482}, {35.265913409844735`, + 37.38213720051288}, {35.37317065519204, 37.9479613976437}, { + 35.48893185528895, 38.525156536649384`}, {35.614147415091956`, + 39.11548220828203}, {35.7122742180686, 39.55518862732703}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{35.73500261170108, 39.657034608971415`}, { + 35.74881733460104, 39.71893841254165}, {35.89294161381621, + 40.33552514942823}, {36.04652025273747, 40.96524241894178}, { + 36.209553251364824`, 41.60809022108229}, {36.38204060969826, + 42.264068555849775`}, {36.563982327737776`, 42.93317742324422}, { + 36.73454281651448, 43.578754746228405`}, {36.77067888812028, + 43.70012306485433}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{36.800456470599016`, 43.8001354612657}, { + 36.94839100382452, 44.2969953789721}, {37.1724773347517, + 45.02974568203696}, {37.40719370125155, 45.77769522427006}, { + 37.6529319952796, 46.54153357451852}, {37.91008410879138, + 47.32195030162941}, {38.0638872958489, 47.77810525815113}}]}, + {Arrowheads[{{0.010772430747056715`, 1.}}], + ArrowBox[{{38.0972275785963, 47.87698705324277}, {38.17904193374241, + 48.11963497444984}, {38.46019736208822, 48.9352771618269}, { + 38.81903635775576, 49.95032318875829}, {38.836973701191006`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{23.470220821913333`, 15.085565547830058`}, { + 22.981366107675314`, 15.518284548499466`}, {22.51639893692169, + 15.947079180848966`}, {22.074405893235802`, 16.371904793283985`}, { + 21.654473560200984`, 16.79271673420994}, {21.25568852140058, + 17.209470352032262`}, {20.87713736041792, 17.62212099515637}, { + 20.52104676307981, 18.033834921251263`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{20.45278368851573, 18.112761067142728`}, { + 20.175251966848197`, 18.433644784931886`}, {19.54114384028032, + 19.226672897579935`}, {18.969702896650194`, 20.00239607954362}, { + 18.455819051893734`, 20.762005077266046`}, {18.07020937629293, + 21.37796775552071}, {18.00638071623046, 21.487912928234255`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{17.95398867495026, 21.578158470310946`}, { + 17.718793488507583`, 21.98328330560478}, {17.398636370309323`, + 22.57909086577481}, {17.108107456015723`, 23.166023290617776`}, { + 16.845675143169853`, 23.74504069512406}, {16.60980782931478, + 24.317103194284048`}, {16.399575590598833`, 24.883052815195416`}, { + 16.237206627866204`, 25.37293915655153}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{16.2053980674546, 25.47230938707473}, { + 16.045117233213617`, 26.022835261275823`}, {15.900869356050205`, + 26.59921837812327}, {15.78019740906542, 27.175178656115946`}, { + 15.682503269132331`, 27.752398708975104`}, {15.612922462502699`, + 28.286119413998488`}, {15.562478980771743`, 28.826173923832307`}, { + 15.531172823939466`, 29.37256223847656}, {15.526667513662884`, + 29.57719853047741}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{15.524370653873001`, 29.681524501785265`}, { + 15.519003992005867`, 29.92528435793125}, {15.51828034339738, + 30.079992856580102`}, {15.519056007726483`, 30.235480800083707`}, { + 15.55031846211015, 30.846938063698044`}, {15.605096918336777`, + 31.477023789484207`}, {15.672286136286775`, 32.118324809133796`}, { + 15.764296877683512`, 32.782056416510244`}, {15.88261608950664, + 33.472327519599645`}, {15.954143042595671`, 33.825236574737076`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{15.97487130339802, 33.92750838443228}, {16.02873071873582, + 34.19324702638811}, {16.20451650071959, 34.94924342482441}, { + 16.41334975908533, 35.748287993216366`}, {16.662023958756293`, + 36.61085431151899}, {16.952030328464485`, 37.532061136412345`}, { + 17.09255864317092, 37.946257499956985`}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{17.12608576403821, 38.04507610154885}, { + 17.287515595341052`, 38.52087807236833}, {17.473608667445955`, + 39.04344333339228}, {17.672626486517135`, 39.58627472385885}, { + 17.886137999878457`, 40.15216237691478}, {18.116035418371467`, + 40.74440994342615}, {18.36332197816409, 41.364908900530885`}, { + 18.60172543837519, 41.94875368701877}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{18.641408767784313`, 42.04526416382306}, { + 18.914075466319854`, 42.69822689507231}, {19.219548867018837`, + 43.4148288867849}, {19.54642435368911, 44.16724817764269}, { + 19.895705162498594`, 44.95737624478362}, {20.170394327145438`, + 45.5694559640595}, {20.307977928927432`, 45.871953079265694`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{20.35118088123575, 45.96694091409767}, { + 20.461257930489893`, 46.20896096167972}, {20.76929348378262, + 46.877654262768814`}, {21.09549849827426, 47.57729889245131}, { + 21.44087048521547, 48.30965787585175}, {21.806406955856904`, + 49.07649423809468}, {22.127788009699607`, 49.743922946522126`}}]}, + {Arrowheads[{{0.0008629872787197494, 1.}}], + ArrowBox[{{22.173060242135065`, 49.83794214043768}, { + 22.193105421449207`, 49.87957100430463}, {22.251647228996497`, + 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{37.48627654338087, 8.809842802380324}, { + 36.626219069263136`, 9.21585371115884}, {35.80226208661862, + 9.627039379453516}, {35.01285610304464, 10.04302671328968}, { + 34.25645162613851, 10.463442618692657`}, {33.78663623092154, + 10.738527125383836`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{33.696585491948284`, 10.7912532883828}, { + 33.531499163497536`, 10.88791400168778}, {32.94462640124435, + 11.24717935044862}, {32.376469636764234`, 11.608337642631321`}, { + 31.826502929173795`, 11.971296721113163`}, {31.29420033758966, + 12.335964428771419`}, {30.779035921128447`, 12.702248608483362`}, { + 30.280483738906774`, 13.07005710312627}, {30.22840296815164, + 13.109915543313623`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{30.145535284328624`, 13.173335814773386`}, { + 29.798017850041262`, 13.439297755577417`}, {29.37599260236369, + 13.81774248318664}, {28.941039242642436`, 14.192535367333754`}, { + 28.521120294510578`, 14.568576095043651`}, {28.116235757968116`, + 14.945864666316337`}, {27.726385633015052`, 15.324401081151812`}, { + 27.076981316341534`, 15.99698403266353}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{27.004498707194276`, 16.072053701807786`}, { + 26.991788617877116`, 16.085217441511123`}, {26.317329249096773`, + 16.85102517612158}, {25.69710844926041, 17.62179219238419}, { + 25.12522714095442, 18.397486397699954`}, {24.601685324178806`, + 19.178107792068865`}, {24.476263556048252`, 19.385440305087194`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{24.4222519352974, 19.474725962827325`}, { + 24.12648299893357, 19.96365637549093}, {23.744421429858292`, + 20.663037850868964`}, {23.395450104871276`, 21.36761829633955}, { + 23.06036026273179, 22.120782852835685`}, {22.760123381498413`, + 22.881453612134287`}, {22.63672669637018, 23.23800092580061}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{22.60259811312328, 23.336613418212988`}, { + 22.49387862209047, 23.65075186067304}, {22.260765145427275`, + 24.429798884889625`}, {22.089025944988165`, 25.09846013370916}, { + 21.940365247875135`, 25.777476997508224`}, {21.814783054088192`, + 26.466849476286814`}, {21.712279363627335`, 27.16657757004493}, { + 21.68635092953108, 27.4002194036681}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{21.67484119228529, 27.50393396292935}, { + 21.633149117660903`, 27.879622395429116`}, {21.577687257357237`, + 28.608945069085923`}, {21.545893782716345`, 29.35454559101535}, { + 21.53776869373822, 30.116423961217393`}, {21.5392741412956, + 30.42895785101014}, {21.54481625445728, 30.744776369430802`}, { + 21.609285429293784`, 31.67055681197811}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{21.616534649388687`, 31.774655960208236`}, { + 21.617531093272618`, 31.788964942170228`}, {21.682061597244324`, + 32.340272885302326`}, {21.735322867390412`, 32.879895365729475`}, { + 21.830761850326166`, 33.66274911347372}, {21.951141515156483`, + 34.474479513898956`}, {22.096461861881362`, 35.315086567005174`}, { + 22.211774035222952`, 35.90395917403917}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{22.231827095226194`, 36.00636551485227}, { + 22.266722890500805`, 36.184570272792385`}, {22.465406975195005`, + 37.09010777350419}, {22.695996490144154`, 38.038876211384164`}, { + 22.958491435348257`, 39.03087558643232}, {23.249219889922813`, + 40.05319394567386}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{23.27737268978264, 40.15367568207321}, { + 23.391168625837675`, 40.560731551471335`}, {23.57134009587752, + 41.12982065095849}, {23.76027367554548, 41.71119213444517}, { + 23.95836224087375, 42.3055833267851}, {24.16599866789452, + 42.913731552832004`}, {24.38357583263998, 43.53637413743964}, { + 24.590315868425485`, 44.11499595543403}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{24.625691157055126`, 44.21316750181388}, { + 24.85012387943372, 44.828091681752}, {25.13732960246073, + 45.59660623650886}, {25.443211146227988`, 46.394217482154964`}, { + 25.769079260910146`, 47.2232764622927}, {26.11624469668185, + 48.08613422052446}, {26.125331449227513`, 48.10822628298985}}]}, + {Arrowheads[{{0.009318544673586782, 1.}}], + ArrowBox[{{26.165025892478358`, 48.20473294094269}, { + 26.486018203717755`, 48.985141800452595`}, {26.879710532192508`, + 49.92265024567952}, {26.91283074798475, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{7.380939549637546, 50.}, {7.739938473640906, + 49.550735516622474`}, {8.217865940968393, 49.08735724752728}, { + 8.714360981517045, 48.73862405116805}, {9.251282448099278, + 48.501898103269035`}, {9.815927622112142, 48.39445465182176}, { + 9.92423077255682, 48.386441588483436`}, {10.03368119572553, + 48.38314483829652}, {10.396188183227663`, 48.43740701051539}, { + 10.77402969866314, 48.54381143026198}, {10.949430844116431`, + 48.61092876121355}}]}, + {Arrowheads[{{0.011896609445858982`, 1.}}], + ArrowBox[{{11.046890646469466`, 48.64822180050414}, { + 11.373496363207295`, 48.77319763190089}, {12.016547901203626`, + 49.13599711929082}, {12.713002524091502`, 49.64739883655534}, { + 13.109722656106657`, 50.}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{14.190613870852335`, 21.989082681500314`}, { + 13.760419804759046`, 22.51401904926761}, {13.371275679548933`, + 22.994973110183707`}, {12.691917071134574`, 23.834948410836674`}, { + 12.120358333625525`, 24.523580848348047`}, {11.867595380330492`, + 24.81506608519778}, {11.632741409547945`, 25.07379556891386}, { + 11.5142160679752, 25.19031122425383}}]}, + {Arrowheads[{{0.013098281174180656`, 1.}}], + ArrowBox[{{11.439800400179545`, 25.263465118482014`}, { + 11.133139147050304`, 25.564926699622447`}, {10.696191592637298`, + 25.895136251624617`}, {10.668499387375153`, 25.912191791166414`}, { + 10.640993637960138`, 25.928579700536275`}, {10.435612375063256`, + 26.01285669135882}, {10.236493365647785`, 26.05887068812279}, { + 9.846791987147515, 26.075293846849068`}, {9.466852803349513, + 25.9432905861258}, {9.083403963254911, 25.666758005267006`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{0.9701099597005121, 50.}, {0.9731407875071092, + 49.893201640121646`}, {0.9955140278346496, 49.110658591026066`}, { + 1.0174858373962665`, 48.342315514907355`}, {1.038928373388392, + 47.58690107203786}, {1.059841635811026, 46.844415262417584`}, { + 1.0802256246641688`, 46.11485808604654}, {1.0881837530036005`, + 45.82762042807017}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{1.0910737713986183`, 45.72330920313297}, { + 1.1000803399478198`, 45.39822954292471}, {1.1194057816619793`, + 44.694529633052106`}, {1.1382019498066474`, 44.003758356428726`}, { + 1.1564688443818238`, 43.32591571305456}, {1.1750794788742331`, + 42.62478462227685}, {1.1929691871918549`, 41.93641205434676}, { + 1.2028816452931017`, 41.55075768148098}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{1.205562895608084, 41.446440881535}, {1.2104984324220909`, + 41.254418747840184`}, {1.2264981435506106`, 40.59671690481822}, { + 1.2413673741773048`, 39.97484246280159}, {1.2554754673414465`, + 39.36280525816519}, {1.268822423043036, 38.76060529090903}, { + 1.2814082412820733`, 38.16824256103309}, {1.2932329220585586`, + 37.58571706853739}, {1.2992655091525593`, 37.27344895707759}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{1.301281054636046, 37.169117171745285`}, { + 1.304296465372491, 37.013028813421926`}, {1.3145988712238716`, + 36.450177795686685`}, {1.3241401396127, 35.89716401533168}, { + 1.3408857395246483`, 34.81737487943436}, {1.3544797406302853`, + 33.77038811840195}, {1.3624579347211427`, 32.99553194595931}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{1.363532315292604, 32.8911862246258}, { + 1.3649221429296108`, 32.75620373223443}, {1.3722129464226245`, + 31.774821720931826`}, {1.3737069851424102`, 31.522552660045047`}, { + 1.3749900576958953`, 31.27232977004853}, {1.3759812349625555`, + 30.28409045732634}, {1.3736539266244303`, 29.326830790810384`}, { + 1.3717963879300215`, 28.774913201739423`}, {1.3714913662437465`, + 28.717185341272476`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{1.3709400042085529`, 28.612835545613223`}, { + 1.3689306744469432`, 28.232553377722535`}, {1.3650567861751959`, + 27.699751318759713`}, {1.3601747231147796`, 27.176507024850963`}, { + 1.3473860726279392`, 26.15869173219567}, {1.3305647229864224`, + 25.179107499756654`}, {1.3146727021752485`, 24.439223030873784`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{1.3124318525091716`, 24.334895841479092`}, { + 1.3102774346454749`, 24.234592655636785`}, {1.2870909680603433`, + 23.321985527938935`}, {1.2610053232310272`, 22.4412861166631}, { + 1.2320205001575268`, 21.59249442180928}, {1.1993699663266277`, + 20.778507775549755`}, {1.1746425776762055`, 20.1631955959647}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{1.1704524234887075`, 20.058928504022386`}, { + 1.167397405979878, 19.98290796224163}, {1.1331388933995155`, + 19.216897999617697`}, {1.096901041590826, 18.479318954809052`}, { + 1.0393175560071022`, 17.414937267260242`}, {0.97970881613222, + 16.407506273963712`}, {0.9470757215035309, + 15.890943338590052`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{0.9404966016567355, 15.786799692426383`}, { + 0.9193811647063893, 15.452554588893387`}, {0.85964094446982, + 14.545610826023198`}, {0.8009836839805076, 13.684872161453569`}, { + 0.7434415894066099, 12.870060663928626`}, {0.6876260199035819, + 12.098992286387864`}, {0.6527109424583515, + 11.622702526725856`}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{0.6450818014200863, 11.518630532120005`}, { + 0.6341483346268778, 11.369482981770775`}, {0.5831665951154305, + 10.679887114918717`}, {0.534579835698731, 10.02886671461697}, { + 0.48861087471807224`, 9.414699229720913}, {0.44548253051474695`, + 8.83566210908592}, {0.36758214368723335`, 7.776349606859256}, { + 0.3375581452637891, 7.3559262088693185`}}]}, + {Arrowheads[{{0.005977184805582084, 1.}}], + ArrowBox[{{0.33012496445705825`, 7.25184003458418}, { + 0.3005475777104635, 6.837670500457238}, {0.24391889382623366`, + 6.007370240696041}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{3.662177501068409, 49.028240396498525`}, { + 3.803583529581349, 48.09430696972094}, {3.9429186269238428`, + 47.198057460364524`}, {4.079993747411388, 46.338021730281355`}, { + 4.214619845359483, 45.51272964132353}, {4.315774016081059, + 44.90573532957899}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{4.33292735095522, 44.802803570840894`}, { + 4.346607875083623, 44.72071105534313}, {4.475768790899307, + 43.96049583419224}, {4.601913547122033, 43.230613839722956`}, { + 4.724661028457513, 42.52919567203556}, {4.843699963105929, + 41.85451711732192}, {4.958946070624479, 41.20532581657145}, { + 5.050612067722278, 40.69093444996175}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{5.0689193428094255`, 40.58820165318728}, { + 5.070315070570358, 40.5803694107736}, {5.177722682500765, + 39.978395540917774`}, {5.281084625972898, 39.398151847993404`}, { + 5.380316620543952, 38.83838597298993}, {5.475334385771126, + 38.29784555689677}, {5.607599427641654, 37.530962460156616`}, { + 5.730158280389231, 36.80165762018195}, {5.782890591963492, + 36.47571834971359}}]}, + {Arrowheads[{{0.019999999999999983`, 1.}}], + ArrowBox[{{5.799556429844104, 36.372706536303866`}, { + 5.842812300528163, 36.10534130020226}, {5.945451130566394, + 35.43946364645617}, {6.038018948288843, 34.801320951593844`}, { + 6.120459931480426, 34.18820950826547}, {6.192780431775049, + 33.59829634392677}, {6.255007166286044, 33.02862163997665}, { + 6.326733525694626, 32.23322615113391}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{6.3348837266731115`, 32.129201994420114`}, { + 6.384503346902058, 31.36262169679778}, {6.413678580826118, + 30.577417021797316`}, {6.419703984186642, 29.815516508576927`}, { + 6.418958912917197, 29.714788992390215`}, {6.417807196246605, + 29.614380878041487`}, {6.399272200862874, 29.10477159692873}, { + 6.3703959794303335`, 28.59998786441578}, {6.320700022141414, + 27.960421208352315`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{6.312616031767383, 27.85638355673592}, {6.292517266068536, + 27.59772065797574}, {6.175557890157135, 26.605518909229296`}, { + 6.022005863339529, 25.61536735240541}, {5.883975062146253, + 24.87009674551967}, {5.728252430886634, 24.122298195706552`}, { + 5.641036533116933, 23.74036642895198}}]}, + {Arrowheads[{{0.012709842916010137`, 1.}}], + ArrowBox[{{5.617805444264102, 23.63863393480712}, {5.556330854214666, + 23.36942729486526}, {5.369703216784341, 22.608939634895012`}, { + 5.170150352386805, 21.84142338430829}, {4.9596176371772875`, + 21.06925675539658}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{7.223677525521819, 42.45604326642656}, {7.497133560630535, + 41.94542101834788}, {7.784543577477226, 41.47099433415936}, { + 8.071472584678805, 41.05871777105589}, {8.501269585321605, + 40.554542511029304`}, {8.935099171080322, 40.18135840847174}, { + 9.79142740754636, 39.830545392507595`}, {9.851358910686436, + 39.8227871657933}, {9.91160966135354, 39.81725945125586}, { + 10.165185553735444`, 39.85735712535744}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{10.26825613547345, 39.87365556192083}, { + 10.271050472398839`, 39.87409742731391}, {10.648853098983556`, + 40.01144895832334}, {11.102289170029579`, 40.22969418935258}, { + 11.588243147047937`, 40.56655519199345}, {12.116508120877484`, + 41.03623359794114}, {12.69687718235707, 41.65293103889084}, { + 13.342640093719977`, 42.43815690621982}, {13.405612675925394`, + 42.521353027528946`}}]}, + {Arrowheads[{{0.020000000000000014`, 1.}}], + ArrowBox[{{13.468591166752898`, 42.60455695500423}, { + 13.700676052894298`, 42.911175512878344`}, {14.077718426986106`, + 43.43062810440714}, {14.540649561283345`, 44.095373218007374`}, { + 15.044575080856061`, 44.8481740786198}, {15.595943335072297`, + 45.699815949708594`}, {15.819237737291155`, 46.05215417080202}}]}, + {Arrowheads[{{0.009085522653342167, 1.}}], + ArrowBox[{{15.87509731101342, 46.14029548845605}, {15.89143359684925, + 46.166072659014176`}, {16.201202673300102`, 46.66108409473791}, { + 16.52738197112422, 47.18855646435075}, {16.872510701029707`, + 47.75292152902761}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{20.12694150910278, 12.742035321552946`}, { + 19.475309313361567`, 13.106672712330523`}, {18.853322956339937`, + 13.456537053991413`}, {18.258963022182925`, 13.791422784066848`}, { + 17.71175053082192, 14.113317006421621`}, {17.183077090978163`, + 14.419307586081462`}, {16.677991242289075`, 14.709908429218304`}, { + 16.501539787699183`, 14.810404875828599`}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{16.41086391515586, 14.862048558818186`}, { + 15.73858231837493, 15.244940905922983`}, {14.881589832640975`, + 15.718313211478819`}, {14.095079858648713`, 16.12992412082897}, { + 13.612015838254463`, 16.36793659886111}, {13.15300527780204, + 16.579761422848595`}, {12.699677697280075`, 16.76466222979054}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{12.603054580667838`, 16.804072345121}, { + 12.356914470045423`, 16.904466645027618`}, {11.624195502125907`, + 17.14325779402543}, {10.94573743961601, 17.299685205508997`}, { + 10.312429348088251`, 17.377299215145282`}, {10.232191143929295`, + 17.38231889691224}, {10.152608909785817`, 17.386050449557032`}, { + 9.811359184231767, 17.37259402369173}, {9.48064527163832, + 17.335479576279525`}, {8.875456256930349, 17.227003907543974`}, { + 8.538691590541408, 17.11767233297943}}]}, + {Arrowheads[{{0.016923601674316276`, 1.}}], + ArrowBox[{{8.43943986827253, 17.0854499885445}, {8.302674686555187, + 17.04104879639124}, {7.75853969360489, 16.784246505361683`}, { + 7.239290411171504, 16.463229296995667`}, {6.743270438669417, + 16.083773147998258`}, {6.267498255044522, 15.656274816438579`}, { + 5.645413566862449, 14.98949921316205}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{36.479716132863196`, 0.4016323505227532}, { + 35.87546906212038, 0.41067147157894923`}, {35.2814318928921, + 0.41969872264618785`}, {34.697407923088, 0.4287077903131379}, { + 34.123200450617716`, 0.43769236116846894`}, {33.55861277339086, + 0.44664612180085017`}, {33.00344818931709, 0.4555627587989509}, { + 32.3061777067387, 0.4669580480252763}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{32.20184038694285, 0.4686632025755976}, { + 31.920601492267284`, 0.47325940824698837`}, {31.27065455267774, + 0.48404207226579526`}, {30.633104443674384`, 0.4947028220270601}, { + 30.007701606745016`, 0.505234380398115}, {29.394196483377435`, + 0.5156294702462919}, {28.792339515059435`, 0.525880814438923}, { + 28.20188114327882, 0.5359811358433402}, {28.02838236709559, + 0.5389586962927787}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{27.924046478658035`, 0.5407492934468509}, { + 27.622571809523382`, 0.5459231573268756}, {27.075457614988743`, + 0.5563205837445278}, {26.525725147222868`, 0.5661582550891151}, { + 25.986642600457774`, 0.5758230722474847}, {24.94042726992993, + 0.5946341440055707}, {23.93681162340521, 0.6127537990187855}, { + 23.750677476741124`, 0.6161293831760191}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{23.646343380069148`, 0.6180215052293723}, { + 22.975795660883612`, 0.6301820372871292}, {22.054029160036304`, + 0.6468462373138664}, {21.168161898534446`, 0.6626737776022614}, { + 20.318193876378043`, 0.6776646581523145}, {19.504125093567083`, + 0.6918188789640256}, {19.472955323276842`, 0.6923513546365635}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{19.36861929415349, 0.6941337353458237}, { + 18.86388165900055, 0.702756208634227}, {18.244873342382046`, + 0.7130993261897992}, {17.26723730956536, 0.7288480725635298}, { + 16.342410706324333`, 0.7429515518870157}, {15.467571425333125`, + 0.7554165158637226}, {15.195075762775167`, 0.7589831373437188}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{15.090733447794502`, 0.7603488454742231}, { + 14.639897359265905`, 0.7662497161971161}, {14.043604128476263`, + 0.773380797882648}, {13.47070993833581, 0.7796253755194875}, { + 12.395118680002474`, 0.7894550186470898}, {11.405799273712331`, + 0.795919387444197}, {10.916867850228805`, 0.7976808819587541}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{10.812517275160651`, 0.7980568303162228}, { + 10.495427408911816`, 0.7991992237750833}, {10.324281086477587`, + 0.7995308600687618}, {10.155927515927576`, 0.7997480120600583}, { + 9.814971458543933, 0.7994846727439558}, {9.48545402611965, + 0.7987519072343788}, {8.700078792955896, 0.7956200578521103}, { + 7.979577289538006, 0.7898617345668076}, {7.318761293014036, + 0.7817477286146144}, {6.712442580532048, 0.7715488312316741}, { + 6.638656763119474, 0.7697755977114633}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.534335631573717, 0.767268534243034}, { + 5.6458847866064135`, 0.7459171299406784}, {4.903257829353509, + 0.7205622578828108}, {4.258261404296697, 0.6925638640323629}, { + 3.2064010428146545`, 0.6320612542363377}, {2.4122560278133154`, + 0.569253782633929}, {2.3660459649395396`, 0.5644851764411436}}]}, + {Arrowheads[{{0.004872495342548926, 1.}}], + ArrowBox[{{2.262245933548732, 0.5537736248500198}, { + 1.814219003441145, 0.5075398856906186}, {1.2527186891481723`, + 0.43247365957612666`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{33.284228421357426`, 4.35668445327842}, {32.3548236467046, + 4.525354326233555}, {31.4574447764906, 4.6933871755879535`}, { + 30.590857468477452`, 4.860514984317108}, {29.75382738042721, + 5.026469735396508}, {29.18487102691367, 5.142211378645766}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{29.08261417107948, 5.163013284547095}, { + 28.945120170101927`, 5.190983411801643}, {28.163501495263645`, + 5.353787996508002}, {27.40773701367442, 5.5146154724910765`}, { + 26.676592383096292`, 5.673197822726358}, {25.697837651698613`, + 5.888866038794643}, {25.00264063250247, 6.043924839235834}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{24.90079202305755, 6.066641454484549}, { + 24.758626133029896`, 6.098350555304389}, {23.856862719588257`, + 6.301259730772988}, {23.01280011722511, 6.50137943286567}, { + 22.196757636330634`, 6.6931614072454595`}, {21.413973045659496`, + 6.87758475761888}, {20.83576072353346, 7.014178966388414}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{20.73420477549139, 7.0381700745641105`}, { + 20.664446345211708`, 7.0546494839859335`}, {19.948177534987263`, + 7.224355586346618}, {19.26186318643962, 7.3862607462924075`}, { + 18.602199871022247`, 7.539922645414778}, {17.96918758873514, + 7.685341283713729}, {17.362826339578294`, 7.822516661189262}, { + 16.784816535282708`, 7.950575932596747}, {16.666932585984405`, + 7.975958396190243}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{16.564919291393842`, 7.997923631927681}, { + 16.229123684760538`, 8.070226263549376}, {15.220516434634007`, + 8.275902753460873}, {14.282481299946859`, 8.450596509954092}, { + 13.408809849892174`, 8.594833807739283}, {12.593293653663034`, + 8.709140921526695}, {12.456062416612525`, 8.724105969130257}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{12.352326150623574`, 8.73541839472742}, { + 11.678164666393682`, 8.808935612241642}, {10.832448207959695`, + 8.868355476245918}, {10.69738135222392, 8.874889307498668}, { + 10.56403984719346, 8.880367009258485}, {10.210638758667116`, + 8.884980790230737}, {9.86901587011006, 8.882132568164712}, { + 9.113633723761886, 8.857554833792474}, {8.41472106320831, + 8.796888172702165}, {8.190022081807298, 8.764485188453454}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{8.086739209386847, 8.749591158817296}, {7.767474971064815, + 8.703551279058951}, {7.1670925299468875`, 8.580962847027996}, { + 6.610544131265691, 8.43194683385523}, {6.09237647956132, + 8.261586362583335}, {5.374377788568465, 7.960988960643618}, { + 4.732639870181266, 7.626415050507472}, {4.210241833388427, + 7.3018665988777}}]}, + {Arrowheads[{{0.013203088989000106`, 1.}}], + ArrowBox[{{4.123313960110224, 7.24425625523851}, {3.644409163090605, + 6.896268822264425}, {3.1873653005643283`, 6.5154543022109275`}, { + 2.781693542612774, 6.132629472051729}, {2.10514849933814, + 5.381565778183589}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{25.270552352601207`, 8.178002954716998}, { + 24.607671521889493`, 8.405565201082126}, {23.968933060077035`, + 8.629162352359591}, {23.35316031645023, 8.848550580614702}, { + 22.759176640295458`, 9.063486057912769}, {22.185805380899122`, + 9.273724956319104}, {21.410379599566216`, 9.56053530264626}, { + 21.341360238016392`, 9.586156042520043}}]}, + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{21.243531788515007`, 9.622471030092353}, { + 20.667770330847855`, 9.836199963611852}, {19.95598244545731, + 10.10041690650925}, {19.294302193166306`, 10.356105780835886`}, { + 18.654465242412833`, 10.598987789914487`}, {18.04145941641372, + 10.82981801551163}, {17.455284715168958`, 11.048596457627319`}, { + 17.336903254417834`, 11.092348821744688`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{17.23902307807133, 11.128524157715475`}, { + 16.895941138678555`, 11.255323116261549`}, {16.36040748895613, + 11.449794059404466`}, {15.84566256801531, 11.631805355046215`}, { + 14.878538912478481`, 11.9584490038262}, {14.376393423169754`, + 12.118077650687214`}, {13.895231083128445`, 12.262553717369887`}, { + 13.275968534820485`, 12.433677535927297`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{13.174704355775432`, 12.45885358200318}, { + 12.6682401053037, 12.583025127698345`}, {12.102885623176297`, + 12.701953579426151`}, {11.565976007269615`, 12.794191187469032`}, { + 10.770459427667948`, 12.888129482114566`}, {10.03216977693193, + 12.921162980062356`}, {9.928666816444826, 12.921539421395678`}, { + 9.826233962623142, 12.920703998279134`}, {9.495000372803677, + 12.900796186137324`}, {9.174345566929613, 12.868311339607068`}, { + 9.045750216221387, 12.849638839928458`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{8.94248194290329, 12.834643921451832`}, {8.49385914976217, + 12.769502305408873`}, {7.859442430027147, 12.615619645837397`}, { + 7.267015142392209, 12.412372820306981`}, {6.712497021525018, + 12.16547128823197}, {6.193609150208173, 11.879610168173011`}, { + 5.70624947745035, 11.563240673539275`}, {5.186719874123697, + 11.154369701133044`}}]}, + {Arrowheads[{{0.00030816743784531044`, 1.}}], + ArrowBox[{{5.104717905716634, 11.089833966601011`}, { + 5.05417723271208, 11.05005834268061}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{36.190296044951495`, 2.278988599990219}, { + 35.192676218892515`, 2.369765546014048}, {34.225910718792655`, + 2.460493451038834}, {33.28885886367611, 2.5509943594550206`}, { + 32.38037997256709, 2.6410903156530523`}, {32.03520907481531, + 2.6761591746478217`}}]}, + {Arrowheads[{{0.019999999999999993`, 1.}}], + ArrowBox[{{31.93139225916488, 2.686706811464959}, { + 31.499333364489786`, 2.7306033640233744`}, {30.644578358468404`, + 2.8193555489564295`}, {30.04954921020404, 2.8820694891286935`}, { + 29.466241613991087`, 2.9441179678805156`}, {28.894387809846, + 3.005462874619257}, {28.33372003778525, 3.06606609875228}, { + 27.78397053782529, 3.125889529686947}, {27.780560906655122`, + 3.126262721047158}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{27.676829145691617`, 3.137616382202573}, { + 27.244871549982594`, 3.1848950568306202`}, {26.22040292264331, + 3.303552061279532}, {25.229968024299886`, 3.4177179116000556`}, { + 24.27892205462306, 3.528154819644949}, {23.530267123775417`, + 3.615783654985654}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{23.42662343213255, 3.62791497959844}, {23.36726501361283, + 3.6348627854142115`}, {22.494996901269204`, 3.737841808907844}, { + 21.658628200878713`, 3.8367001846125817`}, {20.8546693957279, + 3.9310462070151617`}, {20.08312048581676, 4.0208798761155835`}, { + 19.343981471145298`, 4.106201191913848}, {19.280904109575246`, + 4.113389484966046}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{19.1772239261019, 4.125204873624692}, { + 18.706497975308356`, 4.178848780049356}, {18.09167797889866, + 4.24761146035275}, {17.37483257638206, 4.325604438013289}, { + 16.68688165632021, 4.397739431963119}, {16.02782521871311, + 4.464016442202238}, {15.397663263560764`, 4.524435468730647}, { + 15.025788482097589`, 4.558078648041699}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{14.921861665902803`, 4.567480814272791}, { + 14.793781139325171`, 4.579068145107517}, {14.213564194468344`, + 4.6279861048920194`}, {13.65701242899028, 4.6711893480841535`}, { + 13.124125842890981`, 4.708677874683921}, {12.119247816814715`, + 4.767486545988051}, {11.19284931346906, 4.805120729975748}, { + 11.030895920565133`, 4.810058227118876}, {10.8713171668112, + 4.81432972535928}, {10.75601153632908, 4.81593300512951}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{10.651670370117776`, 4.817383828305181}, { + 10.508495403501266`, 4.819374620312647}, {10.157803780771825`, + 4.820943996958636}, {9.346482864974295, 4.815469019032042}, { + 8.599515921588882, 4.7914946268532095`}, {7.911641771615255, + 4.750755480994464}, {7.277599236053081, 4.69498624202813}, { + 6.693851357343197, 4.625608623343333}, {6.488073628743292, + 4.594950115790393}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{6.384861616594407, 4.579572716712511}, {6.154031611879116, + 4.545181709040498}, {5.386603777370995, 4.39540333541825}, { + 4.711359050168454, 4.226500485928004}, {4.11496450113375, + 4.044650166579768}, {3.5903213200267814`, 3.853707066400027}, { + 2.724368460869932, 3.45983837826572}, {2.4401935092996707`, + 3.2928924492504383`}}]}, + {Arrowheads[{{0.001616949458014049, 1.}}], + ArrowBox[{{2.3502197485019285`, 3.240035035180768}, { + 2.0592537009871386`, 3.069099501116813}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.019999999999999997`, 1.}}], + ArrowBox[{{50., 16.927683874390233`}, {49.9085258402617, + 17.06782331794245}, {49.60134528278074, 17.570553536300356`}, { + 49.30827235130409, 18.08416196275136}, {49.029352030259666`, + 18.60894478811419}, {48.61712579644272, 19.461973258711016`}, { + 48.24046421926981, 20.3446945235371}, {48.12710397795115, + 20.64903818988108}}]}, + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{48.090680417116744`, 20.74682626722369}, { + 47.89995745562148, 21.25886933172532}, {47.59619566237826, + 22.206258432408568`}, {47.329235224753326`, 23.187797036860847`}, { + 47.09955954529376, 24.20508078664326}, {46.99908807827641, + 24.727986901834374`}, {46.992345173418954`, 24.767607240761173`}}]}, + {Arrowheads[{{0.02000000000000001, 1.}}], + ArrowBox[{{46.97483758080441, 24.87047933637055}, {46.90839930688091, + 25.260861076319355`}, {46.827647066467435`, 25.804047234418643`}, { + 46.75698519239615, 26.357889300452676`}, {46.69607454392253, + 26.92188897036574}, {46.64475524434011, 27.495854204966165`}, { + 46.603450025066174`, 28.080588325870487`}, {46.572581617518004`, + 28.67689465469524}, {46.56128821779805, 29.020446761880407`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{46.55785978827449, 29.12474167894363}, {46.55257275311288, + 29.285576513056956`}, {46.54384616326808, 29.90743722257217}, { + 46.54682457940089, 30.543280104857413`}, {46.56193073292859, + 31.193908481529217`}, {46.60074066194667, 32.06841127159385}, { + 46.66204374433008, 32.97165599175458}, {46.69130331353067, + 33.294198238671214`}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{46.70073087406533, 33.398122754338054`}, { + 46.746739071145974`, 33.90529314913227}, {46.84613542874499, + 34.853367841558395`}, {46.97296994057879, 35.83926225324546}, { + 47.12499487897946, 36.85885011639126}, {47.21045375814236, + 37.38127909226118}, {47.23724112915973, 37.53625602308441}}]}, + {Arrowheads[{{0.01999999999999999, 1.}}], + ArrowBox[{{47.25501443364049, 37.63908254447873}, { + 47.302210243946966`, 37.912131430995785`}, {47.4002643363933, + 38.45140713259508}, {47.50461603548134, 38.99910619705906}, { + 47.61591469445789, 39.55637347306148}, {47.73480966656976, + 40.124353809276094`}, {47.861300951816936`, 40.703047205702916`}, { + 47.99538855019942, 41.29245366234194}, {48.097844841853195`, + 41.7264198027947}}]}, + {Arrowheads[{{0.02, 1.}}], + ArrowBox[{{48.12182223701982, 41.82797898935725}, {48.13707246171722, + 41.892573179193164`}, {48.28635268637032, 42.5034057562566}, { + 48.44322922415874, 43.12495139353223}, {48.607702075082464`, + 43.757210091020056`}, {48.88518382325472, 44.808648426427176`}, { + 49.03538095657439, 45.35087077467897}, {49.17805395600637, + 45.865930463731004`}}]}, + {Arrowheads[{{0.012644001720598238`, 1.}}], + ArrowBox[{{49.20792368938321, 45.9659072381097}, {49.42363453613884, + 46.66881048528552}, {49.661690982383625`, 47.44452784764029}, { + 49.9309249016575, 48.26676300126804}, {50., + 48.482957315927486`}}]}}, + {Hue[0.67, 0.6, 0.6], + {Arrowheads[{{0.020000000000000007`, 1.}}], + ArrowBox[{{12.565916046932262`, 20.60570641946029}, { + 12.2123917131082, 20.833871506624245`}, {11.876577004601629`, + 21.031142440303277`}, {10.939149459576333`, 21.45006494135886}, { + 10.103358364970097`, 21.607336644331554`}, {10.05034315202163, + 21.60943094596297}, {9.997619283949339, 21.610451041028742`}, { + 9.659635899296376, 21.565111216597902`}, {9.329751950939706, + 21.47587622049211}, {8.698856689190954, 21.177150711403073`}}]}, + {Arrowheads[{{0.004124750181173024, 1.}}], + ArrowBox[{{8.604543597199726, 21.13249397021794}, {8.361564965429825, + 21.017444896506355`}, {7.895113454608308, + 20.652898851426308`}}]}}}}, {{}, + {RGBColor[1, 0, 0], PointSize[0.03], + PointBox[{{0., 0.}, {10., 30.}}]}, {}}}, {{}, {}, + {RGBColor[0, 1, 0], LineBox[CompressedData[" +1:eJxTTMoPSmViYGAwAWIQrdT/d/E8uYd2DGBg53Bq4u3CF+n8DjC+1152v2fp +8nD+WV4zTpZYAzjfqd/1wHJ/Czg/Vf8XryGvA5zvq5n6UczdBc7fdKW29KSF +B5xvLaS1nqXeB85P/z1p7tKIADg//9hz4/W+QXB+VxSb6t+cEDg/+Xh1mmFG +GJx/kF0yMDsyAs43FGyY9rIkCs5P+Gyr45cTA+cvnHdU5ntvHJy/uc/q9qWg +BDi/ZJdtwFyfRDh//6mlnzqjk+D8THfLvZkRyXD+nBWGW7OzUuD8iZ/3NhaU +p8L5z1aVlmUUpcH5R9wmzWhqSofzGf1vPepvyIDzGRy3MS6ozITzO8S/+15q +z4LzC6KSD31vzobzHzaapNhPzYHzRSbPvNW5MBfOXyagVXl8dh4ivIrkXdVX +58P58xQWyNiGFMD5e2t+MWRcQPAVvdn/KIcXwvlbzmt237yC4Pcc+2egEFsE +508ufpmVcAfBrxGV41eKLIbzV2qynip5gOCzfWGUPBhXAucvN9hYN+85gq+Z +tMrvb24pnH/bc+em0NcI/qXFVbr2xWVw/o/NgTZKnxD8/zuKtrbllcP53gZu +rjVfEfzjsfqZ2cUVcL4Ve8CGrTsR/HUbCr7//4/gAwC5L9RY + "]]}}, {{}, {}, + {RGBColor[0.5, 0, 0.5], LineBox[{{10., 0.}, {10., 400.}}]}}}, {{}, {}, + {GrayLevel[0.5], Thickness[Large], + LineBox[{{33.570226039551585`, -20.}, {-13.570226039551583`, + 80.}}]}}, {{}, {}, + {GrayLevel[0], Thickness[Large], + LineBox[{{-13.570226039551583`, -20.}, {33.570226039551585`, 80.}}]}}}, + AspectRatio->1, + Frame->True, + Method->{"TransparentPolygonMesh" -> True}, + PlotRange->{{-1.0878130721773847`, + 51.08781307217738}, {-1.0878130721773847`, 51.08781307217738}}, + PlotRangeClipping->True, + PlotRangePadding->{ + Scaled[0.02], + Scaled[0.02]}]], "Output", + CellChangeTimes->{{3.514691009500609*^9, 3.514691043595607*^9}, { + 3.514691284220406*^9, 3.514691309255802*^9}, 3.514691371020177*^9, { + 3.514691806484208*^9, 3.514691852781773*^9}, {3.5146925917136087`*^9, + 3.514692607901375*^9}, {3.514692651415642*^9, 3.5146927219682283`*^9}, { + 3.514693254278116*^9, 3.514693364886175*^9}, {3.514693594246429*^9, + 3.514693614141787*^9}, 3.514694072215996*^9, 3.514694199356619*^9, + 3.514694259337203*^9, + 3.620425623703861*^9},ExpressionUUID->"01cbeb0d-e5f8-41ac-b2aa-\ +d9bf695e8c57"] +}, Open ]], + +Cell[TextData[{ + "Stretching occurs along the black eigenvector (by a factor given by the \ +eigenvalue ", + Cell[BoxData[ + RowBox[{ + RowBox[{"1", "+", + RowBox[{ + SqrtBox["rc"], " ", + SqrtBox["rd"]}]}], "}"}]], + CellChangeTimes->{ + 3.514430079485057*^9, 3.514431346378005*^9, {3.514513514991106*^9, + 3.514513544721499*^9}, 3.514513602831394*^9, 3.514688704300499*^9, + 3.5146931948396797`*^9},ExpressionUUID-> + "cfb8086e-bb3d-4fa0-a364-769b1529f0dc"], + "), while shrinking occurs along the gray eigenvector (by a factor given by \ +the eigenvalue ", + Cell[BoxData[ + RowBox[{ + RowBox[{"1", "-", + RowBox[{ + SqrtBox["rc"], " ", + SqrtBox["rd"]}]}], "}"}]], + CellChangeTimes->{ + 3.514430079485057*^9, 3.514431346378005*^9, {3.514513514991106*^9, + 3.514513544721499*^9}, 3.514513602831394*^9, 3.514688704300499*^9, + 3.5146931948396797`*^9},ExpressionUUID-> + "01aba5c9-7801-4bc2-9fc5-e1252e0e89f5"], + "). So near the equilibrium with both species present, if we start below \ +the gray line, the system is stretched downward eventually, while if we start \ +above the gray line, the system is stretched upward eventually.\n\nThese \ +eigenvectors only describe the stretching/shrinking near the equilibrium, \ +however, and it is clear that as we move further from the red equilibrium \ +point, the straight eigenvectors provide a poorer description of where the \ +system eventually heads. " +}], "Text", + CellChangeTimes->{{3.514693564143486*^9, 3.514693569319523*^9}, { + 3.5146936290799437`*^9, 3.514693866538453*^9}, {3.514693912676289*^9, + 3.514693933340423*^9}, {3.514694312311425*^9, 3.5146943138048983`*^9}, { + 3.514694458593581*^9, 3.514694497369865*^9}, {3.514694783095038*^9, + 3.5146947832595243`*^9}, {3.620424834149797*^9, 3.620424840270849*^9}, { + 3.620425652511738*^9, + 3.620425652860046*^9}},ExpressionUUID->"349c6c71-36ea-41ce-ab28-\ +97d162a0a359"], + +Cell["\<\ +Of course, the above model is just a start. One limitation is that it \ +predicts that if the populations are able to grow, they do so indefinitely. \ +In reality, population growth must be limited eventually by competition, but \ +this has not yet been incorporated into the model.\ +\>", "Text", + CellChangeTimes->{{3.514688976472577*^9, 3.514689144308895*^9}, { + 3.514693437744516*^9, + 3.514693487087606*^9}},ExpressionUUID->"ae62c8d6-928b-4b30-a031-\ +dc1a7ca34e6f"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell[TextData[{ + "Appendix: Quick reference to ", + StyleBox["Mathematica", + FontSlant->"Italic"] +}], "Section", + Evaluatable->False, + CellChangeTimes->{{3.513949886366438*^9, 3.513949888828957*^9}}, + AspectRatioFixed-> + True,ExpressionUUID->"5fd34efa-326c-4863-8ddf-adfe8c8ed51d"], + +Cell[CellGroupData[{ + +Cell["Getting started", "Subsection", + Evaluatable->False, + AspectRatioFixed-> + True,ExpressionUUID->"15c6e2b9-8932-4d44-b865-b09662f8305c"], + +Cell[TextData[{ + "Help -> Documentation Center", + StyleBox[" - Can be used to search for commands of interest\n", + FontFamily->"Times", + FontWeight->"Plain"], + "\n?Command", + StyleBox[" - gives a fairly detailed description of a command, e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + "?Plot", + StyleBox[" tells you all about this command. \n\tYou can use * as a \ +wildcard, for instance ", + FontFamily->"Times", + FontWeight->"Plain"], + "?*Plot", + StyleBox["* gives a list of all commands with Plot in their name. \n\tMore \ +help can be found in the menu under \"Help\", in the Function Navigator or \ +Documentation Center.\n\t\n", + FontFamily->"Times", + FontWeight->"Plain"], + "*", + StyleBox[" - Times command (2*3 gives 6). Spaces can also be used but be \ +careful (e.g, ", + FontFamily->"Times", + FontWeight->"Plain"], + "a=2 3", + StyleBox[" gives six\n\tbut ", + FontFamily->"Times", + FontWeight->"Plain"], + "a=23", + StyleBox[" gives twenty-three)\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "^", + StyleBox[" - Power command (2^3 gives 8)\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "n!", + StyleBox[" - factorial (3! gives 6)\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "{}", + StyleBox[" - denotes a list, e.g., {2,3,4}\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "()", + StyleBox[" - Places variables together, e.g., (1+x)/(1-x) takes 1+x over \ +1-x\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "[]", + StyleBox[" - Generally used to denote that something is a function of \ +something else\n\n%", + FontFamily->"Times", + FontWeight->"Plain"], + "#", + StyleBox[" - grabs previous output number #.\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "%", + StyleBox[" - grabs the previous line of output regardless of the number\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "%%", + StyleBox[" - grabs output two lines back. Note: naming outputs is safer \ +(see next section).\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "f /. object1 -> object2", + StyleBox[" \n - tells Mathematica to make replace object1 with \ +object2 in the function\n e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + "3*x^2 /. x -> 2*y+z", + StyleBox[" gives ", + FontFamily->"Times", + FontWeight->"Plain"], + "3*(2*y + z)^2 \n " +}], "Input", + CellChangeTimes->{{3.513949908602819*^9, 3.513949996977407*^9}, { + 3.5139501531450663`*^9, 3.513950178540937*^9}, {3.513950343469256*^9, + 3.513950345242174*^9}, 3.5140603007363853`*^9, {3.514060332457301*^9, + 3.514060344341905*^9}, {3.563121569604072*^9, 3.563121569929719*^9}, { + 3.618707495180807*^9, 3.618707565305377*^9}, {3.618707601648489*^9, + 3.618707609832266*^9}, {3.6187077244610243`*^9, 3.618707824899582*^9}, { + 3.618708522804984*^9, 3.61870852609206*^9}}, + AspectRatioFixed-> + True,ExpressionUUID->"407f3365-c0ab-485c-83aa-2dfa2e0cb43f"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell[TextData[{ + "Avoiding conflict with ", + StyleBox["Mathematica", + FontSlant->"Italic"] +}], "Subsection", + CellChangeTimes->{{3.513950368656147*^9, 3.513950374988236*^9}, + 3.513950561334874*^9},ExpressionUUID->"a01fa7c4-eef1-4966-a9b6-\ +1a85c61bcf9c"], + +Cell[TextData[{ + StyleBox["Mathematica", + FontSlant->"Italic"], + " tends to use capital letters for its functions, so its often a good idea \ +to use \nlower case names for your functions and variables.\n\nIf you refer \ +to previous entries using %, it can be difficult to know exactly what your \n\ +previous entry was. It is safer to assign a name to the output and then \ +refer to this name later.\n\nFor example," +}], "Text", + CellChangeTimes->{{3.513950396290183*^9, 3.513950507636909*^9}, { + 3.514081351768971*^9, + 3.514081353894698*^9}},ExpressionUUID->"ed6897e0-eb4f-4a84-80ef-\ +26277213ad33"], + +Cell[BoxData[ + RowBox[{"myderivative", " ", "=", " ", + RowBox[{"D", "[", + RowBox[{ + RowBox[{"a", " ", + RowBox[{"Sin", "[", + RowBox[{"b", " ", "x"}], "]"}]}], ",", " ", "x"}], "]"}]}]], "Input", + CellChangeTimes->{{3.5139505131262074`*^9, + 3.5139505527349653`*^9}},ExpressionUUID->"168487e7-aebb-4ba1-ad4e-\ +987bbefe0ad8"], + +Cell[BoxData[ + RowBox[{ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{ + RowBox[{"myderivative", "/.", + RowBox[{"a", "\[Rule]", "1"}]}], "/.", + RowBox[{"b", "\[Rule]", "3"}]}], ",", + RowBox[{"{", + RowBox[{"x", ",", "0", ",", "10"}], "}"}]}], "]"}], + "\[IndentingNewLine]"}]], "Input", + CellChangeTimes->{{3.513950521780437*^9, 3.513950546486189*^9}, { + 3.563121571454344*^9, 3.563121571645876*^9}, {3.618707770838048*^9, + 3.618707771686625*^9}, + 3.618708422888011*^9},ExpressionUUID->"3f4dd988-8c28-40a2-bed7-\ +b1971dfdab81"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell[TextData[{ + "Functions and constants in ", + StyleBox["Mathematica", + FontSlant->"Italic"], + "\n(A small fraction!)" +}], "Subsection", + Evaluatable->False, + AspectRatioFixed-> + True,ExpressionUUID->"e79b889b-0e02-4a7e-91f7-b4d817901a28"], + +Cell[TextData[{ + StyleBox["Abs[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - Takes the absolute value of x\n\n", + StyleBox["E", + FontFamily->"Courier", + FontWeight->"Bold"], + " - The exponential constant 2.71838. ", + StyleBox["E^(x)", + FontFamily->"Courier", + FontWeight->"Bold"], + " can be invoked using ", + StyleBox["Exp[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + StyleBox["\n", + FontSize->12], + StyleBox["\nI", + FontFamily->"Courier", + FontWeight->"Bold"], + " - The square root of negative 1.\n\n", + StyleBox["Infinity", + FontFamily->"Courier", + FontWeight->"Bold"], + " - Self-explanatory.\n\n", + StyleBox["Log[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " -Takes the natural log of x\n\n", + StyleBox["Log[b,x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " -Takes the log of x in base b\n\n", + StyleBox["Pi", + FontFamily->"Courier", + FontWeight->"Bold"], + " - 3.14159...\n\n", + StyleBox["Sin[x], Cos[x], Tan[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - trigonometric functions", + StyleBox["\n", + FontSize->12], + StyleBox["ArcSin[x], ArcCos[x], ArcTan[x] ", + FontFamily->"Courier", + FontWeight->"Bold"], + "- inverse trigonometric functions\n\n", + StyleBox["Sqrt[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - Square root" +}], "Text", + Evaluatable->False, + CellChangeTimes->{{3.513950323503922*^9, 3.513950333260998*^9}, { + 3.563121524371439*^9, 3.563121524704859*^9}, {3.618707651880374*^9, + 3.618707668239052*^9}, {3.618707766796749*^9, 3.6187077676614428`*^9}, + 3.6187084181609707`*^9, {3.618708461384329*^9, 3.618708464911661*^9}, + 3.62004023217328*^9}, + AspectRatioFixed-> + True,ExpressionUUID->"056622c9-2b57-4e8a-a5af-0c906eb66688"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell[TextData[{ + "Writing equations in ", + StyleBox["Mathematica", + FontSlant->"Italic"] +}], "Subsection", + Evaluatable->False, + AspectRatioFixed-> + True,ExpressionUUID->"a652d8ab-b08b-4312-9fd2-10b613a341dc"], + +Cell[TextData[{ + StyleBox["x=y", "Input", + FontWeight->"Bold"], + StyleBox[" ", "Input", + FontFamily->"Times", + FontWeight->"Bold"], + StyleBox[" - Sets x to y immediately and from then on (use Clear[x] to \ +unassign x), e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["plot1=Plot[x^2,{x,0,10}]", "Input", + FontWeight->"Bold"], + StyleBox["\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["x:=y", "Input", + FontWeight->"Bold"], + StyleBox[" - Does nothing until x is called, at which point x is assigned \ +the value y\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["x==y", "Input", + FontWeight->"Bold"], + StyleBox[" ", "Input", + FontFamily->"Times", + FontWeight->"Bold"], + StyleBox[" - Tests whether x equals y BUT makes no assignment\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["f[x_]:=", "Input", + FontWeight->"Bold"], + " ", + StyleBox["- This is how you define a function (called \"f\") of x, e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["f[x_] := x^2", "Input", + FontWeight->"Bold"], + "\n\n", + StyleBox["f[x]", "Input", + FontWeight->"Bold"], + " ", + StyleBox["- This gives the function evaluated at x, e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["f[3]", "Input", + FontWeight->"Bold"], + StyleBox[" gives ", + FontFamily->"Times", + FontWeight->"Plain"], + "9", + StyleBox[" in the above example", + FontFamily->"Times", + FontWeight->"Plain"], + "\n\n", + StyleBox["f[x_,y_,...]=", "Input", + FontWeight->"Bold"], + " ", + StyleBox["- This is how you define a function of several variables", + FontFamily->"Times", + FontWeight->"Plain"] +}], "Input", + CellChangeTimes->{ + 3.513951162654813*^9, {3.563121328181324*^9, 3.563121345683249*^9}, { + 3.563121529178462*^9, 3.5631215293437777`*^9}, {3.618707875626803*^9, + 3.618707881302347*^9}, {3.620040237579296*^9, 3.620040238380657*^9}}, + AspectRatioFixed-> + True,ExpressionUUID->"0a60f49a-ea6d-4902-bb95-9adaf42301f4"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["A list of helpful commands", "Subsection", + Evaluatable->False, + AspectRatioFixed-> + True,ExpressionUUID->"a224c7ec-60c0-4910-98d7-3fd99236f8bb"], + +Cell[TextData[{ + StyleBox["Clear[symbol1,symbol2,...]", "Input"], + " - clears variable or function definitions, \n\te.g., ", + StyleBox["Clear[x, y, pop1]", "Input", + FontWeight->"Bold"], + "\n\n", + StyleBox["Clear[\[OpenCurlyDoubleQuote]Global`*\[CloseCurlyDoubleQuote]] ", + "Input", + FontWeight->"Bold"], + "- clears all variable or function definitions from memory\n\n", + StyleBox["Collect[eqn,{terms},Factor]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - collects parts of an equation involving \[OpenCurlyDoubleQuote]terms\ +\[CloseCurlyDoubleQuote] and \n\tfactors them separately (if only one \ +\[OpenCurlyDoubleQuote]term\[CloseCurlyDoubleQuote], the braces aren\ +\[CloseCurlyQuote]t needed)\n\te.g. Collect[", + Cell[BoxData[ + RowBox[{"a", "-", "b", "+", + RowBox[{"a", " ", "x"}], "-", + RowBox[{"2", " ", "b", " ", "x"}], "+", + RowBox[{ + SuperscriptBox["a", "2"], " ", + SuperscriptBox["x", "2"]}], "+", + RowBox[{"2", " ", "a", " ", "b", " ", + SuperscriptBox["x", "2"]}], "+", + RowBox[{ + SuperscriptBox["b", "2"], " ", + SuperscriptBox["x", "2"]}]}]], + CellChangeTimes->{{3.51395123610637*^9, 3.513951252570932*^9}}, + ExpressionUUID->"02062a25-918b-4ace-a999-6a1189d8d3d5"], + ", x, Factor]\n\n", + StyleBox["D[f,x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - takes the partial derivative of f with respect to x - e.g. D[x^2+y \ +Log[x], x]\n\n", + StyleBox["D[f, {x, n}] ", + FontFamily->"Courier", + FontWeight->"Bold"], + " - takes the nth derivative with respect to x - e.g. D[x^2+y Log[x],{x,2}]\ +\n\n", + StyleBox["DSolve[eqn, y[x],x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - solves differential equation for y as a function of x \n\t\ +(SYMBOLICALLY) e.g. DSolve[{y'[x] == k y[x], y[0]==y0, y[x],x]\n\n", + StyleBox["DSolve[eqns, {y1,y2,y3,..}, x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " same as above but for a system of eqns \n\te.g. pred-prey equations \ +DSolve[{y'[x] == k y-x, z'[x]==x+z}, {y[x],z[x]}, x]\n\n", + StyleBox["NDSolve[eqns, y, {x, xmin,xmax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - same as DSolve but seeks solution\n\tNUMERICALLY - e.g. NDSolve[{y'[x] \ +==4 y[x], y[3]==62}, y[x], {x, 0,20}]\n\n", + StyleBox["Expand[expr]", + FontFamily->"Courier", + FontWeight->"Bold"], + "- expands an expr e.g. Expand[(1+x)^2] gives 1+2x+x^2\n\n", + StyleBox["Evaluate[object]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - evaluates a symbolic object like interpolating functions\n\n", + StyleBox["Factor[polynomial]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - self explanatory - e.g. Factor[x^2 + 2 x + 1]\n\n", + StyleBox["FindRoot[eqn1==eqn2, {x, x0}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - searches for numerical root of eqn1==eqn2\n starting at x0 \ +e.g. FindRoot[Log[x] + x + Arctan[x] == 0, {x, 4}] tries to find \n \ + x that satisfies this very ugly - impossible to solve by hand equation, \ +starting at x=4.\n\n", + StyleBox["For[start,test,increment,body]", "Input", + FontWeight->"Bold"], + " - repeats procedure \[OpenCurlyDoubleQuote]body\[CloseCurlyDoubleQuote], \ +starting from \[OpenCurlyDoubleQuote]start\[CloseCurlyDoubleQuote] \n\tuntil \ +the \[OpenCurlyDoubleQuote]test\[CloseCurlyDoubleQuote] condition is met, \ +adding \[OpenCurlyDoubleQuote]increment\[CloseCurlyDoubleQuote] each time, \n\ +\te.g., ", + StyleBox["For[i=1, i\[LessEqual]10, i=i+1, Print[i]]", "Input", + FontWeight->"Bold"], + " prints out integers 1 through 10.\n\n", + StyleBox["Integrate[f,x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - finds indefinite integral of f with respect to x \n\te.g., \ +Integrate[Log[x], x]\n\n", + StyleBox["Integrate[f, {x, xmin, xmax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - computes definite integral from xmin to xmax\n\te.g., Integrate[Log[x], \ +{x, 1,6}]\n\n", + StyleBox["ListPlot[list] ", "Input", + FontWeight->"Bold"], + "- plots a list of integers, e.g., ", + StyleBox["ListPlot[{2,4,3,5,4}]", "Input", + FontWeight->"Bold"], + "\n\n", + StyleBox["ListPlot[{{x1, y1},{x2, y2},...}] ", "Input"], + "- plots a series of {x, y} values,\n\te.g., ", + StyleBox["ListPlot[{{1,2},{2,1},{5,7}}] ", "Input", + FontWeight->"Bold"], + "To join the points with a line use:", + StyleBox["\n\t ListPlot[{{1,2},{2,1},{5,7}},PlotJoined->True] ", "Input", + FontWeight->"Bold"], + "(in ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " 5)\n", + StyleBox["\t ListPlot[{{1,2},{2,1},{5,7}},Joined->True] ", "Input", + FontWeight->"Bold"], + "(in more recent versions)\n\n", + StyleBox["N[f]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - gives a numerical value for an expression - e.g. N[Pi] gives 3.14159\n\n", + StyleBox["Part[eqn,i]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - grabs the ith part of eqn, e.g., Part[3x^2+x^3,2] gives x^3\n\n", + StyleBox["Plot[f,{x,xmin,xmax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - plots f versus x on the interval [xmin,xmax] \n e.g., \ +Plot[x^2, {x,0,2}] NOTE: Plot has lots of options e.g. AxesLabel,\n \ + Grid, AxesOrigin, etc. See the manual for a complete list and usage \n \ + e.g., Plot[x^2, {x,0,2}, PlotStyle->Dashed] makes a dashed curve.\n\n", + StyleBox["Plot3D[f, {x, xmin, xmax}, {y, ymin, ymax}] ", "Input", + FontWeight->"Bold"], + "- makes a 3D plot of f\n\n", + StyleBox["Show[graphics, options]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - displays graphic objects using options e.g. \n\tShow[popplot1, \ +PlotJoined->True]\n\n", + StyleBox["Simplify[expr]", "Input", + FontWeight->"Bold"], + " - does its best to simplify an expression, expr\n\n", + StyleBox["Solve[eqns, vars]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - tries to solve one or a system equations for the vars specified \n\t\ +(SYMBOLICALLY)- e.g. Solve[{x+y ==1, x-y ==4}, {x,y}]\n\n", + StyleBox["NSolve[eqns, vars]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - does the same thing as Solve, but does it NUMERICALLY\n\t(See also \ +FindRoot)\n\n", + StyleBox["Sum[f, {i, imin, imax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - sums f from i to imax i.e. f[1] + f[2] + f[3] + ... \n (only \ +really interesting if f depends on i) - e.g. Sum[i, {i, 1,4}] gives 10.\n \ + \n", + StyleBox["Reduce[{eqns}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - can be used to determine if a statement is true or false \n\te.g., \ +Reduce[{a + b > 1, a < 0, b < 0}]\n\t\n", + StyleBox["RSolve[eqns, vars]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - solves a discrete-time equation for y as a function of x \n\t\ +(SYMBOLICALLY) e.g. RSolve[{n[t+1] == R n[t], n[0]==n0}, n[t],t]\n\t\n", + StyleBox["Table[f, {i, imin, imax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + "- makes a table in list format of the function f\n\twith i values that run \ +from imin to imax - e.g. Table[i, {i, 1,4}] gives {1,2,3,4}.\n\t" +}], "Text", + Evaluatable->False, + CellChangeTimes->{{3.513950574915991*^9, 3.513950644564106*^9}, { + 3.5139506852524443`*^9, 3.5139507449534903`*^9}, {3.513951058272286*^9, + 3.513951157431922*^9}, {3.513951258750285*^9, 3.513951289125362*^9}, { + 3.513951388122881*^9, 3.5139514539888678`*^9}, {3.563121349636468*^9, + 3.56312137989666*^9}, {3.5631215383007097`*^9, 3.5631215384589367`*^9}, { + 3.5631216133411827`*^9, 3.563121629795897*^9}, {3.618706999372814*^9, + 3.6187070072615623`*^9}, {3.618707059868635*^9, 3.618707088131692*^9}, { + 3.6187079213007107`*^9, 3.6187079237033043`*^9}, {3.618707973985024*^9, + 3.6187079869762917`*^9}, {3.618708025765148*^9, 3.618708066614579*^9}, { + 3.618708105359006*^9, 3.6187081645478563`*^9}, {3.618708214244253*^9, + 3.618708219452034*^9}, 3.61870843421904*^9, {3.6187084805441637`*^9, + 3.618708512996409*^9}, 3.618708553301162*^9, {3.618708665614304*^9, + 3.618708799566545*^9}, {3.618708829907131*^9, 3.618708878628771*^9}, { + 3.618708971988484*^9, 3.6187089725306787`*^9}, {3.618709332845521*^9, + 3.618709368817597*^9}, {3.618709565197136*^9, 3.6187095669896708`*^9}, { + 3.6187096668400307`*^9, 3.6187097296590443`*^9}, {3.618709851524448*^9, + 3.618709893664585*^9}, {3.618709931444655*^9, 3.618709948061162*^9}, { + 3.618710235087677*^9, 3.618710236246958*^9}}, + AspectRatioFixed-> + True,ExpressionUUID->"b19aa47d-3c71-402c-b720-da43ff8233ff"] +}, Closed]], + +Cell[CellGroupData[{ + +Cell["Libraries", "Subsection", + Evaluatable->False, + AspectRatioFixed-> + True,ExpressionUUID->"33a7dbbb-a5e3-4827-92ec-6dc7fd7393cc"], + +Cell[TextData[{ + StyleBox["Mathematica", + FontFamily->"Times", + FontWeight->"Plain", + FontSlant->"Italic"], + StyleBox[" has some libraries or packages that it does not load \ +automatically.\nThe Documentation Center will tell you if a function needs a \ +library.\nFor example, to plot error bars on a list plot, you will need:", + FontFamily->"Times", + FontWeight->"Plain"] +}], "Text", + CellChangeTimes->{{3.563121394475396*^9, + 3.5631213999837*^9}},ExpressionUUID->"b5072fa0-642d-496f-99b2-c4dade28aec5"], + +Cell[BoxData[ + RowBox[{"Needs", "[", "\"\\"", "]"}]], "Input", + CellChangeTimes->{ + 3.563121385155899*^9},ExpressionUUID->"86fc153c-ff24-47f9-babf-\ +da8878c78712"], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{ + RowBox[{"ErrorListPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"1", ",", "1"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.2", "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"2", ",", "2"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.1", "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"3", ",", "4"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.3", "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"4", ",", "6"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.4", "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"5", ",", "7"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.8", "]"}]}], "}"}]}], "}"}], ",", " ", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"0", ",", "6"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "8"}], "}"}]}], "}"}]}]}], "]"}], " "}]], "Input", + CellChangeTimes->{{3.513950246287406*^9, 3.513950270738648*^9}, + 3.563121389070549*^9},ExpressionUUID->"1646f9c1-3057-470c-8965-\ +fee79a25fe5b"], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {Hue[0.67, 0.6, 0.6], + LineBox[{{1., 1.}, {2., 2.}, {3., 4.}, {4., 6.}, {5., + 7.}}], {{LineBox[{{1., 1.2}, {1., 0.8}}], + LineBox[{Offset[{1.5, 0}, {1., 1.2}], Offset[{-1.5, 0}, {1., 1.2}]}], + LineBox[{Offset[{1.5, 0}, {1., 0.8}], Offset[{-1.5, 0}, {1., 0.8}]}]}, { + LineBox[{{2., 2.1}, {2., 1.9}}], + LineBox[{Offset[{1.5, 0}, {2., 2.1}], Offset[{-1.5, 0}, {2., 2.1}]}], + LineBox[{Offset[{1.5, 0}, {2., 1.9}], Offset[{-1.5, 0}, {2., 1.9}]}]}, { + LineBox[{{3., 4.3}, {3., 3.7}}], + LineBox[{Offset[{1.5, 0}, {3., 4.3}], Offset[{-1.5, 0}, {3., 4.3}]}], + LineBox[{Offset[{1.5, 0}, {3., 3.7}], Offset[{-1.5, 0}, {3., 3.7}]}]}, { + LineBox[{{4., 6.4}, {4., 5.6}}], + LineBox[{Offset[{1.5, 0}, {4., 6.4}], Offset[{-1.5, 0}, {4., 6.4}]}], + LineBox[{Offset[{1.5, 0}, {4., 5.6}], Offset[{-1.5, 0}, {4., 5.6}]}]}, { + LineBox[{{5., 7.8}, {5., 6.2}}], + LineBox[{Offset[{1.5, 0}, {5., 7.8}], Offset[{-1.5, 0}, {5., 7.8}]}], + LineBox[{Offset[{1.5, 0}, {5., 6.2}], Offset[{-1.5, 0}, {5., 6.2}]}]}}}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{{0, 6}, {0, 8}}, + PlotRangeClipping->True, + PlotRangePadding->{Automatic, Automatic}]], "Output", + CellChangeTimes->{{3.563121232176646*^9, + 3.563121287867106*^9}},ExpressionUUID->"7f10c13f-6df7-4857-a107-\ +0cbd910efa4c"] +}, Open ]] +}, Closed]] +}, Closed]] +}, Open ]] +}, +WindowSize->{1125, 723}, +WindowMargins->{{Automatic, 42}, {Automatic, 0}}, +PrivateNotebookOptions->{"VersionedStylesheet"->{"Default.nb"[8.] -> False}}, +ShowSelection->True, +Magnification->1.25, +FrontEndVersion->"12.1 for Mac OS X x86 (64-bit) (June 19, 2020)", +StyleDefinitions->"Default.nb", +ExpressionUUID->"944b1ac1-e437-4809-b94c-9c98a940d90a" +] +(* End of Notebook Content *) + +(* Internal cache information *) +(*CellTagsOutline +CellTagsIndex->{ + "Info3514654656-5782146"->{ + Cell[142150, 3914, 1150, 23, 258, "Print",ExpressionUUID->"353a083e-0028-4907-af1c-6a1b1a33e6bc", + CellTags->"Info3514654656-5782146"]}, + "Info3514665203-3164126"->{ + Cell[316619, 8381, 2837, 46, 96, "Print",ExpressionUUID->"cf242f76-0f13-470e-8415-d864fa3ca790", + CellTags->"Info3514665203-3164126"]}, + "Info3514667375-7328529"->{ + Cell[356608, 9152, 2826, 45, 96, "Print",ExpressionUUID->"b34c0a8d-db2f-40c0-b644-c27d30afdb23", + CellTags->"Info3514667375-7328529"]}, + "Info3514664747-5819389"->{ + Cell[489452, 11286, 350, 7, 61, "Print",ExpressionUUID->"818115c5-a869-4c3c-82fb-74819af00235", + CellTags->"Info3514664747-5819389"]} + } +*) +(*CellTagsIndex +CellTagsIndex->{ + {"Info3514654656-5782146", 927512, 18608}, + {"Info3514665203-3164126", 927682, 18611}, + {"Info3514667375-7328529", 927851, 18614}, + {"Info3514664747-5819389", 928020, 18617} + } +*) +(*NotebookFileOutline +Notebook[{ +Cell[CellGroupData[{ +Cell[567, 22, 508, 12, 134, "Title",ExpressionUUID->"8a327de2-529b-4bea-8247-b78719b77d90"], +Cell[1078, 36, 642, 17, 217, "Text",ExpressionUUID->"c1f25a80-b0a0-4723-b2be-418deaae5a8c"], +Cell[CellGroupData[{ +Cell[1745, 57, 364, 7, 84, "Section",ExpressionUUID->"73ad134b-a12d-40b7-9758-a39415a42e2a"], +Cell[CellGroupData[{ +Cell[2134, 68, 166, 3, 67, "Subsection",ExpressionUUID->"487c3942-fe85-40fd-83f5-55cc1164f56d"], +Cell[2303, 73, 1717, 41, 280, "Text",ExpressionUUID->"7a137491-f62f-47fa-b492-d360b4529c55"] +}, Open ]], +Cell[CellGroupData[{ +Cell[4057, 119, 214, 4, 67, "Subsection",ExpressionUUID->"10ac2577-62f8-4f6c-9f58-c0040c166b45"], +Cell[4274, 125, 1866, 45, 285, "Text",ExpressionUUID->"28be2ba4-f799-48b5-b3d7-88ff742ece0d"] +}, Open ]], +Cell[CellGroupData[{ +Cell[6177, 175, 223, 4, 67, "Subsection",ExpressionUUID->"583ce927-cb7a-4afc-806f-e2ddd8887de0"], +Cell[6403, 181, 2120, 63, 261, "Text",ExpressionUUID->"1877d1e9-a3c1-4034-a81a-b82bee67d839"] +}, Closed]], +Cell[CellGroupData[{ +Cell[8560, 249, 228, 7, 46, "Subsection",ExpressionUUID->"95131596-18ab-4c85-82e9-b54886651daf"], +Cell[8791, 258, 249, 7, 77, "Text",ExpressionUUID->"e55751a2-3544-4768-be72-fcb24b219507"], +Cell[9043, 267, 317, 7, 77, "Text",ExpressionUUID->"ff278b1a-0b0b-42cc-bdab-4ee0e7a67580"], +Cell[CellGroupData[{ +Cell[9385, 278, 560, 17, 127, "Input",ExpressionUUID->"c3464778-7e0c-4d59-a545-308c9d4c445a"], +Cell[9948, 297, 136, 3, 78, "Output",ExpressionUUID->"0f77a2a6-b30a-4597-b0da-2c19bce19a45"] +}, Open ]], +Cell[10099, 303, 464, 10, 168, "Text",ExpressionUUID->"5c56e21e-ec31-42b6-a0d2-37d703af7a5a"], +Cell[CellGroupData[{ +Cell[10588, 317, 769, 23, 127, "Input",ExpressionUUID->"72de16af-d707-45d3-a95b-a3bd007f56ef"], +Cell[11360, 342, 2132, 41, 743, "Output",ExpressionUUID->"9480aa9f-a717-45f4-b3c1-addffca0ae58"] +}, Open ]], +Cell[CellGroupData[{ +Cell[13529, 388, 928, 29, 207, "Input",ExpressionUUID->"4b10af3a-a9cc-4fe3-bf00-6896aeeeaa8f"], +Cell[14460, 419, 1808, 37, 1088, "Output",ExpressionUUID->"d020b703-cd93-4ce8-a656-2dcfa0f3af53"] +}, Open ]], +Cell[16283, 459, 237, 6, 77, "Text",ExpressionUUID->"876e3ed5-6e8d-47e0-9ca4-743b1adaf708"], +Cell[CellGroupData[{ +Cell[16545, 469, 1009, 31, 207, "Input",ExpressionUUID->"53e980f9-37f4-443f-9547-0fb69514fecc"], +Cell[17557, 502, 1833, 37, 1097, "Output",ExpressionUUID->"3c4c386e-d59c-4551-8218-3d4a996c1d25"] +}, Open ]], +Cell[19405, 542, 572, 12, 168, "Text",ExpressionUUID->"c10d2856-d7bf-4d90-bcb3-ce0a55ad610f"], +Cell[CellGroupData[{ +Cell[20002, 558, 439, 14, 127, "Input",ExpressionUUID->"922e013f-a8d9-42ec-9f0d-9665f8e654c3"], +Cell[20444, 574, 347, 10, 120, "Output",ExpressionUUID->"9e704cf5-9e13-4825-9e03-f24f3bacb049"] +}, Open ]], +Cell[CellGroupData[{ +Cell[20828, 589, 289, 7, 78, "Input",ExpressionUUID->"2cb5418e-d92d-43df-ab99-85fbe81cc54f"], +Cell[21120, 598, 410, 12, 127, "Output",ExpressionUUID->"02e5c93b-0e82-4b7d-a031-2e36790fe261"] +}, Open ]], +Cell[21545, 613, 179, 3, 77, "Text",ExpressionUUID->"a41ccc35-b5d5-4df5-b8c3-8e5867aef1cf"], +Cell[CellGroupData[{ +Cell[21749, 620, 263, 7, 78, "Input",ExpressionUUID->"1ff5ba50-aac4-4e63-b58b-075ce8a614f0"], +Cell[22015, 629, 223, 6, 78, "Output",ExpressionUUID->"7ee70b82-bce6-40b1-8408-656f1529801f"] +}, Open ]], +Cell[CellGroupData[{ +Cell[22275, 640, 310, 5, 71, "Subsubsection",ExpressionUUID->"24309d09-0367-4b0b-ad2c-754d2fef5c0e"], +Cell[22588, 647, 960, 22, 77, "Text",ExpressionUUID->"68fd811c-e53f-4b9b-a3c0-1ad1c408144e"] +}, Open ]], +Cell[CellGroupData[{ +Cell[23585, 674, 397, 6, 71, "Subsubsection",ExpressionUUID->"57290fed-efd0-44d2-8889-1127cb5522a3"], +Cell[23985, 682, 1234, 28, 151, "Text",ExpressionUUID->"cff07c96-34d1-4f12-8a7d-36bfa18dd4ca"], +Cell[CellGroupData[{ +Cell[25244, 714, 385, 9, 78, "Input",ExpressionUUID->"e1a15929-f7cb-47fd-9710-0566528aef82"], +Cell[25632, 725, 319, 9, 78, "Output",ExpressionUUID->"89d412fb-4a6d-429c-9f82-04b3ce12492f"] +}, Open ]], +Cell[CellGroupData[{ +Cell[25988, 739, 315, 7, 78, "Input",ExpressionUUID->"497361c6-a8e6-4820-b11d-eba88b766705"], +Cell[26306, 748, 327, 8, 127, "Output",ExpressionUUID->"ec300727-d5e6-41b2-bc23-5a69ecbb736b"] +}, Open ]] +}, Open ]] +}, Closed]] +}, Closed]], +Cell[CellGroupData[{ +Cell[26706, 764, 332, 5, 65, "Section",ExpressionUUID->"e0554370-a9b3-4d8f-baf3-5b8d86b4d15b"], +Cell[CellGroupData[{ +Cell[27063, 773, 160, 3, 67, "Subsection",ExpressionUUID->"e8647bd2-c630-4afa-8af9-25d300729b04"], +Cell[27226, 778, 1702, 40, 610, "Text",ExpressionUUID->"59b3ff5b-28bd-474d-b760-08f76a51d0a4"], +Cell[28931, 820, 2029, 59, 246, "Text",ExpressionUUID->"6dd72596-e66a-41c9-9d67-b158c959ed83"], +Cell[CellGroupData[{ +Cell[30985, 883, 697, 25, 235, "Input",ExpressionUUID->"55ea47c1-5afc-41eb-b248-9498217e514d"], +Cell[31685, 910, 339, 11, 150, "Output",ExpressionUUID->"55adb479-7e78-49e9-8a8d-86dfd097cbec"] +}, Open ]], +Cell[32039, 924, 537, 14, 126, "Text",ExpressionUUID->"ba06d15a-7139-4fa8-bd15-dfc475594e2b"], +Cell[32579, 940, 899, 25, 168, "Text",ExpressionUUID->"cc7094ca-48e3-4dfe-9a0e-cad216f631f7"], +Cell[CellGroupData[{ +Cell[33503, 969, 541, 19, 235, "Input",ExpressionUUID->"e547c90a-d03f-48c6-b9a2-d46d1811a9aa"], +Cell[34047, 990, 337, 11, 150, "Output",ExpressionUUID->"726504dd-f95a-4267-887e-fa79d14c1b56"] +}, Open ]], +Cell[CellGroupData[{ +Cell[34421, 1006, 428, 8, 110, "Subsubsection",ExpressionUUID->"19fcb08f-cef1-4f0b-851e-204451f81b5f"], +Cell[34852, 1016, 2178, 59, 737, "Text",ExpressionUUID->"20346cdb-2405-4e8d-b6dc-5218420720b2"], +Cell[37033, 1077, 171, 3, 120, "Text",ExpressionUUID->"f892946f-f291-4fd1-ab51-7c3843c79c47"], +Cell[CellGroupData[{ +Cell[37229, 1084, 622, 21, 246, "Input",ExpressionUUID->"6ac1835c-89b6-405d-a6a5-d408611ffe6b"], +Cell[37854, 1107, 363, 11, 150, "Output",ExpressionUUID->"3a121993-a18a-4b8c-869b-d5cd5e1c4544"] +}, Open ]], +Cell[38232, 1121, 2577, 79, 577, "Text",ExpressionUUID->"699fd76b-b65c-43a8-9271-f6d9479b7b5e"], +Cell[40812, 1202, 171, 3, 120, "Text",ExpressionUUID->"a9c07be6-763e-4eb9-90a4-daf30288e223"], +Cell[CellGroupData[{ +Cell[41008, 1209, 401, 12, 150, "Input",ExpressionUUID->"e18b4d29-b842-47cf-8b4a-c74a3f3bcaf1"], +Cell[41412, 1223, 337, 11, 150, "Output",ExpressionUUID->"65fabd40-9f07-4d87-ba1d-1c7e58864d68"] +}, Open ]], +Cell[41764, 1237, 1170, 30, 441, "Text",ExpressionUUID->"0658489f-4ac3-4f87-9733-58612ac4f32a"] +}, Open ]] +}, Closed]], +Cell[CellGroupData[{ +Cell[42983, 1273, 207, 4, 46, "Subsection",ExpressionUUID->"e2a372cb-28a5-4c1c-8dbc-d7b6868d9c8b"], +Cell[43193, 1279, 936, 15, 44, "Text",ExpressionUUID->"6d87ee01-7b2a-4c67-9f96-7167fd83e3b6"], +Cell[44132, 1296, 919, 20, 93, "Text",ExpressionUUID->"85774559-e169-45fc-9e68-278f0e4398ef"], +Cell[45054, 1318, 1353, 27, 159, "Text",ExpressionUUID->"d1b1de43-3816-4c63-93de-5975d0d80112"], +Cell[46410, 1347, 835, 24, 97, "Text",ExpressionUUID->"c64cdd2a-ad16-461a-9a59-626d15cb90a8"], +Cell[CellGroupData[{ +Cell[47270, 1375, 586, 15, 60, "Input",ExpressionUUID->"a311f301-be2d-45f8-bcb2-e675016090b3"], +Cell[47859, 1392, 2510, 80, 80, "Output",ExpressionUUID->"d6b5dc83-38e5-490e-a8fd-68b50013d7f3"] +}, Open ]], +Cell[50384, 1475, 370, 8, 64, "Text",ExpressionUUID->"5bd3f20b-dd2d-4e92-a445-f9c76a5c92ba"], +Cell[CellGroupData[{ +Cell[50779, 1487, 460, 12, 57, "Input",ExpressionUUID->"cb1d7f5f-565d-4256-b898-8c51a434c309"], +Cell[51242, 1501, 1756, 57, 80, "Output",ExpressionUUID->"aea1312f-55f3-41f4-a4c2-5d7d6cb0a9c8"] +}, Open ]], +Cell[53013, 1561, 1030, 27, 159, "Text",ExpressionUUID->"a7b26b4f-bb00-4086-ae61-f139786379d6"], +Cell[CellGroupData[{ +Cell[54068, 1592, 556, 15, 57, "Input",ExpressionUUID->"2e1cb6cc-c27f-49c3-ac84-deb74f07e6ee"], +Cell[54627, 1609, 344, 8, 79, "Output",ExpressionUUID->"eb05b389-4adb-412c-a490-2e41352af3c4"] +}, Open ]], +Cell[54986, 1620, 591, 16, 68, "Text",ExpressionUUID->"6b45ad0e-00b1-4d1d-ac77-1a35d800e88a"], +Cell[CellGroupData[{ +Cell[55602, 1640, 553, 15, 57, "Input",ExpressionUUID->"8e980d3a-5d73-464f-a23b-33e04e2ac57b"], +Cell[56158, 1657, 557, 16, 79, "Output",ExpressionUUID->"0c5f7d4e-28bf-448e-8d57-7edd7272c104"] +}, Open ]], +Cell[56730, 1676, 593, 16, 68, "Text",ExpressionUUID->"a60afced-54a0-4afe-a512-37eeea8c29ac"], +Cell[CellGroupData[{ +Cell[57348, 1696, 555, 15, 57, "Input",ExpressionUUID->"4af9e3c0-25a6-42e3-afd2-8615b434d799"], +Cell[57906, 1713, 802, 25, 80, "Output",ExpressionUUID->"92b19e0a-ddd9-42ef-9804-6c880b2d88a2"] +}, Open ]], +Cell[CellGroupData[{ +Cell[58745, 1743, 937, 24, 84, "Input",ExpressionUUID->"f900e2ca-9f25-46c8-9357-fd0d20e14373"], +Cell[59685, 1769, 7875, 140, 338, "Output",ExpressionUUID->"f6907b0f-1937-498e-a1bc-ed2ca8442399"] +}, Open ]], +Cell[67575, 1912, 432, 8, 73, "Text",ExpressionUUID->"94a62f9b-bf52-4a39-a92f-a9a726c6ccf5"], +Cell[68010, 1922, 499, 15, 40, "Input",ExpressionUUID->"f1b0f582-39dc-4bfb-8433-4d00f369bbfb"], +Cell[68512, 1939, 4625, 129, 296, "Text",ExpressionUUID->"b132e035-227d-4ef4-ad9c-313b44129e1c"], +Cell[73140, 2070, 3845, 113, 246, "Text",ExpressionUUID->"8939f1a7-008b-4245-8eee-aeff1eb87ef2"], +Cell[76988, 2185, 2890, 65, 491, "Text",ExpressionUUID->"824cfa99-bacf-454a-b7b3-128689879943"], +Cell[79881, 2252, 540, 13, 73, "Text",ExpressionUUID->"ba31bde4-919b-47b7-b6fe-ca97ffc76124"], +Cell[CellGroupData[{ +Cell[80446, 2269, 574, 17, 56, "Input",ExpressionUUID->"0362fd92-1034-4a7e-a6d8-22d1d67c7a1d"], +Cell[81023, 2288, 438, 13, 58, "Output",ExpressionUUID->"f68a7e6c-7d63-4a40-8383-806791bdee61"] +}, Open ]], +Cell[CellGroupData[{ +Cell[81498, 2306, 301, 7, 37, "Input",ExpressionUUID->"c7db40b4-64d5-4093-9d65-09298453b3a8"], +Cell[81802, 2315, 200, 4, 42, "Output",ExpressionUUID->"a1d91ce9-381d-4ab5-b1af-6bcacb93281a"] +}, Open ]], +Cell[82017, 2322, 791, 15, 131, "Text",ExpressionUUID->"8924f4b3-4dcd-4779-92e0-c2f8d3c1008b"], +Cell[CellGroupData[{ +Cell[82833, 2341, 326, 8, 37, "Input",ExpressionUUID->"f35b923a-df30-454c-9325-f96da2902d9b"], +Cell[83162, 2351, 178, 4, 42, "Output",ExpressionUUID->"288a4c0a-3bbc-40cb-b9b5-3f32847806bd"] +}, Open ]], +Cell[83355, 2358, 1476, 34, 131, "Text",ExpressionUUID->"da894a18-5657-4bd6-98ca-45d240c75eba"], +Cell[CellGroupData[{ +Cell[84856, 2396, 497, 9, 56, "Subsubsection",ExpressionUUID->"b453616a-bd0d-42e6-9227-e7fc2cd8cf89"], +Cell[85356, 2407, 1951, 53, 203, "Text",ExpressionUUID->"d9ec45aa-1b0f-43f2-9bb5-0362c2e60df7"], +Cell[87310, 2462, 329, 11, 44, "Text",ExpressionUUID->"3c1e5d40-a65c-4cf9-bc45-c643cdd6c4d9"], +Cell[87642, 2475, 1655, 48, 261, "Text",ExpressionUUID->"64723ab7-8df1-4d2b-8afc-785ce7c57645"], +Cell[89300, 2525, 162, 3, 44, "Text",ExpressionUUID->"77561f68-7936-4f90-89b6-d71709974977"], +Cell[CellGroupData[{ +Cell[89487, 2532, 721, 21, 60, "Input",ExpressionUUID->"a776d04c-6096-410d-911b-3b000d6ba455"], +Cell[90211, 2555, 869, 27, 65, "Output",ExpressionUUID->"76b1f466-857b-4e74-b696-aa5cb22f57d5"] +}, Open ]], +Cell[91095, 2585, 200, 3, 44, "Text",ExpressionUUID->"b06c4621-0993-4cd2-a21c-429a0ce15561"], +Cell[CellGroupData[{ +Cell[91320, 2592, 326, 8, 37, "Input",ExpressionUUID->"33d00c46-6105-427c-978d-44cd120941e5"], +Cell[91649, 2602, 225, 5, 42, "Output",ExpressionUUID->"d33da08e-160d-41df-b6f8-5978952454fc"] +}, Open ]], +Cell[91889, 2610, 826, 19, 131, "Text",ExpressionUUID->"c86419b4-f324-4669-bf14-72d95e3c7ceb"], +Cell[CellGroupData[{ +Cell[92740, 2633, 348, 8, 37, "Input",ExpressionUUID->"3ef9792e-37f1-4e33-b3a8-6f9dc2097834"], +Cell[93091, 2643, 292, 7, 57, "Output",ExpressionUUID->"cd3965e1-b09b-411c-a648-0b0e629815da"] +}, Open ]], +Cell[CellGroupData[{ +Cell[93420, 2655, 185, 4, 37, "Input",ExpressionUUID->"e0aca7e7-144d-434a-a01b-8ee771b2653a"], +Cell[93608, 2661, 175, 5, 60, "Output",ExpressionUUID->"3258bdac-e990-480b-b516-f9b5f70b562a"] +}, Open ]], +Cell[93798, 2669, 825, 19, 131, "Text",ExpressionUUID->"29aa8fb3-7deb-469f-93af-a9d84cff95f0"], +Cell[94626, 2690, 213, 4, 44, "Text",ExpressionUUID->"e6a6cfb3-593b-4a6b-a754-7baf21d438bf"], +Cell[CellGroupData[{ +Cell[94864, 2698, 558, 14, 37, "Input",ExpressionUUID->"8714f100-ee34-4738-87ef-ede441db7f31"], +Cell[95425, 2714, 428, 11, 42, "Output",ExpressionUUID->"d9d92a76-9288-446a-8f82-ec22a1b44396"] +}, Open ]], +Cell[95868, 2728, 200, 3, 44, "Text",ExpressionUUID->"a1c73d06-0283-4f6f-909f-2fe5fd08c848"], +Cell[CellGroupData[{ +Cell[96093, 2735, 326, 8, 37, "Input",ExpressionUUID->"75ba2372-4bc7-4df4-9a61-eb50dfdc070f"], +Cell[96422, 2745, 225, 4, 42, "Output",ExpressionUUID->"310b81b8-6869-47ec-8053-d2b08e9715be"] +}, Open ]], +Cell[96662, 2752, 812, 19, 102, "Text",ExpressionUUID->"3ed079b4-159e-46d6-b9d2-bb511858a350"], +Cell[CellGroupData[{ +Cell[97499, 2775, 348, 8, 37, "Input",ExpressionUUID->"12664078-cfad-427d-816b-4be9ab8b8a14"], +Cell[97850, 2785, 264, 5, 42, "Output",ExpressionUUID->"f04c5f90-f355-4673-b974-8ab43c10a512"] +}, Open ]], +Cell[98129, 2793, 811, 19, 73, "Text",ExpressionUUID->"bccce608-5988-4c97-a855-bd2be51ad106"] +}, Open ]] +}, Open ]] +}, Closed]], +Cell[CellGroupData[{ +Cell[99001, 2819, 196, 3, 65, "Section",ExpressionUUID->"a2a07b40-06dd-4555-bb97-3abb2cd9f7a3"], +Cell[CellGroupData[{ +Cell[99222, 2826, 263, 4, 157, "Subsection",ExpressionUUID->"6ac5e1bb-5542-4ad0-8408-90ac15e3ca11"], +Cell[99488, 2832, 1065, 16, 120, "Text",ExpressionUUID->"1e3b067d-f60c-4ff3-afd8-3c290427ca0c"], +Cell[100556, 2850, 850, 17, 196, "Text",ExpressionUUID->"143bea1c-40de-42d9-a476-959ea71a3968"], +Cell[101409, 2869, 416, 8, 188, "Text",ExpressionUUID->"573123a8-1ff3-4dcf-a945-2c80810ecd23"], +Cell[101828, 2879, 326, 8, 120, "Text",ExpressionUUID->"b4bea33a-7b4c-44d8-8979-ca1c28adafe8"], +Cell[102157, 2889, 162, 3, 120, "Text",ExpressionUUID->"c452e00a-c18a-4525-87e2-2cf6520edd5d"], +Cell[CellGroupData[{ +Cell[102344, 2896, 525, 15, 121, "Input",ExpressionUUID->"fb65b155-6016-496b-a313-28530b16e3c3"], +Cell[102872, 2913, 288, 9, 151, "Output",ExpressionUUID->"2268ea6d-296f-483b-ba4c-42a5f342a946"] +}, Open ]], +Cell[103175, 2925, 539, 13, 120, "Text",ExpressionUUID->"fcc3e77c-e2fd-4788-9c92-f8726dbba130"], +Cell[CellGroupData[{ +Cell[103739, 2942, 840, 26, 220, "Input",ExpressionUUID->"4304aa7d-e533-4dab-a3dd-2cf7f1de261d"], +Cell[104582, 2970, 576, 20, 262, "Output",ExpressionUUID->"2c42cbf4-017a-4ba5-88e0-f0bda16abc98"] +}, Open ]], +Cell[105173, 2993, 366, 10, 120, "Text",ExpressionUUID->"05de0edb-fb88-48f5-bea8-d6e1faebcb5e"], +Cell[CellGroupData[{ +Cell[105564, 3007, 505, 14, 210, "Input",ExpressionUUID->"c2a1b75e-df8d-4ad1-bf2d-2c572a613662"], +Cell[106072, 3023, 246, 6, 137, "Output",ExpressionUUID->"bdd7674e-ec2c-4665-a907-e255e575bbb1"] +}, Open ]], +Cell[106333, 3032, 214, 4, 120, "Text",ExpressionUUID->"b15044b7-afe3-42fb-8ad3-49848a1fbe95"], +Cell[CellGroupData[{ +Cell[106572, 3040, 657, 17, 121, "Input",ExpressionUUID->"bd2a3e68-c2cc-4462-bcd1-23d7697253d3"], +Cell[107232, 3059, 329, 10, 151, "Output",ExpressionUUID->"fe6dc093-d105-4763-bcf2-ae97ff6c3eb3"] +}, Open ]], +Cell[CellGroupData[{ +Cell[107598, 3074, 695, 20, 121, "Input",ExpressionUUID->"60879615-4a14-4b9b-8e33-8dff4ed852a4"], +Cell[108296, 3096, 581, 10, 96, "Message",ExpressionUUID->"c56da930-1131-40f7-9927-0b6203956ac9"], +Cell[108880, 3108, 492, 15, 226, "Output",ExpressionUUID->"fb0de74f-42f8-4ab5-b5cc-bf3a7e6be932"] +}, Open ]], +Cell[109387, 3126, 201, 3, 120, "Text",ExpressionUUID->"34e02973-9e3f-4546-8c9b-5328b3e1f700"], +Cell[CellGroupData[{ +Cell[109613, 3133, 1096, 33, 366, "Input",ExpressionUUID->"22795aeb-d61b-4e3b-9220-d1a5337a9e40"], +Cell[110712, 3168, 2063, 42, 1722, "Output",ExpressionUUID->"e7ec6cc7-1552-4ce3-bfc0-65151baade76"] +}, Open ]], +Cell[CellGroupData[{ +Cell[112812, 3215, 710, 12, 110, "Subsubsection",ExpressionUUID->"e478712e-1285-4223-af1a-9cd518503832"], +Cell[113525, 3229, 1779, 45, 502, "Text",ExpressionUUID->"f7931284-0a87-4d28-9326-5ab53f843f2a"], +Cell[CellGroupData[{ +Cell[115329, 3278, 679, 20, 206, "Input",ExpressionUUID->"790c2919-a15e-46db-8846-d47e76c50a14"], +Cell[116011, 3300, 535, 10, 96, "Message",ExpressionUUID->"6c658f82-9b03-4796-9ab0-1082f3dc8fed"], +Cell[116549, 3312, 502, 15, 218, "Output",ExpressionUUID->"e1e9ac0d-24c9-4b40-a6ff-8d7f171b25ce"] +}, Open ]], +Cell[117066, 3330, 771, 18, 266, "Text",ExpressionUUID->"1040be7d-568e-44eb-b39d-67c0ed2002ea"], +Cell[CellGroupData[{ +Cell[117862, 3352, 687, 19, 228, "Input",ExpressionUUID->"8d2d7efc-166b-4baf-9e31-4f3235f70007"], +Cell[118552, 3373, 4915, 88, 1145, "Output",ExpressionUUID->"dae5cb29-070e-44bd-ae19-9172e325277d"] +}, Open ]] +}, Open ]] +}, Closed]], +Cell[CellGroupData[{ +Cell[123528, 3468, 209, 4, 112, "Subsection",ExpressionUUID->"58ceb75c-09a2-4a8b-bfb4-92009e759cd2"], +Cell[123740, 3474, 450, 9, 188, "Text",ExpressionUUID->"00483b84-7fd6-44fc-91da-732d218c2f7d"], +Cell[124193, 3485, 850, 18, 196, "Text",ExpressionUUID->"bf49b3d6-91da-4bfe-a8dc-6faeaf5cb3d0"], +Cell[125046, 3505, 1531, 36, 562, "Input",ExpressionUUID->"dc948b39-aaa6-44f1-8bbb-394906603b25"], +Cell[126580, 3543, 513, 11, 335, "Text",ExpressionUUID->"ce8154fb-dd94-44e3-9b8c-17424baf8b4b"], +Cell[127096, 3556, 187, 3, 120, "Text",ExpressionUUID->"2838ef50-526a-48f1-b5ba-959a98e5a849"], +Cell[CellGroupData[{ +Cell[127308, 3563, 528, 11, 121, "Input",ExpressionUUID->"c10177da-49e8-4bc0-b2d7-f35760d0cf96"], +Cell[127839, 3576, 3136, 53, 633, "Output",ExpressionUUID->"ee3bd96d-26c4-4148-b336-e9873c0bbe72"] +}, Open ]], +Cell[130990, 3632, 214, 4, 120, "Text",ExpressionUUID->"a96c73bf-9ca4-41d0-a489-1dbb5cbc5d8b"], +Cell[CellGroupData[{ +Cell[131229, 3640, 777, 20, 121, "Input",ExpressionUUID->"ca8208d5-8dee-40f6-ab5d-597aaae23723"], +Cell[132009, 3662, 1778, 35, 1133, "Output",ExpressionUUID->"480264ba-2562-4dc7-bcb9-4c65467e27fc"] +}, Open ]], +Cell[133802, 3700, 582, 13, 197, "Text",ExpressionUUID->"c8e6fc21-a714-4130-8bbf-e21840bc1edd"], +Cell[134387, 3715, 280, 6, 120, "Text",ExpressionUUID->"c2f894fe-029c-42f0-9944-db874a4a86f0"], +Cell[CellGroupData[{ +Cell[134692, 3725, 333, 9, 121, "Input",ExpressionUUID->"528b6743-9092-419f-a27c-3f4fd0938e0e"], +Cell[135028, 3736, 5462, 138, 1251, "Output",ExpressionUUID->"d89c91cc-12a2-441b-994e-f8c28ee9dfcb"] +}, Open ]], +Cell[CellGroupData[{ +Cell[140527, 3879, 428, 6, 110, "Subsubsection",ExpressionUUID->"9553666f-de5a-407a-aeb9-b5956a9e001b"], +Cell[140958, 3887, 993, 17, 262, "Text",ExpressionUUID->"bc9ffdcd-39e2-446e-92e6-bc228d896b78"], +Cell[CellGroupData[{ +Cell[141976, 3908, 171, 4, 121, "Input",ExpressionUUID->"b946961a-bc28-4972-bfb8-e6f5e36fc209"], +Cell[142150, 3914, 1150, 23, 258, "Print",ExpressionUUID->"353a083e-0028-4907-af1c-6a1b1a33e6bc", + CellTags->"Info3514654656-5782146"] +}, Open ]], +Cell[CellGroupData[{ +Cell[143337, 3942, 1994, 47, 633, "Input",ExpressionUUID->"a743e79f-784f-46b2-8a37-11af33266c90"], +Cell[145334, 3991, 349, 6, 121, "Output",ExpressionUUID->"4e89080b-ade0-498d-acac-484062e82c6d"] +}, Open ]], +Cell[CellGroupData[{ +Cell[145720, 4002, 677, 19, 121, "Input",ExpressionUUID->"c93ca56a-8631-450c-8711-eebe63283128"], +Cell[146400, 4023, 967, 21, 1133, "Output",ExpressionUUID->"3a56179d-ab8a-4830-9057-a6b9f6854dc5"] +}, Open ]] +}, Open ]] +}, Closed]], +Cell[CellGroupData[{ +Cell[147428, 4051, 263, 4, 112, "Subsection",ExpressionUUID->"58f64af0-0781-4aa2-9f1b-9b347d3e61c6"], +Cell[147694, 4057, 457, 10, 120, "Text",ExpressionUUID->"cd058551-75ba-4eb3-92b3-0d5086978cd0"], +Cell[148154, 4069, 947, 26, 206, "Input",ExpressionUUID->"a9619a38-4615-45df-b3e5-6c602325f296"], +Cell[CellGroupData[{ +Cell[149126, 4099, 226, 5, 121, "Input",ExpressionUUID->"1f6d2dc1-7850-4998-91fd-b519cf2402a1"], +Cell[149355, 4106, 577, 18, 121, "Output",ExpressionUUID->"65dd93eb-fbdd-4bcb-9abc-fe28e19a63fb"] +}, Open ]], +Cell[149947, 4127, 623, 13, 335, "Text",ExpressionUUID->"17fe90c5-4054-4cf2-b34a-604602898420"], +Cell[150573, 4142, 217, 5, 120, "Text",ExpressionUUID->"22dbf043-9638-4932-b9a9-b678355f1c16"], +Cell[CellGroupData[{ +Cell[150815, 4151, 212, 5, 121, "Input",ExpressionUUID->"74f8c6a0-9134-4d49-ab17-bc0960733b52"], +Cell[151030, 4158, 278, 8, 121, "Output",ExpressionUUID->"23cdf5a0-e55d-4e76-aa15-0c4584ea8e54"] +}, Open ]], +Cell[CellGroupData[{ +Cell[151345, 4171, 540, 13, 121, "Input",ExpressionUUID->"a9699b78-7502-413f-9a1c-0cd324b3563f"], +Cell[151888, 4186, 5016, 89, 1133, "Output",ExpressionUUID->"57d7f0df-c484-49ec-99c6-f0290561e912"] +}, Open ]] +}, Closed]] +}, Closed]], +Cell[CellGroupData[{ +Cell[156965, 4282, 291, 4, 65, "Section",ExpressionUUID->"f9d39d79-2a68-422a-a40f-655b104ca3d5"], +Cell[157259, 4288, 1093, 18, 101, "Text",ExpressionUUID->"5001d2bb-dd3f-4e30-a192-73e2954ad9b7"], +Cell[CellGroupData[{ +Cell[158377, 4310, 197, 3, 42, "Subsection",ExpressionUUID->"7e12f097-d403-4e1e-8056-efda95e775ee"], +Cell[158577, 4315, 213, 3, 35, "Text",ExpressionUUID->"79f8d706-301d-446b-85c0-dde780c58e76"], +Cell[CellGroupData[{ +Cell[158815, 4322, 574, 15, 33, "Input",ExpressionUUID->"dacf77d1-44f5-4b43-bc29-0fa0d5ac36d1"], +Cell[159392, 4339, 631, 12, 26, "Message",ExpressionUUID->"2e40cf07-d7ef-4af0-b00c-a6a586d9abd1"], +Cell[160026, 4353, 471, 14, 64, "Output",ExpressionUUID->"c4963338-8faa-49cc-b25d-914e2345320b"] +}, Open ]], +Cell[160512, 4370, 671, 12, 123, "Text",ExpressionUUID->"757b6524-1bbf-4879-9643-9ab3ba6b6485"], +Cell[CellGroupData[{ +Cell[161208, 4386, 969, 24, 33, "Input",ExpressionUUID->"70d54709-16b4-4d50-a40c-1deef37762f8"], +Cell[162180, 4412, 504, 10, 33, "Output",ExpressionUUID->"2e775eb2-64a7-4bb7-929c-d14d1bd552fa"] +}, Open ]], +Cell[162699, 4425, 276, 4, 35, "Text",ExpressionUUID->"32c6ad4a-b22f-4b98-909d-6a336cd16ac2"], +Cell[CellGroupData[{ +Cell[163000, 4433, 903, 25, 68, "Input",ExpressionUUID->"6897de05-9760-40e5-bd0e-d19d142f71ec"], +Cell[163906, 4460, 527, 13, 55, "Output",ExpressionUUID->"7260dc89-b4fe-4f2c-9a06-200ac7c2c000"] +}, Open ]], +Cell[164448, 4476, 3633, 88, 161, "Text",ExpressionUUID->"e87db525-cef4-44ae-83fc-7e378908e535"], +Cell[168084, 4566, 219, 3, 35, "Text",ExpressionUUID->"5b95f0c5-09b6-491e-83d4-02f5ba491ff0"], +Cell[CellGroupData[{ +Cell[168328, 4573, 403, 11, 57, "Input",ExpressionUUID->"ebf97833-1d1c-448f-bc07-b0e3e3b4bc58"], +Cell[168734, 4586, 424, 12, 42, "Output",ExpressionUUID->"f5e77a29-becb-4327-ab99-cb096a1fee80"] +}, Open ]], +Cell[CellGroupData[{ +Cell[169195, 4603, 230, 5, 33, "Input",ExpressionUUID->"b77696b3-0607-4130-af39-3af596842bd8"], +Cell[169428, 4610, 322, 8, 33, "Output",ExpressionUUID->"602f541e-f6c6-4693-b6d8-2956887f9d9f"] +}, Open ]], +Cell[169765, 4621, 179, 3, 35, "Text",ExpressionUUID->"dfa9fe7d-52f5-4709-adbc-7c86baf09615"], +Cell[169947, 4626, 1625, 38, 129, "Input",ExpressionUUID->"a9c27bf1-3e48-4a2b-9665-0ae68b43f061"], +Cell[171575, 4666, 240, 4, 35, "Text",ExpressionUUID->"cce32caf-a2ac-4ca5-ba9a-e8e9a1ac094c"], +Cell[CellGroupData[{ +Cell[171840, 4674, 835, 21, 33, "Input",ExpressionUUID->"c7fb5c51-1831-4453-af5b-47bede8f7315"], +Cell[172678, 4697, 3134, 57, 310, "Output",ExpressionUUID->"e30590a9-c540-40ed-8ba0-050cdb5befc3"] +}, Open ]], +Cell[175827, 4757, 306, 7, 43, "Text",ExpressionUUID->"5bdff7e1-684c-4997-9893-1a80a59e1f64"], +Cell[CellGroupData[{ +Cell[176158, 4768, 665, 19, 41, "Input",ExpressionUUID->"58a7e84e-bc5e-4cd9-b543-49962fd9bf0a"], +Cell[176826, 4789, 705, 21, 50, "Output",ExpressionUUID->"a4d60120-14aa-44a6-8025-7454aa30fd11"] +}, Open ]], +Cell[177546, 4813, 462, 8, 98, "Text",ExpressionUUID->"b7f8b7ff-6f72-4b62-96d5-5529f7b87b30"] +}, Open ]], +Cell[CellGroupData[{ +Cell[178045, 4826, 197, 3, 38, "Subsection",ExpressionUUID->"a2bce3ad-29ce-460d-88e0-0ddbaecc8c43"], +Cell[178245, 4831, 367, 10, 55, "Text",ExpressionUUID->"c6436ce7-86e7-43c3-b835-b7b8ec54be39"], +Cell[CellGroupData[{ +Cell[178637, 4845, 625, 16, 41, "Input",ExpressionUUID->"62782af1-49c7-4a1d-a048-815c4b4d312f"], +Cell[179265, 4863, 496, 15, 80, "Output",ExpressionUUID->"4bfc5d0b-b53b-4c92-b189-8b9a8a4f91c2"] +}, Open ]], +Cell[179776, 4881, 435, 8, 71, "Text",ExpressionUUID->"24bc2abf-6754-4aa9-a460-eeeaf53144db"], +Cell[CellGroupData[{ +Cell[180236, 4893, 994, 25, 41, "Input",ExpressionUUID->"f37908d9-c92b-4adb-8853-b38c4c4192ed"], +Cell[181233, 4920, 514, 10, 41, "Output",ExpressionUUID->"b3561524-58c2-44dc-bf33-19f3e83f3263"] +}, Open ]], +Cell[181762, 4933, 457, 10, 126, "Text",ExpressionUUID->"e0384f15-834c-4d94-b0c5-cb3b97420d7c"], +Cell[CellGroupData[{ +Cell[182244, 4947, 928, 26, 85, "Input",ExpressionUUID->"0f5ce446-cf44-4887-a5fd-4423e3fac872"], +Cell[183175, 4975, 540, 13, 68, "Output",ExpressionUUID->"faaace4c-5efc-480c-b8d0-c8d2201fb32d"] +}, Open ]], +Cell[183730, 4991, 405, 8, 43, "Text",ExpressionUUID->"41e13911-680e-4263-93c7-eb11a49e322d"], +Cell[184138, 5001, 237, 4, 43, "Text",ExpressionUUID->"293f34b2-086e-481d-a88e-3127fdd22ed4"], +Cell[184378, 5007, 1739, 41, 66, "Input",ExpressionUUID->"19955c9c-c237-4299-ae2f-385a0a345cd6"], +Cell[186120, 5050, 292, 5, 43, "Text",ExpressionUUID->"3e85b415-6994-47ae-bdd9-a33fd66a6a43"], +Cell[CellGroupData[{ +Cell[186437, 5059, 687, 18, 41, "Input",ExpressionUUID->"61c1fca2-1d25-404f-ac70-10ce3b7c3398"], +Cell[187127, 5079, 5124, 91, 386, "Output",ExpressionUUID->"7a9c3600-b070-4979-8624-5a957cf57ca1"] +}, Open ]], +Cell[192266, 5173, 376, 10, 43, "Text",ExpressionUUID->"da642108-c0a8-4dcc-a420-5c13d26a2602"], +Cell[CellGroupData[{ +Cell[192667, 5187, 728, 21, 41, "Input",ExpressionUUID->"5b28911a-3582-49d2-a996-7d8fb3def27e"], +Cell[193398, 5210, 1173, 34, 80, "Output",ExpressionUUID->"85661489-628d-4104-a702-17f201a71056"] +}, Open ]] +}, Closed]] +}, Closed]], +Cell[CellGroupData[{ +Cell[194632, 5251, 201, 3, 65, "Section",ExpressionUUID->"19ba622d-4e76-4a8c-a456-266950e623bf"], +Cell[194836, 5256, 1640, 36, 868, "Text",ExpressionUUID->"c745fa0b-2400-4d93-8e80-af69d9d1bdec"], +Cell[CellGroupData[{ +Cell[196501, 5296, 160, 3, 81, "Subsection",ExpressionUUID->"b5030c12-f365-4c49-bc72-9ddf08ba9dcf"], +Cell[196664, 5301, 540, 12, 188, "Text",ExpressionUUID->"95c1bf97-fd52-4cec-97bd-0eeff9d637ee"], +Cell[197207, 5315, 233, 4, 120, "Text",ExpressionUUID->"64e9c8fa-6a84-434f-a573-70054ad6e192"], +Cell[CellGroupData[{ +Cell[197465, 5323, 802, 26, 171, "Input",ExpressionUUID->"064c0c7f-fac7-484a-88ca-062fea785f14"], +Cell[198270, 5351, 315, 10, 157, "Output",ExpressionUUID->"bfbe1d41-ef42-440b-b7f6-74ca26a9918a"] +}, Open ]], +Cell[198600, 5364, 772, 20, 296, "Text",ExpressionUUID->"e18bc38e-3af4-4ebc-9275-bad02d3fc5ef"] +}, Closed]], +Cell[CellGroupData[{ +Cell[199409, 5389, 208, 4, 58, "Subsection",ExpressionUUID->"ad16f01f-31e5-4acf-b6d9-945d60c058a9"], +Cell[199620, 5395, 4245, 130, 1768, "Text",ExpressionUUID->"0e3237a5-0c14-42f5-9ef7-1f85d7372688"], +Cell[203868, 5527, 1808, 32, 840, "Text",ExpressionUUID->"f8b0a314-f0df-493a-b48c-32fd1769ea94"], +Cell[205679, 5561, 274, 6, 120, "Text",ExpressionUUID->"3a9ab152-0b77-41b8-90da-ca717514a666"], +Cell[205956, 5569, 454, 12, 197, "Input",ExpressionUUID->"b4b9976b-2d47-430f-a300-f8f889415d91"], +Cell[206413, 5583, 326, 7, 188, "Text",ExpressionUUID->"e6e3a9ae-4680-4b3e-9a42-c1c2ec8d3c60"], +Cell[CellGroupData[{ +Cell[206764, 5594, 1215, 33, 197, "Input",ExpressionUUID->"c12a312f-b33b-4e0a-93d7-3f90b7ff94b4"], +Cell[207982, 5629, 275, 9, 121, "Output",ExpressionUUID->"1b7940f6-cd18-4472-99d7-9ec0615b1b1c"] +}, Open ]], +Cell[208272, 5641, 219, 4, 120, "Text",ExpressionUUID->"8a46c20a-c617-4220-a1c3-8385a4e2bec5"], +Cell[CellGroupData[{ +Cell[208516, 5649, 190, 4, 121, "Input",ExpressionUUID->"eebf09de-33e2-4ef8-8c89-cddead8bbf29"], +Cell[208709, 5655, 344, 12, 157, "Output",ExpressionUUID->"55a9be03-cd32-442e-8c54-f3582ad448d5"] +}, Open ]], +Cell[209068, 5670, 1154, 25, 668, "Text",ExpressionUUID->"4c2c6ca4-9859-4037-be95-55e188f5b51a"] +}, Closed]], +Cell[CellGroupData[{ +Cell[210259, 5700, 255, 4, 58, "Subsection",ExpressionUUID->"e83b0893-70af-4294-a70a-94dc75e2de25"], +Cell[210517, 5706, 428, 8, 262, "Text",ExpressionUUID->"387787a9-3664-4801-a41f-d6fe64c431b4"], +Cell[210948, 5716, 1905, 44, 562, "Input",ExpressionUUID->"24d86754-888c-4944-957e-8abe0942fe45"], +Cell[212856, 5762, 513, 11, 477, "Text",ExpressionUUID->"3da61e30-63c4-414f-950a-b8bf68d9cb9b"], +Cell[213372, 5775, 271, 6, 120, "Text",ExpressionUUID->"c9d99922-8617-4632-9b94-045d2b428fe0"], +Cell[CellGroupData[{ +Cell[213668, 5785, 561, 12, 121, "Input",ExpressionUUID->"61de1e26-2fd5-4130-83f8-c149b1b1f884"], +Cell[214232, 5799, 9523, 208, 2445, "Output",ExpressionUUID->"47611ce0-2125-4b36-89dd-b42d8b7682db"] +}, Open ]], +Cell[223770, 6010, 341, 5, 120, "Text",ExpressionUUID->"25e7b837-c443-4112-949e-912b357896ba"], +Cell[CellGroupData[{ +Cell[224136, 6019, 1027, 29, 272, "Input",ExpressionUUID->"fa209c03-e262-41ff-80f5-c0fc7049a4cf"], +Cell[225166, 6050, 3414, 64, 1133, "Output",ExpressionUUID->"bddef3f5-0a3a-4e13-afbc-5f6245eb5cc0"] +}, Open ]], +Cell[228595, 6117, 376, 7, 262, "Text",ExpressionUUID->"650ae84b-5ec7-4b74-8867-978a9284c976"] +}, Closed]], +Cell[CellGroupData[{ +Cell[229008, 6129, 278, 3, 58, "Subsection",ExpressionUUID->"855ac022-6df1-4808-b4e6-bd05ae13e8d7"], +Cell[229289, 6134, 948, 23, 1195, "Text",ExpressionUUID->"adbfe2dd-c363-48a4-a73d-6c3886b8fe53"], +Cell[230240, 6159, 322, 5, 120, "Text",ExpressionUUID->"dacd7d5c-f30d-43d8-aade-b70915a608ab"], +Cell[CellGroupData[{ +Cell[230587, 6168, 1357, 48, 157, "Input",ExpressionUUID->"098a5b2f-d58c-49f7-8e01-49d551a1f714"], +Cell[231947, 6218, 556, 18, 200, "Output",ExpressionUUID->"a8f24c50-9f41-48f7-a6d3-72aa8107d410"] +}, Open ]], +Cell[232518, 6239, 677, 19, 220, "Text",ExpressionUUID->"7dc3ed25-f099-4e15-a3c3-4187128ca5f3"], +Cell[233198, 6260, 203, 4, 120, "Text",ExpressionUUID->"9a121723-c825-4085-bfe6-d6e64694c4af"], +Cell[233404, 6266, 779, 22, 197, "Input",ExpressionUUID->"71426e94-b246-452c-be0b-9c386eb2818a"], +Cell[CellGroupData[{ +Cell[234208, 6292, 842, 24, 197, "Input",ExpressionUUID->"5de1e242-2f7a-4bad-ac49-a8f9982ef37c"], +Cell[235053, 6318, 646, 20, 121, "Output",ExpressionUUID->"377ffe04-779a-4bf9-a404-958d04aa437a"] +}, Open ]], +Cell[235714, 6341, 236, 6, 120, "Text",ExpressionUUID->"dbad70cc-7af3-4a3c-b334-bdbe93532d09"], +Cell[CellGroupData[{ +Cell[235975, 6351, 400, 12, 213, "Input",ExpressionUUID->"38d15bf3-de85-4369-b68f-01e5e65db9da"], +Cell[236378, 6365, 445, 14, 200, "Output",ExpressionUUID->"4db48e60-f0fb-4978-b03b-40f6acfed804"] +}, Open ]], +Cell[CellGroupData[{ +Cell[236860, 6384, 190, 4, 121, "Input",ExpressionUUID->"b4bf41ef-f692-4aac-84d9-1b3ccd5a58e5"], +Cell[237053, 6390, 556, 18, 157, "Output",ExpressionUUID->"37bc675d-09ed-40ec-a5cc-e7b1b8f541f3"] +}, Open ]], +Cell[237624, 6411, 1289, 31, 668, "Text",ExpressionUUID->"cf31d981-a20d-4e1f-bc3e-6384ee4a48c3"], +Cell[238916, 6444, 1298, 29, 316, "Text",ExpressionUUID->"86f59446-8f78-4386-8bd3-46be8378d541"], +Cell[240217, 6475, 1190, 37, 408, "Text",ExpressionUUID->"e10779af-4db5-4e4c-83af-e298fca8bb43"], +Cell[241410, 6514, 686, 19, 243, "Text",ExpressionUUID->"191a1bec-aaf8-4c6c-bb38-585b844c8776"], +Cell[242099, 6535, 290, 7, 120, "Text",ExpressionUUID->"bb1b30ee-b64b-44be-8fed-3512c87c9db5"], +Cell[242392, 6544, 2440, 58, 706, "Input",ExpressionUUID->"ac165de2-81ec-43b8-85f4-e5f933894914"], +Cell[244835, 6604, 314, 6, 120, "Text",ExpressionUUID->"4a4e8c9e-4873-421f-bc44-416db59e6084"], +Cell[CellGroupData[{ +Cell[245174, 6614, 948, 18, 121, "Input",ExpressionUUID->"bd2c85b5-2090-42ef-9267-7b6b37605ab3"], +Cell[246125, 6634, 9852, 213, 2518, "Output",ExpressionUUID->"88b0b3db-adf6-493b-8d2a-ec64675522b4"] +}, Open ]], +Cell[255992, 6850, 387, 6, 120, "Text",ExpressionUUID->"e2c4c24e-d9db-4fab-b50f-3254ab48abc2"], +Cell[CellGroupData[{ +Cell[256404, 6860, 1264, 33, 488, "Input",ExpressionUUID->"58eda0db-0570-4b84-95fe-1e162b7b6aa7"], +Cell[257671, 6895, 3406, 63, 1112, "Output",ExpressionUUID->"af794f0f-9f90-4517-834d-e164ba5a68af"] +}, Open ]], +Cell[261092, 6961, 360, 7, 188, "Text",ExpressionUUID->"53242a9e-fb52-444b-8c41-069bc627348e"], +Cell[261455, 6970, 552, 11, 402, "Text",ExpressionUUID->"da97b996-df39-49ee-a52f-cde427c9581a"], +Cell[CellGroupData[{ +Cell[262032, 6985, 1277, 33, 415, "Input",ExpressionUUID->"4075c550-69ae-409a-bee8-92d534acc1fe"], +Cell[263312, 7020, 2559, 48, 1112, "Output",ExpressionUUID->"eaf70f06-5e5f-45b8-94e8-a1f9262f7ebf"] +}, Open ]] +}, Closed]], +Cell[CellGroupData[{ +Cell[265920, 7074, 326, 5, 58, "Subsection",ExpressionUUID->"f495cd23-1926-49f5-ac86-08cda9e6d02e"], +Cell[266249, 7081, 768, 14, 207, "Text",ExpressionUUID->"07acc4e2-a81f-42a6-b6fe-9556df280f78"], +Cell[CellGroupData[{ +Cell[267042, 7099, 293, 6, 63, "Input",ExpressionUUID->"af5aff32-a541-47f4-afaa-c98e3d3cc6f4"], +Cell[267338, 7107, 205, 4, 63, "Output",ExpressionUUID->"f5ecae08-b9cd-4c94-9103-9fa4b08ef4ad"] +}, Open ]], +Cell[267558, 7114, 321, 7, 97, "Text",ExpressionUUID->"f5ed53f9-438e-40e5-9a90-770ffec1ea9d"], +Cell[267882, 7123, 2977, 67, 362, "Input",ExpressionUUID->"130a8b2f-f4e7-485f-aa9b-31f483f6c9ed"], +Cell[270862, 7192, 1119, 20, 282, "Text",ExpressionUUID->"41a744b8-2fa5-41a9-85e8-fe64b957afbb"], +Cell[271984, 7214, 271, 6, 62, "Text",ExpressionUUID->"7c06f4c4-1dce-4a35-ba8b-08422a7e9acd"], +Cell[CellGroupData[{ +Cell[272280, 7224, 561, 12, 63, "Input",ExpressionUUID->"e0113959-d55e-40e8-816c-00b677b61b77"], +Cell[272844, 7238, 6350, 208, 362, "Output",ExpressionUUID->"3cb66346-4a46-4413-acf6-840ee7cf3197"] +}, Open ]], +Cell[279209, 7449, 341, 5, 62, "Text",ExpressionUUID->"0d49130b-62d4-4e30-b25a-08e467c2d605"], +Cell[CellGroupData[{ +Cell[279575, 7458, 1122, 30, 102, "Input",ExpressionUUID->"7ab64719-62ec-4b2f-a883-285fca7554a8"], +Cell[280700, 7490, 1611, 35, 581, "Output",ExpressionUUID->"bd7a2d8a-949b-4334-b532-3f693bba10c6"] +}, Open ]], +Cell[282326, 7528, 628, 11, 172, "Text",ExpressionUUID->"e5da17a1-b409-4435-917a-6e4baadee48e"] +}, Closed]] +}, Closed]], +Cell[CellGroupData[{ +Cell[283003, 7545, 257, 4, 65, "Section",ExpressionUUID->"53213a5b-792a-41e6-b05c-74d43a033327"], +Cell[283263, 7551, 1244, 21, 126, "Text",ExpressionUUID->"881e1045-62f3-4f95-921c-137acec255aa"], +Cell[284510, 7574, 569, 10, 71, "Text",ExpressionUUID->"9242ac77-9484-45de-8973-e502b05d2b3a"], +Cell[285082, 7586, 458, 9, 71, "Text",ExpressionUUID->"a415af70-2efe-4cd2-9c17-30c65db0cdbe"], +Cell[CellGroupData[{ +Cell[285565, 7599, 784, 21, 66, "Input",ExpressionUUID->"dc24c4c8-8280-499b-b0a1-ce20dd786f2f"], +Cell[286352, 7622, 517, 15, 70, "Output",ExpressionUUID->"3e674a4c-7e23-4281-9a17-143d56cf917b"] +}, Open ]], +Cell[286884, 7640, 221, 4, 43, "Text",ExpressionUUID->"390da005-5f56-4165-8aae-ed0a40e614f8"], +Cell[287108, 7646, 841, 22, 66, "Input",ExpressionUUID->"c72a4d3a-7497-4753-9a46-bef194f869ef"], +Cell[287952, 7670, 370, 8, 71, "Text",ExpressionUUID->"84d63635-3dc1-47e0-98b7-67597a441955"], +Cell[CellGroupData[{ +Cell[288347, 7682, 1399, 36, 66, "Input",ExpressionUUID->"ca6abbe4-a86f-49af-b040-ebe6af90a77d"], +Cell[289749, 7720, 616, 15, 41, "Output",ExpressionUUID->"191bd491-03d8-49f1-bef5-adfcb4146094"] +}, Open ]], +Cell[290380, 7738, 283, 4, 43, "Text",ExpressionUUID->"44aa97c0-0020-4f0c-aca5-64082cce01e8"], +Cell[CellGroupData[{ +Cell[290688, 7746, 190, 4, 41, "Input",ExpressionUUID->"a4a00e90-04d1-41a7-950e-a099dbac9574"], +Cell[290881, 7752, 313, 7, 41, "Output",ExpressionUUID->"56de0aa6-d2a5-4d8c-92c3-08392fff5b39"] +}, Open ]], +Cell[291209, 7762, 403, 8, 71, "Text",ExpressionUUID->"07290a94-5cc5-4b13-9777-2b8ec8a032d5"], +Cell[291615, 7772, 985, 20, 57, "Text",ExpressionUUID->"f395aaa3-2cdb-4d89-aace-c08aecef9b5f"], +Cell[CellGroupData[{ +Cell[292625, 7796, 1483, 38, 97, "Input",ExpressionUUID->"0b745602-e472-4031-bbd0-a35fd19d3672"], +Cell[294111, 7836, 695, 18, 70, "Output",ExpressionUUID->"421bd145-5748-4cec-94ca-be9862509029"] +}, Open ]], +Cell[294821, 7857, 219, 4, 43, "Text",ExpressionUUID->"18aa4e6b-a3f4-4818-bc57-f79b931ab81b"], +Cell[CellGroupData[{ +Cell[295065, 7865, 190, 4, 41, "Input",ExpressionUUID->"c7fe8a58-9e45-4024-b000-939b389ce282"], +Cell[295258, 7871, 507, 16, 52, "Output",ExpressionUUID->"833ffb50-eb7e-41e3-91d3-a0322b8ca0ab"] +}, Open ]], +Cell[295780, 7890, 888, 20, 85, "Text",ExpressionUUID->"e788a95b-c09c-4aa1-9e7a-5dcc6b917984"], +Cell[296671, 7912, 156, 3, 43, "Text",ExpressionUUID->"39b09d0a-8d3d-40d1-8287-08b73e4a8fff"], +Cell[296830, 7917, 2642, 64, 185, "Input",ExpressionUUID->"0666236d-e7fd-4351-90e8-5a6bf0b3a404"], +Cell[299475, 7983, 287, 7, 43, "Text",ExpressionUUID->"d4735e35-4d8f-4a7e-af8b-d6dd6d478987"], +Cell[CellGroupData[{ +Cell[299787, 7994, 874, 22, 72, "Input",ExpressionUUID->"88d67e5d-b0f3-4653-a493-6811758cf31d"], +Cell[300664, 8018, 475, 12, 41, "Output",ExpressionUUID->"10f0d594-1671-4246-8c60-e8e1a83d4a0b"] +}, Open ]], +Cell[301154, 8033, 547, 10, 43, "Text",ExpressionUUID->"a4d3e6be-7f17-4eb6-abc7-c9a199713c0c"], +Cell[CellGroupData[{ +Cell[301726, 8047, 1542, 37, 90, "Input",ExpressionUUID->"f478a417-bc6f-4923-951f-887da363b68e"], +Cell[303271, 8086, 3785, 69, 375, "Output",ExpressionUUID->"f4e55749-f176-46c3-a1d5-7ea519728010"] +}, Open ]], +Cell[307071, 8158, 767, 13, 98, "Text",ExpressionUUID->"b0ef7e07-d8af-4b9e-a0b1-6b04f5ec6187"], +Cell[CellGroupData[{ +Cell[307863, 8175, 1648, 39, 90, "Input",ExpressionUUID->"b2475597-da31-46ea-9461-541534144837"], +Cell[309514, 8216, 2478, 46, 375, "Output",ExpressionUUID->"469ee891-e1ab-4e63-bc89-55eb0b4660f2"] +}, Open ]], +Cell[312007, 8265, 548, 10, 43, "Text",ExpressionUUID->"9c37b07f-3093-424b-bb94-3b4bbfebf5fa"], +Cell[CellGroupData[{ +Cell[312580, 8279, 1547, 37, 66, "Input",ExpressionUUID->"80b44baa-03c8-485b-b350-8993b88d764c"], +Cell[314130, 8318, 1527, 31, 343, "Output",ExpressionUUID->"b02a563d-25ca-429f-961d-a237e7029e6d"] +}, Open ]], +Cell[315672, 8352, 402, 8, 71, "Text",ExpressionUUID->"52d499a3-b1bf-4c58-95d8-8596556acd19"], +Cell[316077, 8362, 333, 9, 98, "Text",ExpressionUUID->"a05fce4c-d804-4196-b5f3-9f7877e5ef08"], +Cell[CellGroupData[{ +Cell[316435, 8375, 181, 4, 41, "Input",ExpressionUUID->"48d98892-a54a-4f26-b5e3-aac946bb3de1"], +Cell[316619, 8381, 2837, 46, 96, "Print",ExpressionUUID->"cf242f76-0f13-470e-8415-d864fa3ca790", + CellTags->"Info3514665203-3164126"] +}, Open ]], +Cell[CellGroupData[{ +Cell[319493, 8432, 1689, 44, 90, "Input",ExpressionUUID->"8f7d9e28-4f5b-44d3-ace9-b4e9dddbc194"], +Cell[321185, 8478, 35202, 663, 583, "Output",ExpressionUUID->"939ba5b0-2eaa-4107-8b40-5a23f632e8ab"] +}, Open ]], +Cell[CellGroupData[{ +Cell[356424, 9146, 181, 4, 41, "Input",ExpressionUUID->"d4a15bb4-aa7a-4d78-bbb4-a5de2425508f"], +Cell[356608, 9152, 2826, 45, 96, "Print",ExpressionUUID->"b34c0a8d-db2f-40c0-b644-c27d30afdb23", + CellTags->"Info3514667375-7328529"] +}, Open ]], +Cell[CellGroupData[{ +Cell[359471, 9202, 1681, 43, 66, "Input",ExpressionUUID->"5db764b6-b0ba-401a-a5b9-626464d50d35"], +Cell[361155, 9247, 127576, 2018, 583, "Output",ExpressionUUID->"fbbe5a33-6a67-4d3a-b953-c482a45846e5"] +}, Open ]], +Cell[488746, 11268, 204, 3, 43, "Text",ExpressionUUID->"2ab298f9-b4b2-4ee9-8dc7-adc4cf6fa455"], +Cell[488953, 11273, 358, 6, 41, "Input",ExpressionUUID->"0e1e16b7-3f89-4782-abbb-905a073ff66c"], +Cell[CellGroupData[{ +Cell[489336, 11283, 113, 1, 41, "Input",ExpressionUUID->"22a073d9-aeff-41f3-94fa-5757aea7c239"], +Cell[489452, 11286, 350, 7, 61, "Print",ExpressionUUID->"818115c5-a869-4c3c-82fb-74819af00235", + CellTags->"Info3514664747-5819389"] +}, Open ]], +Cell[489817, 11296, 2306, 57, 90, "Input",ExpressionUUID->"512d3847-ba75-4547-b516-141563d99487"], +Cell[492126, 11355, 188, 3, 43, "Text",ExpressionUUID->"3e484052-b27f-4ca2-831c-d6f6e7417e01"], +Cell[CellGroupData[{ +Cell[492339, 11362, 1231, 31, 155, "Input",ExpressionUUID->"349b7749-c444-475c-84c9-b83e0eecc762"], +Cell[493573, 11395, 129427, 2021, 583, "Output",ExpressionUUID->"2dcc3d79-78d7-42f0-8ad8-44b4f87e4e24"] +}, Open ]], +Cell[623015, 13419, 616, 13, 126, "Text",ExpressionUUID->"ff08303c-386d-42c0-968b-ff661c35b535"], +Cell[623634, 13434, 388, 7, 43, "Text",ExpressionUUID->"2d9e6217-f6a7-4e5b-b1b0-330fdff23667"], +Cell[CellGroupData[{ +Cell[624047, 13445, 493, 13, 41, "Input",ExpressionUUID->"866342d9-d350-46be-836a-7a2b903f2278"], +Cell[624543, 13460, 284, 7, 66, "Output",ExpressionUUID->"8eeed916-b849-4714-a6d5-ff0f45749ca9"] +}, Open ]], +Cell[624842, 13470, 387, 7, 43, "Text",ExpressionUUID->"5cf1d732-dc01-4e0f-a3c2-b9b741a76852"], +Cell[CellGroupData[{ +Cell[625254, 13481, 439, 12, 41, "Input",ExpressionUUID->"79511892-01b5-42a5-8787-e47f4d4b73b0"], +Cell[625696, 13495, 258, 7, 70, "Output",ExpressionUUID->"22d9c645-06c1-4ab5-9aee-60e2558426f9"] +}, Open ]], +Cell[CellGroupData[{ +Cell[625991, 13507, 2116, 51, 248, "Input",ExpressionUUID->"435973e6-70b8-49d5-9cdc-2b803506381f"], +Cell[628110, 13560, 133096, 2086, 583, "Output",ExpressionUUID->"e3f30246-b442-4a43-a6ca-749e247ab6ff"] +}, Open ]], +Cell[761221, 15649, 1128, 21, 288, "Text",ExpressionUUID->"1092780b-2bde-4e19-82ee-b6856863f111"], +Cell[CellGroupData[{ +Cell[762374, 15674, 253, 5, 41, "Input",ExpressionUUID->"06ecc798-3bbf-49d7-91a3-730569eaa574"], +Cell[762630, 15681, 575, 21, 97, "Output",ExpressionUUID->"4840a3dc-397f-4ecc-939b-d9780f67caa7"] +}, Open ]], +Cell[763220, 15705, 314, 7, 53, "Text",ExpressionUUID->"80e7b0f8-ccb1-4f7a-95d1-456522f7a303"], +Cell[CellGroupData[{ +Cell[763559, 15716, 3823, 103, 408, "Input",ExpressionUUID->"c4b73d2b-2352-4706-b985-b1f0135ce97e"], +Cell[767385, 15821, 135379, 2087, 728, "Output",ExpressionUUID->"01cbeb0d-e5f8-41ac-b2aa-d9bf695e8c57"] +}, Open ]], +Cell[902779, 17911, 1913, 42, 277, "Text",ExpressionUUID->"349c6c71-36ea-41ce-ab28-97d162a0a359"], +Cell[904695, 17955, 480, 9, 122, "Text",ExpressionUUID->"ae62c8d6-928b-4b30-a031-dc1a7ca34e6f"] +}, Closed]], +Cell[CellGroupData[{ +Cell[905212, 17969, 282, 8, 65, "Section",ExpressionUUID->"5fd34efa-326c-4863-8ddf-adfe8c8ed51d", + Evaluatable->False], +Cell[CellGroupData[{ +Cell[905519, 17981, 141, 3, 265, "Subsection",ExpressionUUID->"15c6e2b9-8932-4d44-b865-b09662f8305c", + Evaluatable->False], +Cell[905663, 17986, 2928, 87, 3053, "Input",ExpressionUUID->"407f3365-c0ab-485c-83aa-2dfa2e0cb43f"] +}, Closed]], +Cell[CellGroupData[{ +Cell[908628, 18078, 258, 7, 187, "Subsection",ExpressionUUID->"a01fa7c4-eef1-4966-a9b6-1a85c61bcf9c"], +Cell[908889, 18087, 604, 12, 906, "Text",ExpressionUUID->"ed6897e0-eb4f-4a84-80ef-26277213ad33"], +Cell[909496, 18101, 342, 9, 210, "Input",ExpressionUUID->"168487e7-aebb-4ba1-ad4e-987bbefe0ad8"], +Cell[909841, 18112, 560, 15, 331, "Input",ExpressionUUID->"3f4dd988-8c28-40a2-bed7-b1971dfdab81"] +}, Closed]], +Cell[CellGroupData[{ +Cell[910438, 18132, 243, 8, 303, "Subsection",ExpressionUUID->"e79b889b-0e02-4a7e-91f7-b4d817901a28", + Evaluatable->False], +Cell[910684, 18142, 1749, 60, 2195, "Text",ExpressionUUID->"056622c9-2b57-4e8a-a5af-0c906eb66688", + Evaluatable->False] +}, Closed]], +Cell[CellGroupData[{ +Cell[912470, 18207, 211, 7, 187, "Subsection",ExpressionUUID->"a652d8ab-b08b-4312-9fd2-10b613a341dc", + Evaluatable->False], +Cell[912684, 18216, 1993, 66, 1226, "Input",ExpressionUUID->"0a60f49a-ea6d-4902-bb95-9adaf42301f4"] +}, Closed]], +Cell[CellGroupData[{ +Cell[914714, 18287, 152, 3, 187, "Subsection",ExpressionUUID->"a224c7ec-60c0-4910-98d7-3fd99236f8bb", + Evaluatable->False], +Cell[914869, 18292, 8386, 194, 9827, "Text",ExpressionUUID->"b19aa47d-3c71-402c-b720-da43ff8233ff", + Evaluatable->False] +}, Closed]], +Cell[CellGroupData[{ +Cell[923292, 18491, 135, 3, 187, "Subsection",ExpressionUUID->"33a7dbbb-a5e3-4827-92ec-6dc7fd7393cc", + Evaluatable->False], +Cell[923430, 18496, 511, 12, 437, "Text",ExpressionUUID->"b5072fa0-642d-496f-99b2-c4dade28aec5"], +Cell[923944, 18510, 181, 4, 210, "Input",ExpressionUUID->"86fc153c-ff24-47f9-babf-da8878c78712"], +Cell[CellGroupData[{ +Cell[924150, 18518, 1383, 41, 447, "Input",ExpressionUUID->"1646f9c1-3057-470c-8965-fee79a25fe5b"], +Cell[925536, 18561, 1447, 27, 1945, "Output",ExpressionUUID->"7f10c13f-6df7-4857-a107-0cbd910efa4c"] +}, Open ]] +}, Closed]] +}, Closed]] +}, Open ]] +} +] +*) + diff --git a/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/Bios2_WorkshopMaxima.wxmx b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/Bios2_WorkshopMaxima.wxmx new file mode 100644 index 0000000..9dac474 Binary files /dev/null and b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/Bios2_WorkshopMaxima.wxmx differ diff --git a/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/Bios2_WorkshopMaximaSOLUTIONS.wxmx b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/Bios2_WorkshopMaximaSOLUTIONS.wxmx new file mode 100644 index 0000000..5744051 Binary files /dev/null and b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/Bios2_WorkshopMaximaSOLUTIONS.wxmx differ diff --git a/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/Homework1.pdf b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/Homework1.pdf new file mode 100644 index 0000000..a34e180 Binary files /dev/null and b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/Homework1.pdf differ diff --git a/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/HomeworkAnswers.nb b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/HomeworkAnswers.nb new file mode 100644 index 0000000..be295ed --- /dev/null +++ b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/HomeworkAnswers.nb @@ -0,0 +1,811 @@ +(* Content-type: application/vnd.wolfram.mathematica *) + +(*** Wolfram Notebook File ***) +(* http://www.wolfram.com/nb *) + +(* CreatedBy='Mathematica 8.0' *) + +(*CacheID: 234*) +(* Internal cache information: +NotebookFileLineBreakTest +NotebookFileLineBreakTest +NotebookDataPosition[ 157, 7] +NotebookDataLength[ 24312, 802] +NotebookOptionsPosition[ 21818, 714] +NotebookOutlinePosition[ 22271, 732] +CellTagsIndexPosition[ 22228, 729] +WindowFrame->Normal*) + +(* Beginning of Notebook Content *) +Notebook[{ + +Cell[CellGroupData[{ +Cell["Problem 5.10", "Subsection", + CellChangeTimes->{{3.6200546324853783`*^9, 3.620054634692411*^9}}], + +Cell[TextData[{ + "If p[t+1] = (1-m) p\[CloseCurlyQuote] + m and p\[CloseCurlyQuote] = ", + Cell[BoxData[ + FormBox[ + FractionBox[ + RowBox[{ + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], + RowBox[{ + RowBox[{ + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], " ", "+", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]], TraditionalForm]], + FormatType->"TraditionalForm"], + ", then the full recursion equation will equal p[t+1] = (1-m) ", + Cell[BoxData[ + FormBox[ + FractionBox[ + RowBox[{ + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], + RowBox[{ + RowBox[{ + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], " ", "+", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]], TraditionalForm]]], + " + m, let\[CloseCurlyQuote]s call this \[OpenCurlyDoubleQuote]recursion\ +\[CloseCurlyDoubleQuote]:" +}], "Text", + CellChangeTimes->{{3.619900583045334*^9, 3.619900689622931*^9}}], + +Cell[BoxData[ + RowBox[{ + RowBox[{"recursion", "=", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "m"}], ")"}], + FormBox[ + FractionBox[ + RowBox[{ + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], + RowBox[{ + RowBox[{ + RowBox[{"p", "[", "t", "]"}], " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], " ", "+", + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}]}], ")"}]}]], + TraditionalForm]}], "+", "m"}]}], ";"}]], "Input", + CellChangeTimes->{{3.6199006676784983`*^9, 3.619900698150819*^9}, + 3.6200546797086687`*^9}], + +Cell[CellGroupData[{ + +Cell["Part a", "Subsubsection", + CellChangeTimes->{{3.6200546389323883`*^9, 3.620054640355875*^9}, { + 3.620054695498062*^9, 3.620054702162211*^9}}], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"recursion", "\[Equal]", + RowBox[{"p", "[", "t", "]"}]}], ",", + RowBox[{"p", "[", "t", "]"}]}], "]"}]], "Input", + CellChangeTimes->{{3.620054647374654*^9, 3.620054674531081*^9}}], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"p", "[", "t", "]"}], "\[Rule]", "1"}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"p", "[", "t", "]"}], "\[Rule]", + FractionBox["m", "s"]}], "}"}]}], "}"}]], "Output", + CellChangeTimes->{3.620054674975196*^9}] +}, Open ]], + +Cell[TextData[{ + "By hand:\n\n", + Cell[BoxData[ + RowBox[{"p", " ", "=", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "m"}], ")"}], + FormBox[ + FractionBox[ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], + RowBox[{ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], " ", "+", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}]], + TraditionalForm]}], "+", "m"}]}]], + CellChangeTimes->{{3.6199006676784983`*^9, 3.619900698150819*^9}, + 3.6200546797086687`*^9}], + "\n\nmove everything to the right hand side:\n\n", + Cell[BoxData[ + RowBox[{"0", "=", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "m"}], ")"}], + FormBox[ + FractionBox[ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], + RowBox[{ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], " ", "+", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}]], + TraditionalForm]}], "+", "m", " ", "-", " ", "p"}]}]], + CellChangeTimes->{{3.6199006676784983`*^9, 3.619900698150819*^9}, + 3.6200546797086687`*^9}], + "\n\nput everything over a common denominator:\n\n", + Cell[BoxData[ + RowBox[{"0", "=", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "m"}], ")"}], + FormBox[ + FractionBox[ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], + RowBox[{ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], " ", "+", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}]], + TraditionalForm]}], "+", + FormBox[ + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"m", " ", "-", " ", "p"}], ")"}], + RowBox[{"(", + RowBox[{ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], " ", "+", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}], ")"}]}], + RowBox[{ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], " ", "+", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}]], + TraditionalForm]}]}]], + CellChangeTimes->{{3.6199006676784983`*^9, 3.619900698150819*^9}, + 3.6200546797086687`*^9}], + "\n\nbring all the factors in the numerator together:\n\n", + Cell[BoxData[ + RowBox[{"0", "=", + FormBox[ + FractionBox[ + RowBox[{ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}], + RowBox[{"(", + RowBox[{"1", "-", "m"}], ")"}]}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{"m", " ", "-", " ", "p"}], ")"}], + RowBox[{"(", + RowBox[{ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], " ", "+", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}], ")"}]}]}], + RowBox[{ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], " ", "+", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}]], + TraditionalForm]}]], + CellChangeTimes->{{3.6199006676784983`*^9, 3.619900698150819*^9}, + 3.6200546797086687`*^9}], + "\n\n\t", + Cell[BoxData[ + RowBox[{"=", + FormBox[ + FractionBox[ + RowBox[{"p", " ", "-", + RowBox[{"s", " ", "p"}], " ", "-", " ", + RowBox[{"m", " ", "p"}], " ", "+", " ", + RowBox[{"s", " ", "m", " ", "p"}], " ", "-", + RowBox[{"m", " ", "p", " ", "s"}], " ", "+", " ", "m", " ", "+", + RowBox[{ + RowBox[{"p", "^", "2"}], " ", "s"}], " ", "-", "p", " "}], + RowBox[{ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], " ", "+", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}]], + TraditionalForm]}]], + CellChangeTimes->{{3.6199006676784983`*^9, 3.619900698150819*^9}, + 3.6200546797086687`*^9}], + "\n\n\t", + Cell[BoxData[ + RowBox[{"=", + FormBox[ + FractionBox[ + RowBox[{ + RowBox[{ + RowBox[{"-", "s"}], " ", "p"}], " ", "-", " ", + RowBox[{"m", " ", "p"}], " ", "+", " ", "m", " ", "+", + RowBox[{ + RowBox[{"p", "^", "2"}], " ", "s", " "}]}], + RowBox[{ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], " ", "+", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}]], + TraditionalForm]}]], + CellChangeTimes->{{3.6199006676784983`*^9, 3.619900698150819*^9}, + 3.6200546797086687`*^9}], + "\n\nFactor the top (or use the quadratic formula to solve):\n\n\t", + Cell[BoxData[ + RowBox[{"=", + FormBox[ + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"m", " ", "-", " ", + RowBox[{"p", " ", "s"}]}], ")"}], + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}], " "}], + RowBox[{ + RowBox[{"p", " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], " ", "+", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}]], + TraditionalForm]}]], + CellChangeTimes->{{3.6199006676784983`*^9, 3.619900698150819*^9}, + 3.6200546797086687`*^9}], + "\n\nwhich equals zero if p = m/s or p = 1, the two equilibria of the system." +}], "Text", + CellChangeTimes->{{3.620054708722431*^9, 3.620054997074006*^9}}] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Part b", "Subsubsection", + CellChangeTimes->{{3.6200546389323883`*^9, 3.620054640355875*^9}, { + 3.62005468922782*^9, 3.620054689442329*^9}}], + +Cell["\<\ +The polymorphic equibrium is p = m/s, which is a valid allele frequency only \ +if it lies between 0 and 1. Given that m (migration) and s (selection \ +against the allele \[OpenCurlyDoubleQuote]A\[CloseCurlyDoubleQuote] in the \ +marginal population) are positive by the description of the model, p = m/s \ +must be positive. But if will only be less than one if m/s < 1, that is, \ +migration must be weaker than selection.\ +\>", "Text", + CellChangeTimes->{{3.620054690818493*^9, 3.6200547049945908`*^9}, { + 3.620054999715878*^9, 3.620055128183167*^9}}] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Part c", "Subsubsection", + CellChangeTimes->{{3.620055134599427*^9, 3.620055135447016*^9}}], + +Cell["\<\ +Here we need to figure out if p = 1 is a stable equilibrium. This is the \ +code we used for the logistic:\ +\>", "Text", + CellChangeTimes->{{3.620055164623334*^9, 3.620055180134006*^9}}], + +Cell[BoxData[ + RowBox[{"derivative", "=", + RowBox[{"D", "[", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "+", + RowBox[{"r", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{"n", "[", "t", "]"}], "K"]}], ")"}]}]}], ")"}], + RowBox[{"n", "[", "t", "]"}]}], ",", + RowBox[{"n", "[", "t", "]"}]}], "]"}]}]], "Input", + CellChangeTimes->{{3.514118347956435*^9, 3.5141183994468813`*^9}, { + 3.514118454362989*^9, 3.514118457111812*^9}, 3.5145541519167633`*^9}], + +Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{"derivative", "/.", + RowBox[{ + RowBox[{"n", "[", "t", "]"}], "\[Rule]", "0"}]}]}]], "Input", + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9}], + +Cell["and here it is for this model:", "Text", + CellChangeTimes->{{3.620055185095087*^9, 3.620055188893589*^9}}], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"derivative", "=", + RowBox[{"D", "[", + RowBox[{"recursion", ",", + RowBox[{"p", "[", "t", "]"}]}], "]"}]}]], "Input", + CellChangeTimes->{{3.514118347956435*^9, 3.5141183994468813`*^9}, { + 3.514118454362989*^9, 3.514118457111812*^9}, 3.5145541519167633`*^9, { + 3.620055194586741*^9, 3.620055197086155*^9}}], + +Cell[BoxData[ + RowBox[{ + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "m"}], ")"}], " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}], " ", "s", " ", + RowBox[{"p", "[", "t", "]"}]}], + SuperscriptBox[ + RowBox[{"(", + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}], " ", + RowBox[{"p", "[", "t", "]"}]}]}], ")"}], "2"]], "+", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "m"}], ")"}], " ", + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}]}], + RowBox[{"1", "-", + RowBox[{"p", "[", "t", "]"}], "+", + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "s"}], ")"}], " ", + RowBox[{"p", "[", "t", "]"}]}]}]]}]], "Output", + CellChangeTimes->{3.620055197570943*^9}] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"\[Lambda]", "=", + RowBox[{"derivative", "/.", + RowBox[{ + RowBox[{"p", "[", "t", "]"}], "\[Rule]", "1"}]}]}]], "Input", + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9, {3.6200552006470137`*^9, 3.620055202334488*^9}}], + +Cell[BoxData[ + RowBox[{"1", "-", "m", "+", + FractionBox[ + RowBox[{ + RowBox[{"(", + RowBox[{"1", "-", "m"}], ")"}], " ", "s"}], + RowBox[{"1", "-", "s"}]]}]], "Output", + CellChangeTimes->{3.6200552026220818`*^9}] +}, Open ]], + +Cell["\<\ +This can be simplified by factoring:\ +\>", "Text", + CellChangeTimes->{{3.6200552102936296`*^9, 3.620055214621313*^9}}], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Factor", "[", "\[Lambda]", "]"}]], "Input", + CellChangeTimes->{{3.620055215438511*^9, 3.620055218277481*^9}}], + +Cell[BoxData[ + FractionBox[ + RowBox[{ + RowBox[{"-", "1"}], "+", "m"}], + RowBox[{ + RowBox[{"-", "1"}], "+", "s"}]]], "Output", + CellChangeTimes->{3.620055218707775*^9}] +}, Open ]], + +Cell[TextData[{ + "Comparing to the stability conditions, the equilibrium at p = 1 (allele \ +\[OpenCurlyDoubleQuote]a\[CloseCurlyDoubleQuote] absent despite being favored \ +in the marginal patch) will be stable if -1 < \[Lambda] < +1.\n\nIn this \ +case, ", + Cell[BoxData[ + FractionBox[ + RowBox[{"1", "-", "m"}], + RowBox[{"1", "-", "s"}]]], + CellChangeTimes->{3.620055218707775*^9}], + " will be positive because m is the fraction of migrants (can\ +\[CloseCurlyQuote]t be greater than one) and 1-s is the fitness of the \ +\[OpenCurlyDoubleQuote]a\[CloseCurlyDoubleQuote] allele \ +(can\[CloseCurlyQuote]t be negative). So we can focus on \[Lambda] < 1 \ +(stable) or \[Lambda] > 1 (unstable):\n\nChecking when \[Lambda] < 1: ", + Cell[BoxData[ + RowBox[{ + FractionBox[ + RowBox[{"1", "-", "m"}], + RowBox[{"1", "-", "s"}]], "<", "1"}]], + CellChangeTimes->{3.620055218707775*^9}], + " if ", + Cell[BoxData[ + RowBox[{ + RowBox[{"1", "-", "m"}], "<", + RowBox[{"1", "-", "s"}]}]], + CellChangeTimes->{3.620055218707775*^9}], + " if ", + Cell[BoxData[ + RowBox[{"s", "<", "m"}]], + CellChangeTimes->{3.620055218707775*^9}], + " [migration \[OpenCurlyDoubleQuote]swamps\[CloseCurlyDoubleQuote] \ +selection]\n\nThus, if ", + Cell[BoxData[ + RowBox[{"s", "<", "m"}]], + CellChangeTimes->{3.620055218707775*^9}], + " then p = 1 will be a stable equilibrium, and allele \ +\[OpenCurlyDoubleQuote]a\[CloseCurlyDoubleQuote] will fail to spread, even \ +though it is favored in the marginal habitat.\n\nConversely, if ", + Cell[BoxData[ + RowBox[{"s", ">", "m"}]], + CellChangeTimes->{3.620055218707775*^9}], + " then p = 1 will be an unstable equilibrium and allele \ +\[OpenCurlyDoubleQuote]a\[CloseCurlyDoubleQuote] can spread when rare. \ +[migration \[OpenCurlyDoubleQuote]swamps\[CloseCurlyDoubleQuote] selection]" +}], "Text", + CellChangeTimes->{{3.6200552222608128`*^9, 3.620055490527672*^9}}] +}, Open ]] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Problem 5.13", "Subsection", + CellChangeTimes->{{3.6200546324853783`*^9, 3.620054634692411*^9}, { + 3.620055515495582*^9, 3.620055515582779*^9}}], + +Cell["\<\ +If unoccupied sites (fraction 1-p) are recolonized at rate m p, which rises \ +with the fraction of occupied patches, and if occupied sites go extinct at \ +rate e, the following differential equation in continuous time might describe \ +the fraction of occupied sites over time, p:\ +\>", "Text", + CellChangeTimes->{{3.619900583045334*^9, 3.619900689622931*^9}, { + 3.787965773297121*^9, 3.787965857355789*^9}}], + +Cell[BoxData[ + RowBox[{ + RowBox[{"differential", "=", + RowBox[{ + RowBox[{"m", " ", "p", " ", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}], " ", "-", " ", + RowBox[{"e", " ", "p"}]}]}], ";"}]], "Input", + CellChangeTimes->{{3.6199006676784983`*^9, 3.619900698150819*^9}, + 3.6200546797086687`*^9, {3.620055521113267*^9, 3.6200555331839037`*^9}}], + +Cell[CellGroupData[{ + +Cell["Part a", "Subsubsection", + CellChangeTimes->{{3.6200546389323883`*^9, 3.620054640355875*^9}, { + 3.620054695498062*^9, 3.620054702162211*^9}}], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Solve", "[", + RowBox[{ + RowBox[{"differential", "\[Equal]", "0"}], ",", "p"}], "]"}]], "Input", + CellChangeTimes->{{3.620054647374654*^9, 3.620054674531081*^9}, { + 3.62005553933041*^9, 3.620055543815529*^9}}], + +Cell[BoxData[ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"p", "\[Rule]", "0"}], "}"}], ",", + RowBox[{"{", + RowBox[{"p", "\[Rule]", + FractionBox[ + RowBox[{ + RowBox[{"-", "e"}], "+", "m"}], "m"]}], "}"}]}], "}"}]], "Output", + CellChangeTimes->{ + 3.620054674975196*^9, {3.620055541492549*^9, 3.6200555443254633`*^9}}] +}, Open ]], + +Cell[TextData[{ + "By hand:\n\n", + Cell[BoxData[ + RowBox[{"0", "=", + RowBox[{ + RowBox[{"m", " ", "p", " ", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}], " ", "-", " ", + RowBox[{"e", " ", "p"}]}]}]], + CellChangeTimes->{{3.6199006676784983`*^9, 3.619900698150819*^9}, + 3.6200546797086687`*^9}], + "\n\nfactor:\n\n", + Cell[BoxData[ + RowBox[{"0", "=", + RowBox[{"p", + RowBox[{"(", + RowBox[{ + RowBox[{"m", " ", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}], " ", "-", " ", "e"}], ")"}]}]}]], + CellChangeTimes->{{3.6199006676784983`*^9, 3.619900698150819*^9}, + 3.6200546797086687`*^9}], + "\n\nwhich equals zero if p = 0 or p = ", + Cell[BoxData[ + FormBox[ + FractionBox[ + RowBox[{"m", "-", "e"}], "m"], TraditionalForm]], + FormatType->"TraditionalForm"], + ", the two equilibria of the system." +}], "Text", + CellChangeTimes->{{3.620054708722431*^9, 3.620054997074006*^9}, { + 3.620055550687992*^9, 3.6200556046260443`*^9}}] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Part b", "Subsubsection", + CellChangeTimes->{{3.6200546389323883`*^9, 3.620054640355875*^9}, { + 3.62005468922782*^9, 3.620054689442329*^9}}], + +Cell[TextData[{ + "The equibrium with species present is p = ", + Cell[BoxData[ + FormBox[ + FractionBox[ + RowBox[{"m", "-", "e"}], "m"], TraditionalForm]]], + ", which gives a valid frequency of occupied sites only if p lies between 0 \ +and 1. Given that m (migration) is positive, p will be positive if m > e. \ +To ensure that p is less than one requires: ", + Cell[BoxData[ + FormBox[ + RowBox[{ + FractionBox[ + RowBox[{"m", "-", "e"}], "m"], "<", "1"}], TraditionalForm]]], + ", that is ", + Cell[BoxData[ + FormBox[ + RowBox[{ + RowBox[{"m", "-", "e"}], "<", "m"}], TraditionalForm]]], + ", that is ", + Cell[BoxData[ + FormBox[ + RowBox[{"0", "<", "e"}], TraditionalForm]]], + ", which is always true given extinction in the system." +}], "Text", + CellChangeTimes->{{3.620054690818493*^9, 3.6200547049945908`*^9}, { + 3.620054999715878*^9, 3.620055128183167*^9}, {3.6200556226108923`*^9, + 3.620055762104545*^9}}] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Part c", "Subsubsection", + CellChangeTimes->{{3.620055134599427*^9, 3.620055135447016*^9}}], + +Cell[TextData[{ + "Here we need to figure out if p = ", + Cell[BoxData[ + FormBox[ + FractionBox[ + RowBox[{"m", "-", "e"}], "m"], TraditionalForm]]], + " is a stable equilibrium. We use the same procedure as above (we just have \ +different rules for interpreting the derivative):" +}], "Text", + CellChangeTimes->{{3.620055164623334*^9, 3.620055180134006*^9}, { + 3.620055780311201*^9, 3.620055805304062*^9}}], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"derivative", "=", + RowBox[{"D", "[", + RowBox[{"differential", ",", "p"}], "]"}]}]], "Input", + CellChangeTimes->{{3.514118347956435*^9, 3.5141183994468813`*^9}, { + 3.514118454362989*^9, 3.514118457111812*^9}, 3.5145541519167633`*^9, { + 3.620055194586741*^9, 3.620055197086155*^9}, {3.620055811043214*^9, + 3.620055813992404*^9}}], + +Cell[BoxData[ + RowBox[{ + RowBox[{"-", "e"}], "+", + RowBox[{"m", " ", + RowBox[{"(", + RowBox[{"1", "-", "p"}], ")"}]}], "-", + RowBox[{"m", " ", "p"}]}]], "Output", + CellChangeTimes->{3.620055197570943*^9, 3.620055814439342*^9}] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"r", "=", + RowBox[{"derivative", "/.", + RowBox[{"p", "\[Rule]", + FractionBox[ + RowBox[{"m", "-", "e"}], "m"]}]}]}]], "Input", + CellChangeTimes->{{3.5141184032286873`*^9, 3.514118417932392*^9}, + 3.514118463298354*^9, {3.6200552006470137`*^9, 3.620055202334488*^9}, { + 3.620055824021678*^9, 3.620055844233514*^9}}], + +Cell[BoxData[ + RowBox[{ + RowBox[{"-", "m"}], "+", + RowBox[{"m", " ", + RowBox[{"(", + RowBox[{"1", "-", + FractionBox[ + RowBox[{ + RowBox[{"-", "e"}], "+", "m"}], "m"]}], ")"}]}]}]], "Output", + CellChangeTimes->{ + 3.6200552026220818`*^9, {3.6200558263912363`*^9, 3.6200558446781893`*^9}}] +}, Open ]], + +Cell["\<\ +This can be simplified by factoring:\ +\>", "Text", + CellChangeTimes->{{3.6200552102936296`*^9, 3.620055214621313*^9}}], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{"Factor", "[", "r", "]"}]], "Input", + CellChangeTimes->{{3.620055215438511*^9, 3.620055218277481*^9}, + 3.620055846330488*^9}], + +Cell[BoxData[ + RowBox[{"e", "-", "m"}]], "Output", + CellChangeTimes->{ + 3.620055218707775*^9, {3.6200558287591763`*^9, 3.620055846744746*^9}}] +}, Open ]], + +Cell[TextData[{ + "Comparing to the stability conditions for a continuous time model, the \ +equilibrium at p = ", + Cell[BoxData[ + FormBox[ + FractionBox[ + RowBox[{"m", "-", "e"}], "m"], TraditionalForm]]], + " (species present) will be stable if r < 0, which requires that m > e. \n\n\ +Thus, as long as recolonization occurs at a higher rate than extinction, the \ +species can persist and reach this dynamic equilibrium at p = ", + Cell[BoxData[ + FormBox[ + FractionBox[ + RowBox[{"m", "-", "e"}], "m"], TraditionalForm]]], + "." +}], "Text", + CellChangeTimes->{{3.6200552222608128`*^9, 3.620055490527672*^9}, { + 3.6200558355033216`*^9, 3.620055925758931*^9}}] +}, Open ]] +}, Open ]] +}, +WindowSize->{1280, 672}, +WindowMargins->{{0, Automatic}, {Automatic, 0}}, +Magnification:>FEPrivate`If[ + FEPrivate`Equal[FEPrivate`$VersionNumber, 6.], 1.5, 1.5 Inherited], +FrontEndVersion->"8.0 for Mac OS X x86 (32-bit, 64-bit Kernel) (October 5, \ +2011)", +StyleDefinitions->"Default.nb" +] +(* End of Notebook Content *) + +(* Internal cache information *) +(*CellTagsOutline +CellTagsIndex->{} +*) +(*CellTagsIndex +CellTagsIndex->{} +*) +(*NotebookFileOutline +Notebook[{ +Cell[CellGroupData[{ +Cell[579, 22, 102, 1, 51, "Subsection"], +Cell[684, 25, 1187, 37, 84, "Text"], +Cell[1874, 64, 705, 23, 71, "Input"], +Cell[CellGroupData[{ +Cell[2604, 91, 148, 2, 39, "Subsubsection"], +Cell[CellGroupData[{ +Cell[2777, 97, 245, 6, 40, "Input"], +Cell[3025, 105, 311, 10, 61, "Output"] +}, Open ]], +Cell[3351, 118, 5374, 176, 720, "Text"] +}, Open ]], +Cell[CellGroupData[{ +Cell[8762, 299, 147, 2, 39, "Subsubsection"], +Cell[8912, 303, 563, 9, 93, "Text"] +}, Open ]], +Cell[CellGroupData[{ +Cell[9512, 317, 97, 1, 39, "Subsubsection"], +Cell[9612, 320, 196, 4, 42, "Text"], +Cell[9811, 326, 539, 15, 66, "Input"], +Cell[10353, 343, 244, 6, 40, "Input"], +Cell[10600, 351, 112, 1, 42, "Text"], +Cell[CellGroupData[{ +Cell[10737, 356, 340, 7, 40, "Input"], +Cell[11080, 365, 844, 29, 69, "Output"] +}, Open ]], +Cell[CellGroupData[{ +Cell[11961, 399, 292, 6, 40, "Input"], +Cell[12256, 407, 224, 7, 64, "Output"] +}, Open ]], +Cell[12495, 417, 128, 3, 42, "Text"], +Cell[CellGroupData[{ +Cell[12648, 424, 133, 2, 40, "Input"], +Cell[12784, 428, 174, 6, 64, "Output"] +}, Open ]], +Cell[12973, 437, 1894, 46, 364, "Text"] +}, Open ]] +}, Open ]], +Cell[CellGroupData[{ +Cell[14916, 489, 151, 2, 51, "Subsection"], +Cell[15070, 493, 418, 7, 93, "Text"], +Cell[15491, 502, 369, 9, 40, "Input"], +Cell[CellGroupData[{ +Cell[15885, 515, 148, 2, 39, "Subsubsection"], +Cell[CellGroupData[{ +Cell[16058, 521, 237, 5, 40, "Input"], +Cell[16298, 528, 350, 11, 60, "Output"] +}, Open ]], +Cell[16663, 542, 988, 31, 240, "Text"] +}, Open ]], +Cell[CellGroupData[{ +Cell[17688, 578, 147, 2, 39, "Subsubsection"], +Cell[17838, 582, 928, 27, 111, "Text"] +}, Open ]], +Cell[CellGroupData[{ +Cell[18803, 614, 97, 1, 39, "Subsubsection"], +Cell[18903, 617, 409, 10, 77, "Text"], +Cell[CellGroupData[{ +Cell[19337, 631, 363, 7, 40, "Input"], +Cell[19703, 640, 237, 7, 40, "Output"] +}, Open ]], +Cell[CellGroupData[{ +Cell[19977, 652, 353, 8, 64, "Input"], +Cell[20333, 662, 311, 10, 60, "Output"] +}, Open ]], +Cell[20659, 675, 128, 3, 42, "Text"], +Cell[CellGroupData[{ +Cell[20812, 682, 151, 3, 40, "Input"], +Cell[20966, 687, 143, 3, 40, "Output"] +}, Open ]], +Cell[21124, 693, 666, 17, 162, "Text"] +}, Open ]] +}, Open ]] +} +] +*) + +(* End of internal cache information *) diff --git a/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/HomeworkAnswers.pdf b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/HomeworkAnswers.pdf new file mode 100644 index 0000000..588297d Binary files /dev/null and b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/HomeworkAnswers.pdf differ diff --git a/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/MathematicaGuide.nb b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/MathematicaGuide.nb new file mode 100644 index 0000000..f5ae960 --- /dev/null +++ b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/MathematicaGuide.nb @@ -0,0 +1,705 @@ +(* Content-type: application/mathematica *) + +(*** Wolfram Notebook File ***) +(* http://www.wolfram.com/nb *) + +(* CreatedBy='Mathematica 6.0' *) + +(*CacheID: 234*) +(* Internal cache information: +NotebookFileLineBreakTest +NotebookFileLineBreakTest +NotebookDataPosition[ 145, 7] +NotebookDataLength[ 23215, 696] +NotebookOptionsPosition[ 21263, 624] +NotebookOutlinePosition[ 22179, 657] +CellTagsIndexPosition[ 22136, 654] +WindowFrame->Normal*) + +(* Beginning of Notebook Content *) +Notebook[{ + +Cell[CellGroupData[{ +Cell[TextData[{ + "Appendix: Quick reference to ", + StyleBox["Mathematica", + FontSlant->"Italic"] +}], "Section", + Evaluatable->False, + CellChangeTimes->{{3.513949886366438*^9, 3.513949888828957*^9}}, + AspectRatioFixed->True], + +Cell[CellGroupData[{ + +Cell["Getting started", "Subsection", + Evaluatable->False, + AspectRatioFixed->True], + +Cell[TextData[{ + "Help -> Documentation Center", + StyleBox[" - Can be used to search for commands of interest\n", + FontFamily->"Times", + FontWeight->"Plain"], + "\n?Command", + StyleBox[" - gives a fairly detailed description of a command, e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + "?Plot", + StyleBox[" tells you all about this command. \n\tYou can use * as a \ +wildcard, for instance ", + FontFamily->"Times", + FontWeight->"Plain"], + "?*Plot", + StyleBox["* gives a list of all commands with Plot in their name. \n\tMore \ +help can be found in the menu under \"Help\", in the Function Navigator or \ +Documentation Center.\n\t\n", + FontFamily->"Times", + FontWeight->"Plain"], + "*", + StyleBox[" - Times command (2*3 gives 6). Spaces can also be used but be \ +careful (e.g, ", + FontFamily->"Times", + FontWeight->"Plain"], + "a=2 3", + StyleBox[" gives six\n\tbut ", + FontFamily->"Times", + FontWeight->"Plain"], + "a=23", + StyleBox[" gives twenty-three)\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "^", + StyleBox[" - Power command (2^3 gives 8)\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "n!", + StyleBox[" - factorial (3! gives 6)\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "{}", + StyleBox[" - denotes a list, e.g., {2,3,4}\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "()", + StyleBox[" - Places variables together, e.g., (1+x)/(1-x) takes 1+x over \ +1-x\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "[]", + StyleBox[" - Generally used to denote that something is a function of \ +something else\n\n%", + FontFamily->"Times", + FontWeight->"Plain"], + "#", + StyleBox[" - grabs previous output number #.\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "%", + StyleBox[" - grabs the previous line of output regardless of the number\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "%%", + StyleBox[" - grabs output two lines back. Note: naming outputs is safer \ +(see next section).\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + "f /. object1 -> object2", + StyleBox[" \n - tells Mathematica to make replace object1 with \ +object2 in the function\n e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + "3*x^2 /. x -> 2*y+z", + StyleBox[" gives ", + FontFamily->"Times", + FontWeight->"Plain"], + "3*(2*y + z)^2 \n " +}], "Input", + CellChangeTimes->{{3.513949908602819*^9, 3.513949996977407*^9}, { + 3.5139501531450663`*^9, 3.513950178540937*^9}, {3.513950343469256*^9, + 3.513950345242174*^9}, 3.5140603007363853`*^9, {3.514060332457301*^9, + 3.514060344341905*^9}, {3.563121569604072*^9, 3.563121569929719*^9}, { + 3.618707495180807*^9, 3.618707565305377*^9}, {3.618707601648489*^9, + 3.618707609832266*^9}, {3.6187077244610243`*^9, 3.618707824899582*^9}, { + 3.618708522804984*^9, 3.61870852609206*^9}}, + AspectRatioFixed->True] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[TextData[{ + "Avoiding conflict with ", + StyleBox["Mathematica", + FontSlant->"Italic"] +}], "Subsection", + CellChangeTimes->{{3.513950368656147*^9, 3.513950374988236*^9}, + 3.513950561334874*^9}], + +Cell[TextData[{ + StyleBox["Mathematica", + FontSlant->"Italic"], + " tends to use capital letters for its functions, so its often a good idea \ +to use \nlower case names for your functions and variables.\n\nIf you refer \ +to previous entries using %, it can be difficult to know exactly what your \n\ +previous entry was. It is safer to assign a name to the output and then \ +refer to this name later.\n\nFor example," +}], "Text", + CellChangeTimes->{{3.513950396290183*^9, 3.513950507636909*^9}, { + 3.514081351768971*^9, 3.514081353894698*^9}}], + +Cell[BoxData[ + RowBox[{"myderivative", " ", "=", " ", + RowBox[{"D", "[", + RowBox[{ + RowBox[{"a", " ", + RowBox[{"Sin", "[", + RowBox[{"b", " ", "x"}], "]"}]}], ",", " ", "x"}], "]"}]}]], "Input", + CellChangeTimes->{{3.5139505131262074`*^9, 3.5139505527349653`*^9}}], + +Cell[BoxData[ + RowBox[{ + RowBox[{"Plot", "[", + RowBox[{ + RowBox[{ + RowBox[{"myderivative", "/.", + RowBox[{"a", "\[Rule]", "1"}]}], "/.", + RowBox[{"b", "\[Rule]", "3"}]}], ",", + RowBox[{"{", + RowBox[{"x", ",", "0", ",", "10"}], "}"}]}], "]"}], + "\[IndentingNewLine]"}]], "Input", + CellChangeTimes->{{3.513950521780437*^9, 3.513950546486189*^9}, { + 3.563121571454344*^9, 3.563121571645876*^9}, {3.618707770838048*^9, + 3.618707771686625*^9}, 3.618708422888011*^9}] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[TextData[{ + "Functions and constants in ", + StyleBox["Mathematica", + FontSlant->"Italic"], + "\n(A small fraction!)" +}], "Subsection", + Evaluatable->False, + AspectRatioFixed->True], + +Cell[TextData[{ + StyleBox["Abs[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - Takes the absolute value of x\n\n", + StyleBox["E", + FontFamily->"Courier", + FontWeight->"Bold"], + " - The exponential constant 2.71838. ", + StyleBox["E^(x)", + FontFamily->"Courier", + FontWeight->"Bold"], + " can be invoked using ", + StyleBox["Exp[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + StyleBox["\n", + FontSize->12], + StyleBox["\nI", + FontFamily->"Courier", + FontWeight->"Bold"], + " - The square root of negative 1.\n\n", + StyleBox["Infinity", + FontFamily->"Courier", + FontWeight->"Bold"], + " - Self-explanatory.\n\n", + StyleBox["Log[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " -Takes the natural log of x\n\n", + StyleBox["Log[b,x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " -Takes the log of x in base b\n\n", + StyleBox["Pi", + FontFamily->"Courier", + FontWeight->"Bold"], + " - 3.14159...\n\n", + StyleBox["Sin[x], Cos[x], Tan[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - trigonometric functions", + StyleBox["\n", + FontSize->12], + StyleBox["ArcSin[x], ArcCos[x], ArcTan[x] ", + FontFamily->"Courier", + FontWeight->"Bold"], + "- inverse trigonometric functions\n\n", + StyleBox["Sqrt[x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - Square root\n" +}], "Text", + Evaluatable->False, + CellChangeTimes->{{3.513950323503922*^9, 3.513950333260998*^9}, { + 3.563121524371439*^9, 3.563121524704859*^9}, {3.618707651880374*^9, + 3.618707668239052*^9}, {3.618707766796749*^9, 3.6187077676614428`*^9}, + 3.6187084181609707`*^9, {3.618708461384329*^9, 3.618708464911661*^9}}, + AspectRatioFixed->True] +}, Open ]], + +Cell[CellGroupData[{ + +Cell[TextData[{ + "Writing equations in ", + StyleBox["Mathematica", + FontSlant->"Italic"] +}], "Subsection", + Evaluatable->False, + AspectRatioFixed->True], + +Cell[TextData[{ + StyleBox["x=y", "Input", + FontWeight->"Bold"], + StyleBox[" ", "Input", + FontFamily->"Times", + FontWeight->"Bold"], + StyleBox[" - Sets x to y immediately and from then on (use Clear[x] to \ +unassign x), e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["plot1=Plot[x^2,{x,0,10}]", "Input", + FontWeight->"Bold"], + StyleBox["\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["x:=y", "Input", + FontWeight->"Bold"], + StyleBox[" - Does nothing until x is called, at which point x is assigned \ +the value y\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["x==y", "Input", + FontWeight->"Bold"], + StyleBox[" ", "Input", + FontFamily->"Times", + FontWeight->"Bold"], + StyleBox[" - Tests whether x equals y BUT makes no assignment\n\n", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["f[x_]:=", "Input", + FontWeight->"Bold"], + " ", + StyleBox["- This is how you define a function (called \"f\") of x, e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["f[x_] := x^2", "Input", + FontWeight->"Bold"], + "\n\n", + StyleBox["f[x]", "Input", + FontWeight->"Bold"], + " ", + StyleBox["- This gives the function evaluated at x, e.g., ", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["f[3]", "Input", + FontWeight->"Bold"], + StyleBox[" gives ", + FontFamily->"Times", + FontWeight->"Plain"], + "9", + StyleBox[" in the above example", + FontFamily->"Times", + FontWeight->"Plain"], + "\n\n", + StyleBox["f[x_,y_,...]=", "Input", + FontWeight->"Bold"], + " ", + StyleBox["- This is how you define a function of several variables", + FontFamily->"Times", + FontWeight->"Plain"], + StyleBox["\n\n", + FontFamily->"Times", + FontWeight->"Plain"] +}], "Input", + CellChangeTimes->{ + 3.513951162654813*^9, {3.563121328181324*^9, 3.563121345683249*^9}, { + 3.563121529178462*^9, 3.5631215293437777`*^9}, {3.618707875626803*^9, + 3.618707881302347*^9}}, + AspectRatioFixed->True] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["A list of helpful commands", "Subsection", + Evaluatable->False, + AspectRatioFixed->True], + +Cell[TextData[{ + StyleBox["Clear[symbol1,symbol2,...]", "Input"], + " - clears variable or function definitions, \n\te.g., ", + StyleBox["Clear[x, y, pop1]", "Input", + FontWeight->"Bold"], + "\n\n", + StyleBox["Clear[\[OpenCurlyDoubleQuote]Global`*\[CloseCurlyDoubleQuote]] ", + "Input", + FontWeight->"Bold"], + "- clears all variable or function definitions from memory\n\n", + StyleBox["Collect[eqn,{terms},Factor]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - collects parts of an equation involving \[OpenCurlyDoubleQuote]terms\ +\[CloseCurlyDoubleQuote] and \n\tfactors them separately (if only one \ +\[OpenCurlyDoubleQuote]term\[CloseCurlyDoubleQuote], the braces aren\ +\[CloseCurlyQuote]t needed)\n\te.g. Collect[", + Cell[BoxData[ + RowBox[{"a", "-", "b", "+", + RowBox[{"a", " ", "x"}], "-", + RowBox[{"2", " ", "b", " ", "x"}], "+", + RowBox[{ + SuperscriptBox["a", "2"], " ", + SuperscriptBox["x", "2"]}], "+", + RowBox[{"2", " ", "a", " ", "b", " ", + SuperscriptBox["x", "2"]}], "+", + RowBox[{ + SuperscriptBox["b", "2"], " ", + SuperscriptBox["x", "2"]}]}]], + CellChangeTimes->{{3.51395123610637*^9, 3.513951252570932*^9}}], + ", x, Factor]\n\n", + StyleBox["D[f,x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - takes the partial derivative of f with respect to x - e.g. D[x^2+y \ +Log[x], x]\n\n", + StyleBox["D[f, {x, n}] ", + FontFamily->"Courier", + FontWeight->"Bold"], + " - takes the nth derivative with respect to x - e.g. D[x^2+y Log[x],{x,2}]\ +\n\n", + StyleBox["DSolve[eqn, y[x],x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - solves differential equation for y as a function of x \n\t\ +(SYMBOLICALLY) e.g. DSolve[{y'[x] == k y[x], y[0]==y0, y[x],x]\n\n", + StyleBox["DSolve[eqns, {y1,y2,y3,..}, x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " same as above but for a system of eqns \n\te.g. pred-prey equations \ +DSolve[{y'[x] == k y-x, z'[x]==x+z}, {y[x],z[x]}, x]\n\n", + StyleBox["NDSolve[eqns, y, {x, xmin,xmax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - same as DSolve but seeks solution\n\tNUMERICALLY - e.g. NDSolve[{y'[x] \ +==4 y[x], y[3]==62}, y[x], {x, 0,20}]\n\n", + StyleBox["Expand[expr]", + FontFamily->"Courier", + FontWeight->"Bold"], + "- expands an expr e.g. Expand[(1+x)^2] gives 1+2x+x^2\n\n", + StyleBox["Evaluate[object]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - evaluates a symbolic object like interpolating functions\n\n", + StyleBox["Factor[polynomial]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - self explanatory - e.g. Factor[x^2 + 2 x + 1]\n\n", + StyleBox["FindRoot[eqn1==eqn2, {x, x0}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - searches for numerical root of eqn1==eqn2\n starting at x0 \ +e.g. FindRoot[Log[x] + x + Arctan[x] == 0, {x, 4}] tries to find \n \ + x that satisfies this very ugly - impossible to solve by hand equation, \ +starting at x=4.\n\n", + StyleBox["For[start,test,increment,body]", "Input", + FontWeight->"Bold"], + " - repeats procedure \[OpenCurlyDoubleQuote]body\[CloseCurlyDoubleQuote], \ +starting from \[OpenCurlyDoubleQuote]start\[CloseCurlyDoubleQuote] \n\tuntil \ +the \[OpenCurlyDoubleQuote]test\[CloseCurlyDoubleQuote] condition is met, \ +adding \[OpenCurlyDoubleQuote]increment\[CloseCurlyDoubleQuote] each time, \n\ +\te.g., ", + StyleBox["For[i=1, i\[LessEqual]10, i=i+1, Print[i]]", "Input", + FontWeight->"Bold"], + " prints out integers 1 through 10.\n\n", + StyleBox["Integrate[f,x]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - finds indefinite integral of f with respect to x \n\te.g., \ +Integrate[Log[x], x]\n\n", + StyleBox["Integrate[f, {x, xmin, xmax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - computes definite integral from xmin to xmax\n\te.g., Integrate[Log[x], \ +{x, 1,6}]\n\n", + StyleBox["ListPlot[list] ", "Input", + FontWeight->"Bold"], + "- plots a list of integers, e.g., ", + StyleBox["ListPlot[{2,4,3,5,4}]", "Input", + FontWeight->"Bold"], + "\n\n", + StyleBox["ListPlot[{{x1, y1},{x2, y2},...}] ", "Input"], + "- plots a series of {x, y} values,\n\te.g., ", + StyleBox["ListPlot[{{1,2},{2,1},{5,7}}] ", "Input", + FontWeight->"Bold"], + "To join the points with a line use:", + StyleBox["\n\t ListPlot[{{1,2},{2,1},{5,7}},PlotJoined->True] ", "Input", + FontWeight->"Bold"], + "(in ", + StyleBox["Mathematica", + FontSlant->"Italic"], + " 5)\n", + StyleBox["\t ListPlot[{{1,2},{2,1},{5,7}},Joined->True] ", "Input", + FontWeight->"Bold"], + "(in more recent versions)\n\n", + StyleBox["N[f]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - gives a numerical value for an expression - e.g. N[Pi] gives 3.14159\n\n", + StyleBox["Part[eqn,i]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - grabs the ith part of eqn, e.g., Part[3x^2+x^3,2] gives x^3\n\n", + StyleBox["Plot[f,{x,xmin,xmax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - plots f versus x on the interval [xmin,xmax] \n e.g., \ +Plot[x^2, {x,0,2}] NOTE: Plot has lots of options e.g. AxesLabel,\n \ + Grid, AxesOrigin, etc. See the manual for a complete list and usage \n \ + e.g., Plot[x^2, {x,0,2}, PlotStyle->Dashed] makes a dashed curve.\n\n", + StyleBox["Plot3D[f, {x, xmin, xmax}, {y, ymin, ymax}] ", "Input", + FontWeight->"Bold"], + "- makes a 3D plot of f\n\n", + StyleBox["Show[graphics, options]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - displays graphic objects using options e.g. \n\tShow[popplot1, \ +PlotJoined->True]\n\n", + StyleBox["Simplify[expr]", "Input", + FontWeight->"Bold"], + " - does its best to simplify an expression, expr\n\n", + StyleBox["Solve[eqns, vars]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - tries to solve one or a system equations for the vars specified \n\t\ +(SYMBOLICALLY)- e.g. Solve[{x+y ==1, x-y ==4}, {x,y}]\n\n", + StyleBox["NSolve[eqns, vars]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - does the same thing as Solve, but does it NUMERICALLY\n\t(See also \ +FindRoot)\n\n", + StyleBox["Sum[f, {i, imin, imax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - sums f from i to imax i.e. f[1] + f[2] + f[3] + ... \n (only \ +really interesting if f depends on i) - e.g. Sum[i, {i, 1,4}] gives 10.\n \ + \n", + StyleBox["Reduce[{eqns}]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - can be used to determine if a statement is true or false \n\te.g., \ +Reduce[{a + b > 1, a < 0, b < 0}]\n\t\n", + StyleBox["RSolve[eqns, vars]", + FontFamily->"Courier", + FontWeight->"Bold"], + " - solves a discrete-time equation for y as a function of x \n\t\ +(SYMBOLICALLY) e.g. RSolve[{n[t+1] == R n[t], n[0]==n0}, n[t],t]\n\t\n", + StyleBox["Table[f, {i, imin, imax}]", + FontFamily->"Courier", + FontWeight->"Bold"], + "- makes a table in list format of the function f\n\twith i values that run \ +from imin to imax - e.g. Table[i, {i, 1,4}] gives {1,2,3,4}.\n\t" +}], "Text", + Evaluatable->False, + CellChangeTimes->{{3.513950574915991*^9, 3.513950644564106*^9}, { + 3.5139506852524443`*^9, 3.5139507449534903`*^9}, {3.513951058272286*^9, + 3.513951157431922*^9}, {3.513951258750285*^9, 3.513951289125362*^9}, { + 3.513951388122881*^9, 3.5139514539888678`*^9}, {3.563121349636468*^9, + 3.56312137989666*^9}, {3.5631215383007097`*^9, 3.5631215384589367`*^9}, { + 3.5631216133411827`*^9, 3.563121629795897*^9}, {3.618706999372814*^9, + 3.6187070072615623`*^9}, {3.618707059868635*^9, 3.618707088131692*^9}, { + 3.6187079213007107`*^9, 3.6187079237033043`*^9}, {3.618707973985024*^9, + 3.6187079869762917`*^9}, {3.618708025765148*^9, 3.618708066614579*^9}, { + 3.618708105359006*^9, 3.6187081645478563`*^9}, {3.618708214244253*^9, + 3.618708219452034*^9}, 3.61870843421904*^9, {3.6187084805441637`*^9, + 3.618708512996409*^9}, 3.618708553301162*^9, {3.618708665614304*^9, + 3.618708799566545*^9}, {3.618708829907131*^9, 3.618708878628771*^9}, { + 3.618708971988484*^9, 3.6187089725306787`*^9}, {3.618709332845521*^9, + 3.618709368817597*^9}, {3.618709565197136*^9, 3.6187095669896708`*^9}, { + 3.6187096668400307`*^9, 3.6187097296590443`*^9}, {3.618709851524448*^9, + 3.618709893664585*^9}, {3.618709931444655*^9, 3.618709948061162*^9}, { + 3.618710235087677*^9, 3.618710236246958*^9}}, + AspectRatioFixed->True] +}, Open ]], + +Cell[CellGroupData[{ + +Cell["Libraries", "Subsection", + Evaluatable->False, + AspectRatioFixed->True], + +Cell[TextData[{ + StyleBox["Mathematica", + FontFamily->"Times", + FontWeight->"Plain", + FontSlant->"Italic"], + StyleBox[" has some libraries or packages that it does not load \ +automatically.\nThe Documentation Center will tell you if a function needs a \ +library.\nFor example, to plot error bars on a list plot, you will need:", + FontFamily->"Times", + FontWeight->"Plain"] +}], "Text", + CellChangeTimes->{{3.563121394475396*^9, 3.5631213999837*^9}}], + +Cell[BoxData[ + RowBox[{"Needs", "[", "\"\\"", "]"}]], "Input", + CellChangeTimes->{3.563121385155899*^9}], + +Cell[CellGroupData[{ + +Cell[BoxData[ + RowBox[{ + RowBox[{"ErrorListPlot", "[", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"1", ",", "1"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.2", "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"2", ",", "2"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.1", "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"3", ",", "4"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.3", "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"4", ",", "6"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.4", "]"}]}], "}"}], ",", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"5", ",", "7"}], "}"}], ",", + RowBox[{"ErrorBar", "[", "0.8", "]"}]}], "}"}]}], "}"}], ",", " ", + RowBox[{"Joined", "\[Rule]", "True"}], ",", + RowBox[{"PlotRange", "\[Rule]", + RowBox[{"{", + RowBox[{ + RowBox[{"{", + RowBox[{"0", ",", "6"}], "}"}], ",", + RowBox[{"{", + RowBox[{"0", ",", "8"}], "}"}]}], "}"}]}]}], "]"}], " "}]], "Input", + CellChangeTimes->{{3.513950246287406*^9, 3.513950270738648*^9}, + 3.563121389070549*^9}], + +Cell[BoxData[ + GraphicsBox[{{}, {}, + {Hue[0.67, 0.6, 0.6], + LineBox[{{1., 1.}, {2., 2.}, {3., 4.}, {4., 6.}, {5., + 7.}}], {{LineBox[{{1., 1.2}, {1., 0.8}}], + LineBox[{Offset[{1.5, 0}, {1., 1.2}], Offset[{-1.5, 0}, {1., 1.2}]}], + LineBox[{Offset[{1.5, 0}, {1., 0.8}], Offset[{-1.5, 0}, {1., 0.8}]}]}, { + LineBox[{{2., 2.1}, {2., 1.9}}], + LineBox[{Offset[{1.5, 0}, {2., 2.1}], Offset[{-1.5, 0}, {2., 2.1}]}], + LineBox[{Offset[{1.5, 0}, {2., 1.9}], Offset[{-1.5, 0}, {2., 1.9}]}]}, { + LineBox[{{3., 4.3}, {3., 3.7}}], + LineBox[{Offset[{1.5, 0}, {3., 4.3}], Offset[{-1.5, 0}, {3., 4.3}]}], + LineBox[{Offset[{1.5, 0}, {3., 3.7}], Offset[{-1.5, 0}, {3., 3.7}]}]}, { + LineBox[{{4., 6.4}, {4., 5.6}}], + LineBox[{Offset[{1.5, 0}, {4., 6.4}], Offset[{-1.5, 0}, {4., 6.4}]}], + LineBox[{Offset[{1.5, 0}, {4., 5.6}], Offset[{-1.5, 0}, {4., 5.6}]}]}, { + LineBox[{{5., 7.8}, {5., 6.2}}], + LineBox[{Offset[{1.5, 0}, {5., 7.8}], Offset[{-1.5, 0}, {5., 7.8}]}], + LineBox[{Offset[{1.5, 0}, {5., 6.2}], Offset[{-1.5, 0}, {5., 6.2}]}]}}}}, + AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], + Axes->True, + AxesOrigin->{0, 0}, + PlotRange->{{0, 6}, {0, 8}}, + PlotRangeClipping->True, + PlotRangePadding->{Automatic, Automatic}]], "Output", + CellChangeTimes->{{3.563121232176646*^9, 3.563121287867106*^9}}] +}, Open ]] +}, Open ]] +}, Open ]] +}, +WindowSize->{860, 748}, +WindowMargins->{{Automatic, 0}, {Automatic, 0}}, +PrintingCopies->1, +PrintingStartingPageNumber->1, +PrintingPageRange->{1, Automatic}, +PageHeaders->{{None, None, None}, {None, None, None}}, +PageFooters->{{None, None, None}, {None, None, None}}, +PageHeaderLines->{False, False}, +PageFooterLines->{False, False}, +PrintingOptions->{"FacingPages"->True, +"FirstPageFace"->Right, +"FirstPageFooter"->False, +"FirstPageHeader"->False, +"PaperOrientation"->"Portrait", +"PaperSize"->{489.84, 636.24}, +"PrintCellBrackets"->False, +"PrintMultipleHorizontalPages"->False, +"PrintRegistrationMarks"->False, +"PrintingMargins"->36}, +FrontEndVersion->"8.0 for Mac OS X x86 (32-bit, 64-bit Kernel) (October 5, \ +2011)", +StyleDefinitions->"Default.nb" +] +(* End of Notebook Content *) + +(* Internal cache information *) +(*CellTagsOutline +CellTagsIndex->{} +*) +(*CellTagsIndex +CellTagsIndex->{} +*) +(*NotebookFileOutline +Notebook[{ +Cell[CellGroupData[{ +Cell[567, 22, 224, 7, 67, "Section", + Evaluatable->False], +Cell[CellGroupData[{ +Cell[816, 33, 83, 2, 34, "Subsection", + Evaluatable->False], +Cell[902, 37, 2870, 86, 391, "Input"] +}, Open ]], +Cell[CellGroupData[{ +Cell[3809, 128, 201, 6, 34, "Subsection"], +Cell[4013, 136, 544, 10, 116, "Text"], +Cell[4560, 148, 282, 7, 27, "Input"], +Cell[4845, 157, 499, 13, 43, "Input"] +}, Open ]], +Cell[CellGroupData[{ +Cell[5381, 175, 185, 7, 49, "Subsection", + Evaluatable->False], +Cell[5569, 184, 1668, 58, 296, "Text", + Evaluatable->False] +}, Open ]], +Cell[CellGroupData[{ +Cell[7274, 247, 153, 6, 34, "Subsection", + Evaluatable->False], +Cell[7430, 255, 1954, 68, 183, "Input"] +}, Open ]], +Cell[CellGroupData[{ +Cell[9421, 328, 94, 2, 34, "Subsection", + Evaluatable->False], +Cell[9518, 332, 8270, 192, 1259, "Text", + Evaluatable->False] +}, Open ]], +Cell[CellGroupData[{ +Cell[17825, 529, 77, 2, 34, "Subsection", + Evaluatable->False], +Cell[17905, 533, 453, 11, 56, "Text"], +Cell[18361, 546, 121, 2, 27, "Input"], +Cell[CellGroupData[{ +Cell[18507, 552, 1326, 40, 43, "Input"], +Cell[19836, 594, 1387, 25, 251, "Output"] +}, Open ]] +}, Open ]] +}, Open ]] +} +] +*) + +(* End of internal cache information *) diff --git a/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/MaximaQuickReference.wxm b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/MaximaQuickReference.wxm new file mode 100644 index 0000000..4feca51 --- /dev/null +++ b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/MaximaQuickReference.wxm @@ -0,0 +1,174 @@ +/* [wxMaxima batch file version 1] [ DO NOT EDIT BY HAND! ]*/ +/* [ Created with wxMaxima version 19.05.7 ] */ +/* [wxMaxima: title start ] +Appendix: Quick reference to Maxima + [wxMaxima: title end ] */ + + +/* [wxMaxima: section start ] +Getting started + [wxMaxima: section end ] */ + + +/* [wxMaxima: comment start ] +If you move your cursor to right here, you will see that this command is written in an entry (bar on the left) that is Text (toggle up top says "Text"). If you move your cursor to "Getting started", right above this though, you see that is a section. + +If you move the cursor right below this sentence, you will see that it gives you a horizontal line on the left, that's a place where you can write input. Type <2+2;> but without the < > (we'll use < > to talk about what we want you to enter into maxima) and then hit enter (or shift return): + [wxMaxima: comment end ] */ + + +/* [wxMaxima: comment start ] +Maxima is very handy because it can handle numbers (like 2+2) but also equations. To see what we mean, move your cursor into the next line and hit enter (or shift return): + [wxMaxima: comment end ] */ + + +/* [wxMaxima: input start ] */ +x+x; +/* [wxMaxima: input end ] */ + + +/* [wxMaxima: section start ] +Getting help + [wxMaxima: section end ] */ + + +/* [wxMaxima: comment start ] +, or (with a space after the question mark): Prints to the screen the documentation of a particular command, e.g. prints the documentation of the integrate() function. + or (with a space after the question marks): Prints to the screen a list of items documented in the manual which contain "string" as part of their name. + returns a list of Maxima commands that have "string" appearing anywhere in them. For example, retruns a list of functions including expand(), exp(), and ratexpand(). + [wxMaxima: comment end ] */ + + +/* [wxMaxima: section start ] +Basic commands + [wxMaxima: section end ] */ + + +/* [wxMaxima: comment start ] +Operations +<*> Times command (2*3; gives 6). +<^> Power command (2^3; gives 8). + Factorial (3!; gives 6). +Parentheses +<[ ]> Denotes a list, e.g. [2,3,4]. Can also denote the argument of a recurrence equation, e.g. n[3]. +<( )> Has two functions. It can place variables together, e.g. (1+x)/(1-x) takes 1+x over 1-x. It is also used to denote arguments of functions, e.g. exp(3) is %e^3. +Grabbing output +<%o#> Grabs the previous output number # +<%> Grabs the previous output regardless of number. It is also used for some built-in symbols, e.g. %pi, %e, etc. +Other basic commands +<:> Defines a variable. For example: r : 10*x assigns the value 10*x to the symbol (variable) r. You can then perform operations on r, +e.g. 2*r returns 20*x. See also: section "Writing equations in Maxima". +<$> Omits the output of a particular operation. For example, a : 3*2; assigns the value 6 to the symbol a and returns the value 6, +whereas 3*2$ doesn't returns anything (but still performs the assignment). + Used to return numerical (instead of symbolic) values, e.g. 100*%pi, numer; returns 314.15926... +Substitutions + Tells mathematica to substitute object1 with object2 in the function, e.g. 3*x^2, x=2*y+z; gives 3*(z+2y)^2 + Same as the above + [wxMaxima: comment end ] */ + + +/* [wxMaxima: section start ] +Avoiding conflict with Maxima + [wxMaxima: section end ] */ + + +/* [wxMaxima: comment start ] +Maxima tends to use lowercase letters for functions, so you can use initial upper case names for your functions and variables. +If you refer to previous outputs using %, it can be difficult to know exactly what your previous entry was. It is safer to assign a name to the output and then refer to this name later. +For example: + [wxMaxima: comment end ] */ + + +/* [wxMaxima: input start ] */ +MyDerivative : diff(a*sin(b*x), x); +wxplot2d(subst([a = 1, b = 3], MyDerivative), [x, 0, %pi]); +/* [wxMaxima: input end ] */ + + +/* [wxMaxima: section start ] +Functions and constants in Maxima (a small fraction!) + [wxMaxima: section end ] */ + + +/* [wxMaxima: comment start ] +Absolute value, Logarithm, Square Root, Trigonometry + Takes the absolute value of x + Takes the natural log of x. Maxima doesn't have a built-in function for base 10 logarithm or other bases. You can calculate the base-n logarithm of x as log(x)/log(n); +, , Trigonometric functions +, , Inverse trigonometric functions + Square root +In-built symbols: +<%e> The exponential constant, 2.71838... %e^x can also be invoked using exp(x). +<%i> The square root of negative 1 +<%pi> 3.14159... + Infinity + [wxMaxima: comment end ] */ + + +/* [wxMaxima: section start ] +Writing equations in Maxima + [wxMaxima: section end ] */ + + +/* [wxMaxima: comment start ] + Sets x to y immediately and from then on. Use kill(x) to unassign x, e.g. plot1 : wxplot2d(x^2, [x,0,10]) +<'x : y> Does nothing until x is called, at which point x is assigned the value y + Defines an equation + Defines a function f, e.g. f(x) := x^2 + This gives the function evaluated at x, e.g. f(3), numer; gives 9 in the above example + [wxMaxima: comment end ] */ + + +/* [wxMaxima: section start ] +A list of helpful commands + [wxMaxima: section end ] */ + + +/* [wxMaxima: comment start ] +Memory + Clears variable or function definitions + Clears all variable or function definitions from memory +Algebra + - expands an expression, e.g. expand((1+x)^2) returns x^2 + 2*x + 1 + - Self explanatory. E.g. factor(x^2+2*x+1) returns (x+1)^2 + - Collects parts of an equation involving a term and factors them separately. E.g. collectterms(a-b+a*x-2*b*x+a^2*x^2, x); returns a^2*x^2+(a-2*b)-b+a + Simplifies a rational expression, e.g. a polynomial. E.g. ratsimp((x+2)*(x-2)); returns x^2-4. You can continue simplifying the expression until no further change occurs by calling fullratsimp() instead. + - meaning "radical cancelation", it is useful in simplifying expressions containing logs, exponentials and radicals. E.g. radcan( (exp(x)-1)/(exp(x/2)+1)); simplifies an expression that ratsimp() cannot simplify. + - Sums a function f which depends on i, from imin to imax. E.g. sum(i+1, i, 1, 4) returns 14 +Calculus + - Takes the partial derivative of f with respect to x. E.g. diff(x^2+y*log(x), x) returns 2*x + 1/2 + - Takes the nth derivative of f with respect to x. E.g. diff(x^2+log(x), x, 2) returns 2 - 1/(x^2) + - Finds the indefinite integral of f with respect to x. E.g. integrate(log(x),x) returns x*log(x)-x + - Finds the definite integral from xmin to xmax. E.g. integrate(log(x),x,1,6) returns 6*log(6)-5 +Solving a recursion equation for y as a function of x (in this example, y(t+1) = x*y(t)), SYMBOLICALLY, with initial value y(0) = y0: +load("solve_rec")$ +solve_rec(y[t+1] = x*y[t], y[t], y[0]=y0); +Solving a differential equation for y as a function of x (in this example, y'(t) = x*y(t)), SYMBOLICALLY, with initial value y(0) = y0: +eqn: 'diff(y(t), t) = x*y(t); +atvalue(y(t), t = 0, y0); +desolve(eqn, y(t)) +Solving a recursion equation NUMERICALLY: +*************************************************************************************** +Solving a differential equation NUMERICALLY: rk uses the Runge-Kutta method +rk(t-x^2,x,1,[t,0,8,0.1])$ +Solving an equation symbolically: +, e.g. solve(x^2 = 3, x) +Can also solve a system of equations, e.g. solve([x^2=3, y+3=x], [x, y]) +Solving an equation numerically within a given interval. For example: + returns 2.6457... +Plotting: + Plots f versus x on the interval [xmin,xmax] + Plots points with x-coordinate given by list1, and y-coordinate given by list2 +Others + Makes a table in list format of the function f with i values that run from imin to imax. E.g. makelist(i+3, i, 1, 4) returns [2,3,4,5] + [wxMaxima: comment end ] */ + + +/* [wxMaxima: input start ] */ + +/* [wxMaxima: input end ] */ + + + +/* Old versions of Maxima abort on loading files that end in a comment. */ +"Created with wxMaxima 19.05.7"$ diff --git a/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/otto1.nb.pdf b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/otto1.nb.pdf new file mode 100644 index 0000000..e2b9c7f Binary files /dev/null and b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/files/otto1.nb.pdf differ diff --git a/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/index.html b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/index.html new file mode 100644 index 0000000..457d057 --- /dev/null +++ b/docs/posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/index.html @@ -0,0 +1,531 @@ + + + + + + + + + + + + +BIOS2 Education resources - Mathematical Modeling in Ecology and Evolution + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

Mathematical Modeling in Ecology and Evolution

+
+
+

This workshop will introduce participants to the logic behind modeling in biology, focusing on developing equations, finding equilibria, analyzing stability, and running simulations.Techniques will be illustrated with the software tools, Mathematica and Maxima. This workshop was held in two parts: January 14 and January 16, 2020.

+
+
+
+
Technical
+
EN
+
+
+
+ +
+
Author
+
+ +
+ Dr Sarah P. Otto +
+
+

+ University of British Columbia +

+
+
+ +
+ + +
+
Published
+
+

January 14, 2020

+
+
+ + +
+ + +
+ + + + +
+ + + + +

In this workshop, I introduce various modelling techniques, using mostly ecological and evolutionary examples, with a focus on how computer software programs can help biologists analyze such models.

+
+

Content

+

Part 1: Classic one-variable models in ecology and evolution
+Part 2: Equilibria and their stability
+Part 3: Beyond equilibria
+Part 4: Example of building a model from scratch
+Part 5: Extending to models with more than one variable
+Part 6: Another example of building a model from scratch

+
+
+

Software

+

In my research, I primarily use Mathematica, which is a powerful software package to organize and conduct analytical modelling, but it is not free (at UBC, we have some licenses available). I will also show some example code and provide translation of most of what I present in a free software package called Maxima.

+
+

Mathematica installation

+

There is a free trial version that you can use for 15 days, if you don’t have a copy (click here to access), or you can buy a student version online. If you want to make sure that all is working, copy the code below, put your cursor over each of the following lines and press enter (on some computers, “enter” is a separate button, on others, press “shift” and “return” at the same time):

+
D[x^3,x]
+ListPlot[Table[x, {x,1,10}],Joined->True]
+RSolve[{x[t+1]\[Equal]A x[t],x[0]\[Equal]x0},x[t],t]
+PDF[NormalDistribution[0,1],x]
+

You should see (a) \(3x^2\), (b) a plot of a line, (c) \({{x[t]->A^t x0}}\), and (d) \(\frac{e^\frac{-x^2}{2}}{\sqrt{2\pi }}\).

+
+
+

Maxima installation:

+

On a Mac, install using the instructions here. For other file systems, download here.

+
+
+

Maxima testing

+

When you first open Maxima, it will give you a choice of GUIs, chose wxMaxima. Once wxMaxima is launched type this command and hit return to see if it answers 4:

+
2+2;
+

If it doesn’t, then scan the installation document for the error that you run into.

+

If it does return 4, then type in and enter these commands:

+
diff(x^3, x);
+
+wxplot2d (3*x, [x, 0, 2*%pi]);
+
+load("solve_rec")$
+solve_rec(x[t+1] = A*x[t], x[t], x[0]=x0);
+
+load("distrib")$
+pdf_normal(x,0,1);
+

You should see (a) \(3x^2\), (b) a plot of a line, (c) \({{x[t]->A^t x0}}\), and (d) \(\frac{e^\frac{-x^2}{2}}{\sqrt{2\pi }}\).

+
+
+
+

Material

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MathematicaMaximaPDF
NotebookNotebookEmbeded below
Hints and solutionsHints and solutions
Homework
Homework answersHomework answers
GuideGuide
+
+

Follow along PDF

+

This PDF was generated from the Mathematica notebook linked above. It doesn’t include dynamic plots, but it’s a good alternative if you want to print out or have a quick reference at hand.

+ +



+
+
+

+

Stability analysis of a recursion equation in a discrete-time model.

+
+
+
+
+
+

Other resources

+ +
+
+

Thanks

+

Niki Love and Gil Henriques did a great job of translating the code into wxMaxima, with limited help from me. Thanks, Niki and Gil!!

+ + + +
+ +

References

+
+Otto, Sarah P, and Troy Day. 2007. A Biologist’s Guide to Mathematical Modeling in Ecology and Evolution. Vol. 13. Princeton University Press. +
+
+ +
+ + + + \ No newline at end of file diff --git a/docs/posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/image.jpg b/docs/posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/image.jpg new file mode 100644 index 0000000..24253d9 Binary files /dev/null and b/docs/posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/image.jpg differ diff --git a/docs/posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/index.html b/docs/posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/index.html new file mode 100644 index 0000000..94c8681 --- /dev/null +++ b/docs/posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/index.html @@ -0,0 +1,414 @@ + + + + + + + + + + + + +BIOS2 Education resources - Sensibilisation aux réalités autochtones et recherche collaborative + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

Sensibilisation aux réalités autochtones et recherche collaborative

+
+
+

Série de deux webinaires sur la sensibilisation aux réalités autochtones et la recherche en collaboration avec les Autochtones, offert du 28 au 30 avril 2020 par Catherine-Alexandra Gagnon, PhD.

+
+
+
+
Transversal competencies
+
FR
+
+
+
+ + +
+ +
+
Author
+
+

Dr Catherine-Alexandra Gagnon

+
+
+ +
+
Published
+
+

April 28, 2020

+
+
+ + +
+ + +
+ + + + +
+ + + + +
+

1 Partie 1 - Sensibilisation aux réalités autochtones

+
+

Objectifs de la formation :

+
    +
  • Améliorer notre compréhension du passé et de ses impacts sur nos relations entre le avec les Peuples Autochtones.

  • +
  • Développer des notions et compétences afin d’agir contre les préjugés et le racisme.

  • +
+
+
+

Durant ce webminaire, nous allons: 

+
    +
  • Faire un survol des événements historiques importants et de leurs impacts à ce jour (Loi sur les Indiens, politiques d’assimilation, les pensionnats, etc.). 

  • +
  • Acquérir des connaissances sur la terminologie autochtone.

  • +
  • Faire un survol de certains procès et contextes légaux et voir comment ils affectent notre travail en territoire autochtone.

  • +
  • Dans une optique de réconciliation, faire une prise de conscience des préjugés persistants et discuter de stratégies pour améliorer nos relations avec les communautés.

  • +
+
+
+
+

2 Partie 2 - Recherche en collaboration avec les communautés autochtones

+
+

Objectifs de la formation :

+
    +
  • Entamer une réflexion collective envers nos pratiques de recherche et comment s’engager de manière significative avec les communautés autochtones.

  • +
  • Développer une meilleure compréhension des perceptions et attentes des communautés envers la recherche et les chercheurs.

  • +
+
+
+

Durant ce webminaire, nous allons: 

+
    +
  • Mieux comprendre la nécessité de prendre en compte les connaissances autochtones dans divers aspects de la gestion environnementale au Canada; 

  • +
  • Discuter du désir des communauté d’avoir une présence accrue dans le milieu de la recherche : comment faire?

  • +
  • Aborder et débattre des différentes approches méthodologiques pour établir des ponts en les connaissances autochtones et scientifiques.

  • +
+
+
+
+

3 Ressources

+
+

Balados

+ +
+
+

Lectures, sites internet

+ +
+
+

Filmographie

+
+

National Film Board of Canada

+ +
+
+
+

Formatrice :

+

Catherine-Alexandra Gagnon possède une expertise dans le travail collaboratif en milieux autochtones. Elle s’intéresse particulièrement à la mise en commun des savoirs locaux, autochtones et scientifiques. Elle détient un doctorat en Sciences de l’environnement et une maîtrise en Gestion de la faune de l’Université du Québec à Rimouski, un baccalauréat en biologie faunique de l’université McGill ainsi qu’un certificat en Études autochtones de l’université de Montréal. Durant ses études, elle a travaillé sur les connaissances locales et ancestrales des Aîné(e)s et chasseurs Inuit, Inuvialuit et Gwich’in du Nunavut, des Territoires du Nord-Ouest et du Yukon.

+ + +
+
+ +
+ +
+ + + + \ No newline at end of file diff --git a/docs/posts/2020-06-15-science-communication/image.jpg b/docs/posts/2020-06-15-science-communication/image.jpg new file mode 100644 index 0000000..5cc1ef2 Binary files /dev/null and b/docs/posts/2020-06-15-science-communication/image.jpg differ diff --git a/docs/posts/2020-06-15-science-communication/index.html b/docs/posts/2020-06-15-science-communication/index.html new file mode 100644 index 0000000..7db424a --- /dev/null +++ b/docs/posts/2020-06-15-science-communication/index.html @@ -0,0 +1,380 @@ + + + + + + + + + + + + + +BIOS2 Education resources - Science Communication + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

Science Communication

+
+
+

Recordings, content and handouts from a 6-hour Science Communication workshop held over two days on 15 and 16 June 2020.

+
+
+
+
Career
+
Fellow contributed
+
EN
+
+
+
+ + +
+ +
+
Authors
+
+

Gracielle Higino

+

Katherine Hébert

+
+
+ +
+
Published
+
+

June 15, 2020

+
+
+ + +
+ + +
+ + + + +
+ + + + +

The objective of this training is to share and discuss the concepts and tools that contribute to effective science communication. The training is split into two sessions, which cover the basic concepts of effective science communication and how social media tools can be used to boost the signal of your research and extend your research network. Each training takes the form of a presentation interspersed with several short activity modules, where participants are invited to use the tools we will be discussing to kickstart their own science communication.

+

This training was given on June 1 and 2, 2020. You can view recordings of each session here:

+
+

Day 1

+ +
+
+

Day 2

+ +
+
+

Session 1: The basics of science communication

+
+

Objectives:

+
    +
  1. Discuss what science communication (or SciComm) can be, and its potential role in boosting the signal of your research
  2. +
  3. Make an overview of basic concepts and tools that you can use in any medium (blog posts, presentations, conversations, twitter, etc.) to do effective science communication
  4. +
+

During this session, we:

+
    +
  1. Discuss the potential pitfalls of science communication (notably, diversity and inclusivity problems).
  2. +
  3. Cover the basic concepts of science communication, including the Golden Circle method, the creation of personas, and storytelling techniques.
  4. +
  5. Have short activities where participants can try to use some of the techniques we will be covering, such as filling in their own Golden Circle and explaining a blog post as a storyboard.
  6. +
+ + +







+
+
+
+

Session 2: Social media as a science communication tool

+
+

Objectives:

+
    +
  1. Rethink the way we write about science by exploring the world of blog posts
  2. +
  3. Clarify the mechanics of Twitter and how it can be used effectively for science communication
  4. +
+

During this session, we:

+
    +
  1. Discuss how to create a story structure using titles and the flow of ideas in blog posts, especially when we are used to writing scientific articles
  2. +
  3. Cover the basics of how Twitter works (retweets, threads, replies, hashtags, photo captions, etc.) and how to find helpful connections
  4. +
  5. Have short activities where participants will be invited to write their own Twitter biographies and to create a Twitter thread explaining a project of their choice.
  6. +
+ + +





+ + +
+
+ +
+ +
+ + + + \ No newline at end of file diff --git a/docs/posts/2020-09-21-data-visualization/image.jpg b/docs/posts/2020-09-21-data-visualization/image.jpg new file mode 100644 index 0000000..2f04cc9 Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/image.jpg differ diff --git a/docs/posts/2020-09-21-data-visualization/index.html b/docs/posts/2020-09-21-data-visualization/index.html new file mode 100644 index 0000000..a9031cd --- /dev/null +++ b/docs/posts/2020-09-21-data-visualization/index.html @@ -0,0 +1,1092 @@ + + + + + + + + + + + + + +BIOS2 Education resources - Data Visualization + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

Data Visualization

+
+
+

General principles of visualization and graphic design, and techniques of tailored visualization. This training was developed and delivered by Alex Arkilanian and Katherine Hébert on September 21st and 22nd, 2020.

+
+
+
+
Technical
+
Fellow contributed
+
EN
+
+
+
+ + +
+ +
+
Authors
+
+

Alex Arkilanian

+

Katherine Hébert

+
+
+ +
+
Published
+
+

September 21, 2020

+
+
+ + +
+ + +
+ + + + +
+ + + + +

Welcome!

+

This training covers the general principles of visualization and graphic design, and techniques of tailored visualization. More specifically, the objectives of the training are:

+
    +
  • Make an overview of basic data visualization principles, including shapes, sizes, colours, and fonts.
  • +
  • Discuss how to choose the right visualization for your data, what you want to communicate, and who you want to communicate to.
  • +
  • Tools and principles to tailor visualizations, particularly in making interpretable, interactive, and honest visualizations.
  • +
+
+

Training material

+

Click on “Show code” to learn how to do each plot!

+
+

Interactive examples

+
+ +
+
+

Streamgraph

+
+
+Show code +
# Script to make a streamgraph of the top 10 most popular dog breeds in 
+# New York City from 1999 to 2015
+
+# load libraries
+library(lubridate) # dealing with dates
+library(dplyr) # data manipulation
+library(streamgraph) #devtools::install_github("hrbrmstr/streamgraph")
+library(htmlwidgets) # to save the widget!
+
+# load the dataset
+# more information about this dataset can be found here:
+# https://www.kaggle.com/smithaachar/nyc-dog-licensing-clean
+nyc_dogs <- read.csv("data/nyc_dogs.csv")
+
+# convert birth year to date format (and keep only the year)
+nyc_dogs$AnimalBirthYear <- mdy_hms(nyc_dogs$AnimalBirthMonth) %>% year()
+
+# identify 10 most common dogs
+topdogs <- nyc_dogs %>% count(BreedName) 
+topdogs <- topdogs[order(topdogs$n, decreasing = TRUE),]
+# keep 10 most common breeds (and remove last year of data which is incomplete)
+df <- filter(nyc_dogs, BreedName %in% topdogs$BreedName[2:11] & AnimalBirthYear < 2016) %>% 
+  group_by(AnimalBirthYear) %>% 
+  count(BreedName) %>% ungroup()
+
+# get some nice colours from viridis (magma)
+cols <- viridis::viridis_pal(option = "magma")(length(unique(df$BreedName)))
+
+# make streamgraph!
+pp <- streamgraph(df, 
+                  key = BreedName, value = n, date = AnimalBirthYear, 
+                  height="600px", width="1000px") %>%
+  sg_legend(show=TRUE, label="names: ") %>%
+  sg_fill_manual(values = cols) 
+# saveWidget(pp, file=paste0(getwd(), "/figures/dogs_streamgraph.html"))
+
+# plot
+pp
+
+
+
+
+ +
+
+
+
+
+

Interactive plot

+
+
+Show code +
# Script to generate plots to demonstrate how combinations of information dimensions
+# can become overwhelming and difficult to interpret.
+
+# set-up & data manipulation ---------------------------------------------------
+
+# load packages
+library(ggplot2) # for plots, built layer by layer
+library(dplyr) # for data manipulation
+library(magrittr) # for piping
+library(plotly) # interactive plots
+
+# set ggplot theme
+theme_set(theme_classic() +
+            theme(axis.title = element_text(size = 11, face = "bold"),
+                  axis.text = element_text(size = 11),
+                  plot.title = element_text(size = 13, face = "bold"),
+                  legend.title = element_text(size = 11, face = "bold"),
+                  legend.text = element_text(size = 10)))
+
+# import data
+# more info on this dataset: https://github.com/rfordatascience/tidytuesday/blob/master/data/2020/2020-07-28/readme.md
+penguins <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-07-28/penguins.csv') 
+
+# get some nice colours from viridis (magma)
+sp_cols <- viridis::viridis_pal(option = "magma")(5)[2:4]
+
+
+#### Day 1 ####
+
+# 1. Similarity
+
+ggplot(penguins) +
+  geom_point(aes(y = bill_length_mm, x = bill_depth_mm, col = species), size = 2.5) +
+  labs(x = "Bill depth (mm)", y = "Bill length (mm)", col = "Species") + # labels
+  scale_color_manual(values = sp_cols) # sets the colour scale we created above 
+
+
+

+
+
+Show code +
ggsave("figures/penguins_similarity.png", width = 6, height = 3, units = "in")
+
+# 2. Proximity
+
+df <- penguins %>% group_by(sex, species) %>% 
+  summarise(mean_mass = mean(body_mass_g, na.rm = TRUE)) %>% na.omit() 
+ggplot(df) +
+  geom_bar(aes(y = mean_mass, x = species, fill = sex), 
+           position = "dodge", stat = "identity") +
+  labs(x = "Species", y = "Mean body mass (g)", col = "Sex") + # labels
+  scale_fill_manual(values = sp_cols) # sets the colour scale we created above
+
+
+

+
+
+Show code +
ggsave("figures/penguins_proximity.png", width = 6, height = 3, units = "in")
+
+# 3. Enclosure (Ellipses over a fake PCA)
+ggplot(data = penguins, 
+       aes(y = bill_length_mm, x = bill_depth_mm)) +
+  geom_point(size = 2.1, col = "grey30") +
+  stat_ellipse(aes(col = species), lwd = .7) +
+  labs(x = "PCA1", y = "PCA2", col = "Species") + # labels
+  scale_color_manual(values = sp_cols) + # sets the colour scale we created above
+  theme(axis.text = element_blank(), axis.ticks = element_blank())
+
+
+

+
+
+Show code +
ggsave("figures/penguins_enclosure.png", width = 6, height = 3, units = "in")
+
+# 4. Mismatched combination of principles
+temp_palette <- rev(c(sp_cols, "#1f78b4", "#33a02c"))
+ggplot(data = penguins, 
+       aes(y = bill_length_mm, x = bill_depth_mm)) +
+  geom_point(aes(col = sex), size = 2.1) +
+  stat_ellipse(aes(col = species), lwd = .7) +
+  labs(x = "Bill depth (mm)", y = "Bill length (mm)", col = "?") + # labels
+  scale_color_manual(values = temp_palette) # sets the colour scale we created above
+
+
+

+
+
+Show code +
ggsave("figures/penguins_mismatchedgestalt.png", width = 6, height = 3, units = "in")
+
+
+
+#### Day 2 ####
+
+# 1. Ineffective combinations: Luminance & shading -----------------------------
+
+# create the plot
+ggplot(penguins) +
+  geom_point(aes(y = bill_length_mm, x = bill_depth_mm, 
+                 col = species, # hue
+                 alpha = log(body_mass_g)), # luminance
+             size = 2.5) +
+  labs(x = "Bill depth (mm)", y = "Bill length (mm)", 
+       col = "Species", alpha = "Body mass (g)") +
+  scale_color_manual(values = sp_cols)
+
+
+

+
+
+Show code +
ggsave("figures/penguins_incompatible1.png", width = 6, height = 3, units = "in")
+
+# 2. Ineffective combinations: Sizes and shapes --------------------------------
+
+ggplot(penguins) +
+  geom_point(aes(y = bill_length_mm, x = bill_depth_mm, 
+                 shape = species, # shape
+                 size = log(body_mass_g)), alpha = .7) + # size
+  scale_size(range = c(.1, 5)) + # make sure the sizes are scaled by area and not by radius
+  labs(x = "Bill depth (mm)", y = "Bill length (mm)", 
+       shape = "Species", size = "Body mass (g)") 
+
+
+

+
+
+Show code +
ggsave("figures/penguins_incompatible2.png", width = 6, height = 3, units = "in")
+
+# 3. Cognitive overload --------------------------------------------------------
+
+# get some nice colours from viridis (magma)
+sex_cols <- viridis::viridis_pal(option = "magma")(8)[c(3,6)]
+
+ggplot(na.omit(penguins)) +
+  geom_point(aes(y = bill_length_mm, # dimension 1: position along y scale
+                 x = bill_depth_mm, # dimension 2: position along x scale
+                 shape = species, # dimension 3: shape
+                 size = log(body_mass_g), # dimension 4: size
+                 col = sex), # dimension 5: hue
+             alpha = .7) + # size
+  scale_size(range = c(.1, 5)) + # make sure the sizes are scaled by area and not by radius
+  labs(x = "Bill depth (mm)", y = "Bill length (mm)", 
+       shape = "Species", size = "Body mass (g)", col = "Sex") +
+  scale_color_manual(values = sex_cols)
+
+
+

+
+
+Show code +
ggsave("figures/penguins_5dimensions.png", width = 7, height = 4, units = "in")
+
+
+# 4. Panels -------------------------------------------------------------------
+
+ggplot(na.omit(penguins)) +
+  geom_point(aes(y = bill_length_mm, # dimension 1: position along y scale
+                 x = bill_depth_mm, # dimension 2: position along x scale
+                 col = log(body_mass_g)), # dimension 3: hue
+             alpha = .7, size = 2) + 
+  facet_wrap(~ species) + # dimension 4: species!
+  # this will create a separate panel for each species
+  # note: this also automatically uses the same axes for all panels! If you want 
+  # axes to vary between panels, use the argument scales = "free"
+  labs(x = "Bill depth (mm)", y = "Bill length (mm)", col = "Body mass (g)") +
+  scale_color_viridis_c(option = "magma", end = .9, direction = -1) +
+  theme_linedraw() + theme(panel.grid = element_blank()) # making the panels prettier
+
+
+

+
+
+Show code +
ggsave("figures/penguins_dimensions_facets.png", width = 7, height = 4, units = "in")
+
+
+# 5. Interactive ---------------------------------------------------------------
+
+p <- na.omit(penguins) %>%
+  ggplot(aes(y = bill_length_mm, 
+             x = bill_depth_mm, 
+             col = log(body_mass_g))) +
+  geom_point(size = 2, alpha = .7) + 
+  facet_wrap(~ species) +
+  labs(x = "Bill depth (mm)", y = "Bill length (mm)", col = "Body mass (g)") +
+  scale_color_viridis_c(option = "magma", end = .9, direction = -1) +
+  theme_linedraw() + theme(panel.grid = element_blank()) # making the panels prettier
+p <- ggplotly(p)
+#setwd("figures")
+htmlwidgets::saveWidget(as_widget(p), "figures/penguins_interactive.html")
+p
+
+
+
+ +
+
+
+
+
+

Example figures

+
+
+Show code +
# Script to make animated plot of volcano eruptions over time
+
+# Load libraries:
+library(dplyr) # data manipulation
+library(ggplot2) # plotting
+library(gganimate) # animation
+library(gifski) # creating gifs
+
+# set ggplot theme
+theme_set(theme_classic() +
+            theme(axis.title = element_text(size = 11, face = "bold"),
+                  axis.text = element_text(size = 11),
+                  plot.title = element_text(size = 13, face = "bold"),
+                  legend.title = element_text(size = 11, face = "bold"),
+                  legend.text = element_text(size = 10)))
+
+# function to floor a year to the decade
+floor_decade = function(value){return(value - value %% 10)}
+
+# read data 
+eruptions <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-05-12/eruptions.csv')
+
+# select top 5 most frequently exploding volcanoes
+temp <- group_by(eruptions, volcano_name) %>% tally() 
+temp <- temp[order(temp$n, decreasing = TRUE),]
+
+# make a time series dataset (number of eruptions per year)
+eruptions$start_decade = floor_decade(eruptions$start_year)
+
+# filter dataset to subset we want to visualize
+df <- eruptions %>% 
+  filter(between(start_decade, 1900, 2019)) %>%
+  filter(volcano_name %in% temp$volcano_name[1:5]) %>%
+  group_by(start_decade) %>%
+  count(volcano_name) %>% ungroup()
+
+# plot!
+p <- ggplot(df, aes(x = start_decade, y = n, fill = volcano_name)) +
+  geom_area() +
+  geom_vline(aes(xintercept = start_decade)) + # line that follows the current decade
+  scale_fill_viridis_d(option = "magma", end = .8) +
+  labs(x = "", y = "Number of eruptions", fill = "Volcano",
+       title = 'Eruptions of the top 5 most frequently erupting volcanos worldwide') +
+  # gganimate part: reveals each decade
+  transition_reveal(start_decade) 
+animate(p, duration = 5, fps = 20, width = 800, height = 300, renderer = gifski_renderer())
+
+
+

+
+
+Show code +
#anim_save("figures/volcano_eruptions.gif")
+
+
+
+
+Show code +
# Script to generate plots with various ways of representing uncertainty, based 
+# Coffee & Code dataset from https://www.kaggle.com/devready/coffee-and-code/data
+
+# set-up & data manipulation ---------------------------------------------------
+
+# load packages
+library(ggplot2) # for plots, built layer by layer
+library(dplyr) # for data manipulation
+library(magrittr) # for piping
+library(ggridges) # for density ridge plots
+library(patchwork) # great package for "patching" plots together!
+
+# set ggplot theme
+theme_set(theme_classic() +
+            theme(axis.title = element_text(size = 11, face = "bold"),
+                  axis.text = element_text(size = 11),
+                  plot.title = element_text(size = 13, face = "bold"),
+                  legend.title = element_text(size = 11, face = "bold"),
+                  legend.text = element_text(size = 10)))
+
+# import data
+df <- read.csv("data/coffee_code.csv")
+
+# set labels to be used in all plots
+coffee_labels <- labs(title = "Does coffee help programmers code?",
+                      x = "Coffee while coding", 
+                      y = "Time spent coding \n(hours/day)") 
+
+# the variable CodingWithoutCoffee is negative, which is harder to understand
+# (i.e. "No" means they drink coffee...). So, let's transform it into a more 
+# intuitive variable!
+df$CodingWithCoffee <- gsub("No", "Usually", df$CodingWithoutCoffee)
+df$CodingWithCoffee <- gsub("Yes", "Rarely\n or never", df$CodingWithCoffee)
+# convert to factor and set levels so they show up in a logical order
+df$CodingWithCoffee <- factor(df$CodingWithCoffee,
+                              levels = c("Rarely\n or never", 
+                                         "Sometimes", 
+                                         "Usually"))
+
+# calculate summary statistics for the variable of choice
+df_summary <- group_by(df, CodingWithCoffee) %>%
+  summarise(
+    # mean
+    mean_codinghours = mean(CodingHours), 
+    # standard deviation
+    sd_codinghours = sd(CodingHours), 
+    # standard error
+    se_codinghours = sd(CodingHours)/sqrt(length(CodingHours)))
+
+
+# 1. Error bars (standard error) -----------------------------------------------
+
+ggplot(df_summary) +
+  geom_errorbar(aes(x = CodingWithCoffee, 
+                    ymin = mean_codinghours - se_codinghours,
+                    ymax = mean_codinghours + se_codinghours), 
+                width = .2) +
+  geom_point(aes(x = CodingWithCoffee, y = mean_codinghours), 
+             size = 3) +
+  coffee_labels + ylim(0,10)
+
+
+

+
+
+Show code +
ggsave("figures/coffee_errorbars.png", width = 5, height = 3, units = "in")
+
+# 2. Boxplot -------------------------------------------------------------------
+
+ggplot(df) +
+  geom_boxplot(aes(x = CodingWithCoffee, y = CodingHours)) +
+  coffee_labels
+
+
+

+
+
+Show code +
ggsave("figures/coffee_boxplot.png", width = 5, height = 3, units = "in")
+
+
+# 3. Error bar demonstration ---------------------------------------------------
+
+# get some nice colours from viridis (magma)
+error_cols <- viridis::viridis_pal(option = "magma")(5)[2:4]
+# set labels to be used in the palette
+error_labels = c("standard deviation","95% confidence interval","standard error")
+
+ggplot(df_summary) +
+  # show the raw data
+  geom_jitter(data = df, aes(x = CodingWithCoffee, 
+                             y = CodingHours),
+              alpha = .5, width = .05, col = "grey") +
+  # standard deviation
+  geom_errorbar(aes(x = CodingWithCoffee, 
+                    ymin = mean_codinghours - sd_codinghours,
+                    ymax = mean_codinghours + sd_codinghours,
+                    col = "SD"), width = .2, lwd = 1) +
+  # 95% confidence interval
+  geom_errorbar(aes(x = CodingWithCoffee, 
+                    ymin = mean_codinghours - 1.96*se_codinghours,
+                    ymax = mean_codinghours + 1.96*se_codinghours, 
+                    col = "CI"), width = .2, lwd = 1) +
+  # standard error
+  geom_errorbar(aes(x = CodingWithCoffee, 
+                    ymin = mean_codinghours - se_codinghours,
+                    ymax = mean_codinghours + se_codinghours, 
+                    col = "SE"), width = .2, lwd = 1) +
+  geom_point(aes(x = CodingWithCoffee, y = mean_codinghours), 
+             size = 3) +
+  coffee_labels + ylim(c(0,11)) +
+  # manual palette/legend set-up!
+  scale_colour_manual(name = "Uncertainty metric", 
+                      values = c(SD = error_cols[1], 
+                                 CI = error_cols[2], 
+                                 SE = error_cols[3]),
+                      labels = error_labels) +
+  theme(legend.position = "top")
+
+
+

+
+
+Show code +
ggsave("figures/coffee_bars_demo.png", width = 7, height = 5, units = "in")
+
+
+# 4. Jitter plot with violin ---------------------------------------------------
+
+ggplot() +
+  geom_jitter(data = df, aes(x = CodingWithCoffee, 
+                             y = CodingHours),
+              alpha = .5, width = .05, col = "grey") +
+  geom_violin(data = df, aes(x = CodingWithCoffee, 
+                             y = CodingHours), alpha = 0) +
+  geom_linerange(data = df_summary,
+                 aes(x = CodingWithCoffee, 
+                     ymin = mean_codinghours - se_codinghours,
+                     ymax = mean_codinghours + se_codinghours)) +
+  geom_point(data = df_summary, 
+             aes(x = CodingWithCoffee, 
+                 y = mean_codinghours), size = 3) +
+  coffee_labels
+
+
+

+
+
+Show code +
ggsave("figures/coffee_violin_jitter.png", width = 5, height = 3, units = "in")
+
+
+# 5. Density ridge plot --------------------------------------------------------
+
+ggplot(df) + 
+  aes(y = CodingWithCoffee, x = CodingHours, fill = stat(x)) +
+  geom_density_ridges_gradient(scale = 1.9, size = .2, rel_min_height = 0.005) +
+  # colour palette (gradient according to CodingHours)
+  scale_fill_viridis_c(option = "magma", direction = -1) +
+  # remove legend - it's not necessary here!
+  theme(legend.position = "none") +
+  labs(title = coffee_labels$title, 
+       x = coffee_labels$y, 
+       y = "Coffee \nwhile coding") + 
+  theme(axis.title.y = element_text(angle=0, hjust = 1, vjust = .9, 
+                                    margin = margin(t = 0, r = -50, b = 0, l = 0)))
+
+
+

+
+
+Show code +
ggsave("figures/coffee_density_ridges.png", width = 5, height = 3, units = "in")
+
+# 6. Jitter vs. Rug plot ------------------------------------------------------------------
+
+jitterplot <- ggplot(df, aes(x = CoffeeCupsPerDay, y = CodingHours)) +
+  geom_jitter(alpha = .2) +
+  geom_smooth(fill = error_cols[1], col = "black", method = lm, lwd = .7) +
+  coffee_labels + ylim(c(0,11)) + labs(x = "Cups of coffee (per day)")
+
+rugplot <- ggplot(df, aes(x = CoffeeCupsPerDay, y = CodingHours)) +
+  geom_smooth(fill = error_cols[1], col = "black", method = lm, lwd = .7) +
+  geom_rug(position="jitter", alpha = .7) + ylim(c(0,11)) +
+  coffee_labels + labs(x = "Cups of coffee (per day)")
+
+# patch the two plots together
+jitterplot + rugplot
+
+
+

+
+
+Show code +
#ggsave("figures/coffee_jitter_vs_rugplot.png", width = 10, height = 4, units = "in")
+
+
+
+
+Show code +
# Script to generate 95% confidence intervals of a generated random normal distribution
+# as an example in Day 2: Visualizing uncertainty.
+
+# load library
+library(ggplot2)
+library(magrittr)
+library(dplyr)
+
+# set ggplot theme
+theme_set(theme_classic() +
+            theme(axis.title = element_text(size = 11, face = "bold"),
+                  axis.text = element_text(size = 11),
+                  plot.title = element_text(size = 13, face = "bold"),
+                  legend.title = element_text(size = 11, face = "bold"),
+                  legend.text = element_text(size = 10)))
+
+# set random seed
+set.seed(22)
+
+# generate population (random normal distribution)
+df <- data.frame("value" = rnorm(50, mean = 0, sd = 1))
+
+# descriptive stats for each distribution
+desc_stats = df %>% 
+  summarise(mean_val = mean(value, na.rm = TRUE),
+            se_val = sqrt(var(value)/length(value)))
+
+# build density plot!
+p <- ggplot(data = df, aes(x = value, y = ..count..)) +
+  geom_density(alpha = .2, lwd = .3) +
+  xlim(c(min(df$value-1), max(df$value+1))) 
+# extract plotted values
+base_p <- ggplot_build(p)$data[[1]]
+# shade the 95% confidence interval
+p + 
+  geom_area(data = subset(base_p, 
+                          between(x, 
+                                  left = (desc_stats$mean_val - 1.96*desc_stats$se_val),
+                                  right = (desc_stats$mean_val + 1.96*desc_stats$se_val))),
+            aes(x = x, y = y), fill = "cadetblue3", alpha = .6) +
+  # add vertical line to show population mean
+  geom_vline(aes(xintercept = 0), lty = 2) +
+  annotate("text", x = 0.9, y = 19, label = "True mean", fontface = "italic") +
+  # label axis!
+  labs(x = "Variable of interest", y = "") 
+
+
+

+
+
+Show code +
#ggsave("figures/confidenceinterval_example.png", width = 5, height = 3.5, units = "in")
+
+
+
+
+

Annotated resource library

+

This is an annotated library of data visualization resources we used to build the BIOS² Data Visualization Training, as well as some bonus resources we didn’t have the time to include. Feel free to save this page as a reference for your data visualization adventures!

+
+
+

Books & articles

+

Fundamentals of Data Visualization
A primer on making informative and compelling figures. This is the website for the book “Fundamentals of Data Visualization” by Claus O. Wilke, published by O’Reilly Media, Inc.

+

Data Visualization: A practical introduction
An accessible primer on how to create effective graphics from data using R (mainly ggplot). This book provides a hands-on introduction to the principles and practice of data visualization, explaining what makes some graphs succeed while others fail, how to make high-quality figures from data using powerful and reproducible methods, and how to think about data visualization in an honest and effective way.

+

Data Science Design (Chapter 6: Visualizing Data)
Covers the principles that make standard plot designs work, show how they can be misleading if not properly used, and develop a sense of when graphs might be lying, and how to construct better ones.

+

Graphical Perception: Theory, Experimentation, and Application to the Development of Graphical Methods
Cleveland, William S., and Robert McGill. “Graphical Perception: Theory, Experimentation, and Application to the Development of Graphical Methods.” Journal of the American Statistical Association, vol. 79, no. 387, 1984, pp. 531–554. JSTOR, www.jstor.org/stable/2288400. Accessed 9 Oct. 2020.

+

Graphical Perception and Graphical Methods for Analyzing Scientific Data
Cleveland, William S., and Robert McGill. “Graphical perception and graphical methods for analyzing scientific data.” Science 229.4716 (1985): 828-833.

+

From Static to Interactive: Transforming Data Visualization to Improve Transparency
Weissgerber TL, Garovic VD, Savic M, Winham SJ, Milic NM (2016) designed an interactive line graph that demonstrates how dynamic alternatives to static graphics for small sample size studies allow for additional exploration of empirical datasets. This simple, free, web-based tool demonstrates the overall concept and may promote widespread use of interactive graphics.

+

Data visualization: ambiguity as a fellow traveler
Research that is being done about how to visualize uncertainty in data visualizations. Marx, V. Nat Methods 10, 613–615 (2013). https://doi.org/10.1038/nmeth.2530

+

Data visualization standards
Collection of guidance and resources to help create better data visualizations with less effort.

+
+
+
+

Design principles

+

Gestalt Principles for Data Visualization: Similarity, Proximity & Enclosure
Short visual guide to the Gestalt Principles.

+

Why scientists need to be better at data visualization
A great overview of principles that could improve how we visualize scientific data and results.

+

A collection of graphic pitfalls
A collection of short articles about common issues with data visualizations that can mislead or obscure your message.

+
+
+
+

Choosing a visualization

+

Data Viz Project
This is a great place to get inspiration and guidance about how to choose an appropriate visualization. There are many visualizations we are not used to seeing in ecology!

+

From data to Viz | Find the graphic you need
Interactive tool to choose an appropriate visualization type for your data.

+
+
+
+

Colour

+

What to consider when choosing colors for data visualization
A short, visual guide on things to keep in mind when using colour, such as when and how to use colour gradients, the colour grey, etc.

+

ColorBrewer: Color Advice for Maps
Tool to generate colour palettes for visualizations with colorblind-friendly options. You can also use these palettes in R using the RColorBrewer package, and the scale_*_brewer() (for discrete palettes) or scale_*_distiller() (for continuous palettes) functions in ggplot2.

+

Color.review
Tool to pick or verify colour palettes with high relative contrast between colours, to ensure your information is readable for everyone.

+

Coblis — Color Blindness Simulator
Tool to upload an image and view it as they would appear to a colorblind person, with the option to simulate several color-vision deficiencies.

+

500+ Named Colours with rgb and hex values
List of named colours along with their hex values.

+

CartoDB/CartoColor
CARTOColors are a set of custom color palettes built on top of well-known standards for color use on maps, with next generation enhancements for the web and CARTO basemaps. Choose from a selection of sequential, diverging, or qualitative schemes for your next CARTO powered visualization using their online module.

+
+
+
+

Tools

+
+
R
+

The R Graph Gallery
A collection of charts made with the R programming language. Hundreds of charts are displayed in several sections, always with their reproducible code available. The gallery makes a focus on the tidyverse and ggplot2.

+
+
Base R
+

Cheatsheet: Margins in base R
Edit your margins in base R to accommodate axis titles, legends, captions, etc.!

+

Customizing tick marks in base R
Seems like a simple thing, but it can be so frustrating! This is a great post about customizing tick marks with base plot in R.

+

Animations in R (for time series)
If you want to use animations but don’t want to use ggplot2, this demo might help you!

+
+
+
ggplot2
+

Cheatsheet: ggplot2
Cheatsheet for ggplot2 in R - anything you want to do is probably covered here!

+

Coding Club tutorial: Data Viz Part 1 - Beautiful and informative data visualization
Great tutorial demonstrating how to customize titles, subtitles, captions, labels, colour palettes, and themes in ggplot2.

+

Coding Club tutorial: Data Viz Part 2 - Customizing your figures
Great tutorial demonstrating how to customize titles, subtitles, captions, labels, colour palettes, and themes in ggplot2.

+

ggplot flipbook
A flipbook-style demonstration that builds and customizes plots line by line using ggplot in R.

+

gganimate: A Grammar of Animated Graphics
Package to create animated graphics in R (with ggplot2).

+
+
+
+
Python
+

The Python Graph Gallery
This website displays hundreds of charts, always providing the reproducible python code.

+

Python Tutorial: Intro to Matplotlib
Introduction to basic functionalities of the Python’s library Matplotlib covering basic plots, plot attributes, subplots and plotting the iris dataset.

+

The Art of Effective Visualization of Multi-dimensional Data
Covers both univariate (one-dimension) and multivariate (multi-dimensional) data visualization strategies using the Python machine learning ecosystem.

+
+
+
Julia
+

Julia Plots Gallery
Display of various plots with reproducible code in Julia.

+

Plots in Julia
Documentation for the Plots package in Julia, including demonstrations for animated plots, and links to tutorials.

+

Animations in Julia
How to start making animated plots in Julia.

+
+
+
+
+

Customization

+

Chart Studio
Web editor to create interactive plots with plotly. You can download the image as .html, or static images, without coding the figure yourself.

+

PhyloPic
Vector images of living organisms. This is great for ecologists who want to add silhouettes of their organisms onto their plots - search anything, and you will likely find it!

+

Add icons on your R plot
Add special icons to your plot as a great way to customize it, and save space with labels!

+
+
+
+

Inspiration (pretty things!)

+

Information is Beautiful
Collection of beautiful original visualizations about a variety of topics!

+

TidyTuesday
A weekly data project aimed at the R ecosystem, where people wrangle and visualize data in loads of creative ways. Browse what people have created (#TidyTuesday on Twitter is great too!), and the visualizations that have inspired each week’s theme.

+

Wind currents on Earth
Dynamic and interactive map of wind currents on Earth.

+

A Day in the Life of Americans
Dynamic visualisation of how Americans spend their time in an average day.

+

2019: The Year in Visual Stories and Graphics
Collection of the most popular visualizations by the New York Times in 2019.

+ + +
+
+
+ +
+ +
+ + + + \ No newline at end of file diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/animated.volcano-1.gif b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/animated.volcano-1.gif new file mode 100644 index 0000000..3158806 Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/animated.volcano-1.gif differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-1.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-1.png new file mode 100644 index 0000000..70de925 Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-1.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-2.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-2.png new file mode 100644 index 0000000..618ac74 Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-2.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-3.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-3.png new file mode 100644 index 0000000..90ba722 Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-3.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-4.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-4.png new file mode 100644 index 0000000..654404e Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-4.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-5.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-5.png new file mode 100644 index 0000000..f8cc82e Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-5.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-6.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-6.png new file mode 100644 index 0000000..7588ffe Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/coffee.uncertainty-6.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/densiplot-1.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/densiplot-1.png new file mode 100644 index 0000000..52825a0 Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/densiplot-1.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-1.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-1.png new file mode 100644 index 0000000..2060854 Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-1.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-2.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-2.png new file mode 100644 index 0000000..8be7dbd Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-2.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-3.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-3.png new file mode 100644 index 0000000..56634af Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-3.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-4.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-4.png new file mode 100644 index 0000000..0163852 Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-4.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-5.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-5.png new file mode 100644 index 0000000..3ac330a Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-5.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-6.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-6.png new file mode 100644 index 0000000..d4bc38c Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-6.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-7.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-7.png new file mode 100644 index 0000000..435335f Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-7.png differ diff --git a/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-8.png b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-8.png new file mode 100644 index 0000000..f85acfe Binary files /dev/null and b/docs/posts/2020-09-21-data-visualization/index_files/figure-html/interactive-plot-8.png differ diff --git a/docs/posts/2020-12-07-making-websites-with-hugo/image.jpg b/docs/posts/2020-12-07-making-websites-with-hugo/image.jpg new file mode 100644 index 0000000..d32a2fe Binary files /dev/null and b/docs/posts/2020-12-07-making-websites-with-hugo/image.jpg differ diff --git a/docs/posts/2020-12-07-making-websites-with-hugo/index.html b/docs/posts/2020-12-07-making-websites-with-hugo/index.html new file mode 100644 index 0000000..a87d7aa --- /dev/null +++ b/docs/posts/2020-12-07-making-websites-with-hugo/index.html @@ -0,0 +1,850 @@ + + + + + + + + + + + +BIOS2 Education resources - Making websites with HUGO + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

Making websites with HUGO

+
+
+

This workshop provides a general introduction to HUGO, a popular open source framework for building websites without requiring a knowledge of HTML/CSS or web programming.

+
+
+
+
Technical
+
Transversal competencies
+
EN
+
+
+
+ + +
+ +
+
Authors
+
+

Dominique Gravel

+

Guillaume Larocque

+
+
+ +
+
Published
+
+

December 7, 2020

+
+
+ + +
+ + +
+ + + + +
+ + + + +
+

1 Why this training workshop ?

+

I am only 10 hours of a crash course in web development ahead of you. As part of a major research project on setting a biodiversity observation network, I had to develop a prototype of a portal for the project, for biodiversity information and bunch of dashboards on biodiversity trends. Never made a website before. I know how to code in a few langages, and I know that I hate playing with boxes, menus, importing images manually, and most of all, dealing with a crash of the system and having to redo the whole thing because I made a mistake somewhere. Not that a bug when I try to compile is better, but at least it is more tractable.

+

Hugo made it very easily because of its fundamental feature (which is the same reason I edit papers with LaTeX): the distinction between the view and the content. Once you have set up the rules defining the visual aspects of the pages, then you can focus on the content and let the software automatically constructing the html code for you. It’s fast, accessible, scriptable and could be version-controlled. All qualities for an open and reproducible science.

+

Took me a few hours to learn the basics (much harder to get the higher level skills, especially to write your own Go scripts), I took some tricks here and there in different templates and at looking what others do, and that was it I had my website. Realized that it could be a good entry level course to BIOS2 fellows and decided to turn that experience into a training workshop.

+

You will find below basic instructions to install and run a template. The following is not a full tutorial, for that I recommend simply to take time looking at the documentation provided on the Hugo page (https://gohugo.io/). I also consulted the online book Hugo in action (https://www.manning.com/books/hugo-in-action). There are many other references, all of them with goods and bads. But it’s nice to have multiple ones because sometimes the description of a concept may be obscure in one reference but better in the other and it’s by comparing and switching between them that you can make progress.

+
+
+

2 Make sure Hugo is installed and check version

+

First step, you have to make sure that it is properly installed on you computer. Type the following command in terminal to make sure :

+
hugo version
+

You can access to the help menu with the simple command :

+
hugo help
+
+
+

3 Be Timothée Poisot for fun

+

We will use Tim’s website, which is a simple but efficient example of what we could achieve with Hugo. The strenght of the website is that it automatically updates with the addition of new content, such as publications, lab members and projects. The only thing you have to do, once the template is properly set up, is to update the content. That way, yo can focus on the material you want to put on, without struggling on how to place the boxes, format the police and all of the complicate stuff that comes with html and css. The content, written in markdown, is human readable and therefore could be easily edited by lab members. Further, since it’s all scripted, it’s easy to maintain and control versions.

+

Take few minutes to look at the final webpage at https://poisotlab.io/

+

Now you will clone the repository on your own computer so that you could start playing with the content, edit the files, modify list of papers and so on.

+

You can either use the clone button on the top of the page or the following command :

+
git clone https://github.com/bios2/Hugo-training-workshop.git
+

We will take a few minutes to look at the content of the different folders. This structure is common to most of the Hugo templates. You will find multiple folders, it’s useful to understand what’s located where because the compiler expects this structure when it looks for specific information.

+

archetypes (not in here, but usually in most templates). These are basic instructions to generate new content with the hugo new command. We won’t use this feature today, but information about this feature is easy to find.

+

assets contains the css files where the controls for visual aspect of the pages are specified. That’s where you’ll search for the different items and how to specify things such as box sizes, font colors and dimensions etc…. Note: assets directory is not created by default.

+

content holds all of the .md files where the main content of the pages is provided. It’s divided in several subfolders, corresponding to the different pages from the menu. Each top-level folder in Hugo is considered a content section (which is described usually in the config file). For instance, you have one folder called Research where the projects are described. You’ll find one .md file per projec tin this folder. Note also that the folders contain systematically a _index.md file where the metadata and the top level information of the page are specified. We’ll come back to that later.

+

data stores specific information that will be consulted by the parser during compilation (configurationfiles). There are also data templates, and at the moment, there is one json file where the papers are listed and two toml files with a list of the students, past and present. json files could be edited with a text editor (not so fun), but there are some tools to do it efficiently.

+

layouts contains the core files to compile the website. You will find in them instructions, in a strange blend of html and Go langages. No so easy and pleasant to play with, but looking at them tells you a bit about what the compiler does (a good example is for people). list.html for instance contains a loop that goes through the toml files in order to create the icons, the text and the link to the full markdown page where you have description for each student. You will find layouts for the main pages, as well as for partials (like the header menu).

+

resources also contains css instructions for the template. We won’t work with this one.

+

static contains bunch of little things that are called during compilation. You’ll find the logo for the lab, the pictures for students, pdf files for applications, images for each research project …

+

There is also one very important file in the main folder the config.toml file. Inside, you will find a lot of the metadata that will control the structure of the main page. This find can be very simple for some templates, much more complicated for other ones. Note that for some templates, the config file may be in a distinct folder. Not all templates have exactly the same folder structure.

+

toml is a file format for configuration files, it contains key parameters for the webpage. It consists of key = “value” pairs, [section names], and # comments. Let’s open this one to have a closer look.

+
+

Exercise : Edit the toml file to include your own information.

+

You may want to change the section People to Collaborators and also provide a proper reference to your on github page. You can also add or remove sections, this will affect the menu at the top of the page. For instance, you can add a blog section.

+
+
+
+

4 Build the static html files

+
+

Build for local development

+

Hugo will use all of the material to generate static html files that will be displayed on your browser. The command is really easy to use to run it on your own computer, you simply have to type the following in the main folder :

+
hugo server
+

And that’s it, it compiles and you can simply open it in your browser by clicking on the adress indicated in the terminal. Congratulations for your first Hugo webste !

+

There are useful information in the terminal about the building process.

+
+
+

Build for publishing your website

+

The command hugo server is very fast and useful to test your website while you develop it. But once you’ll be ready to distribute it, you’ll need all of the html files and related material to distribute the website. This is easily done with the even simpler command

+
hugo
+

You will find in the directory that a new folder named public appeared, with all of the material needed to deploy the website. If you click on the index.html file, you’ll get to the home page of the website. It is interesting to open this file in your text editor, you’ll get a sense of the html code that hugo generated automatically for you. You can also take a look at other files.

+
+
+
+

5 Edit content

+

Editing content is the easier thing to do. First thing to do, is to modify the content of the introduction paragraph on the main page. You’ll find it in the *_index.md* file in the content folder. Open it and modify the text. You can after build the main page again to see the update.

+

You can also add material, with new md files. We will do so with a new research project (note the following could be done manually):

+
hugo new research/chapter1.md
+

This will generate a new markdown file, in which you can start adding material. But those files do have a particular structure, so before editing it, we’ll take a quick look at another one, datascience.md.

+

The header section is typical of a markdown file with metadata (in toml or yaml format). You have to specify information to the parser about the title, the image and associated papers. Note that it will work if some of these (e.g. papers) are missing. You can modify the image as well.

+

The file here also a particular structure, with the marker between two paragraphs. This command indicates that only the first paragraph is displayed on the main page of the Research tab, and the full content follows if you click to know more about the project.

+

Note that here you can use the basic features of markdown, with headers, bold, italics and so on. You can also include html code directly into the markdown and it should work. That said, it may conflict with higher level instructions in the layout or in the theme and may cause difficulties at building. While it is feasible to add such command, it is not recommended to do so. People rather suggest to use shortcodes (Tomorrow) or to modify the layout of the website.

+
+

Exercise

+

Take 15 minutes to remove Tim’s material and replace it by the three chapters of your thesis.

+
+
+
+

6 Hosting the website on a server

+

There are many options to host your new website on a server. An easy one, free, and that could be coupled with version control is to run it on github. Full instructions are available here :

+

https://gohugo.io/hosting-and-deployment/hosting-on-github/

+

We will simply follow the instructions copied here for hosting a personal page. Note that you can also develop a page for a project.

+
+

GitHub User or Organization Pages

+
+

Step-by-step Instructions

+
    +
  1. Create a (e.g. blog) repository on GitHub. This repository will contain Hugo’s content and other source files.
  2. +
  3. Create a .github.io GitHub repository. This is the repository that will contain the fully rendered version of your Hugo website.
  4. +
  5. git clone && cd
  6. +
  7. Paste your existing Hugo project into the new local repository. Make sure your website works locally (hugo server or hugo server -t ) and open your browser to http://localhost:1313.
  8. +
  9. Once you are happy with the results: Press Ctrl+C to kill the server Before proceeding run rm -rf public to completely remove the public directory
  10. +
  11. git submodule add -b main https://github.com//.github.io.git public. This creates a git submodule. Now when you run the hugo command to build your site to public, the created public directory will have a different remote origin (i.e. hosted GitHub repository).
  12. +
  13. Make sure the baseURL in your config file is updated with: .github.io
  14. +
+
+
+

Put it Into a Script

+

You’re almost done. In order to automate next steps create a deploy.sh script. You can also make it executable with chmod +x deploy.sh.

+

The following are the contents of the deploy.sh script:

+
    #!/bin/sh
+
+    # If a command fails then the deploy stops
+    set -e
+
+    printf "\033[0;32mDeploying updates to GitHub...\033[0m\n"
+
+    # Build the project.
+    hugo # if using a theme, replace with `hugo -t <YOURTHEME>`
+
+    # Go To Public folder
+    cd public
+
+    # Add changes to git.
+    git add .
+
+    # Commit changes.
+    msg="rebuilding site $(date)"
+    if [ -n "$*" ]; then
+        msg="$*"
+    fi
+    git commit -m "$msg"
+
+
+
+
+

7 Push source and build repos.

+
git push origin main
+

You can then run ./deploy.sh "Your optional commit message" to send changes to .github.io. Note that you likely will want to commit changes to your repository as well.

+

That’s it! Your personal page should be up and running at https://.github.io within a couple minutes.

+
+

Using a theme

+

It is usually a good idea to not modify a template directly, but to have the template and the site in a separate folder. The basic concept when doing this is that the config.toml file of the site has to link to the proper folder of the theme.

+

For example

+
theme = "template-site"
+themesDir = "../.."
+

This means that the template site is in a folder named template-site which is a parent folder of the site folder. Other options are possible.

+

Usually, all the content should go in the site folder, not in the theme folder.

+
+

Exercise 1

+
    +
  • Start modifying the theme to make it look like a website for a Zoo. Choose your preferred color scheme by changing the style= parameter in the config.toml file.

  • +
  • Feel free to download some images from unsplash and save them in the static/img folder. You can then use these images in the carrousel, as “testimonial” photos or as background images for some of the sections. You can add or remove sections from the home page by editing the config.toml file and changing the enable= parameter in the params. segment at the bottom.

  • +
  • You can also try to create a new blog entry by adding a new file in the content/blog folder. This file will have a .md extension and will be written in markdown format.

  • +
+
+
+
+

Customizing a theme

+
+
+

Basics of HTML

+

Core structure of an HTML page

+
<!DOCTYPE html>
+<html>
+<head>
+<title>This is my great website</title>
+<style>
+.css_goes_here{
+
+}
+</style>
+</head>
+<body>
+<h1>Main title</h1>
+<div>Main content goes here</div>
+</body>
+</html>
+
+

A divider, used to organize content into blocks

+
<div></div>
+
+
+

A span, used to organize content or text into sections with different styles. Usually on the same line.

+
<span></span>
+
+
+

A paragraph

+
<p></p>
+
+
+

Headings at different levels

+
<h1>Main title</h1>
+<h2>Second level</h2>
+<h3>Third level</h3>
+
+
+

An image

+
<img src='img/image_name.jpg'>
+
+ +
+ +
+

Basics of CSS

+

W3 Schools CSS reference

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDescriptionExample
width, heightwidth of item200px, 200pt, 100%, 100vw/vh
min-width, min-heightminimum size of item200px, 200pt, 100%, 100vw
colorfont color#aa0000, red or rgb(255,0,0)
background-colorcolor of background#aa0000, red or rgb(255,0,0)
border-colorcolor of border#aa0000, red or rgb(255,0,0)
bordersize, type and color of border1px solid black
marginmargin around item (top right bottom left)1px, or 1px 2px 2px 1px
paddingpadding within item, inside div for example10px
font-familyname of fontVerdana, Arial
font-sizesize of text14px, 2em
displayshould item be on the same line, or in a separate block?inline, block, inline-block, flex, …
+
+

Exercise 2

+
    +
  • Create a file named custom.css under template-site/my-site/static/css/.

  • +
  • Right-click on elements on the web page that you want to modify, then click on Inspect element and try to find CSS properties that you could modify to improve the look of the page. Then, choosing the proper class, add entries in the custom.css file that start with a dot (.) followed by the proper class names.

  • +
+
.this-class {
+    font-size:28px;
+}
+
+
+
+

Partials

+

Partials are snippets of HTML code that could be reused on different places on the website. For example, you will see that the layouts/index.html file in the template-site folder lists all the partials that create the home page.

+

An important point to remember is that Hugo will look for files first in the site’s folders, and if it doesn’t find the files there, it will look for them in the theme’s folder. So site folder layouts and CSS take priority over the theme folder.

+
+

Exercise 3

+
    +
  • Create a new folder template-site/my-site/layouts. In this folder, create a new file named index.html and copy the content of the template-site/layouts/index.html file into it. Remove the testimonials section from the newly created file.

  • +
  • Create a new folder template-site/my-site/layouts/partials. In this folder, create a new file named featured-species.html put the following content into it, replacing the information with the species you selected.

  • +
+
<div class="featured-species">
+<img src="img/species/frog.jpg" class="species-image" alt="" >
+<div class="species-description">
+<h3>Red-Eyed Tree Frog</h3>
+<p>This frog can be found in the tropical rain forests of Costa Rica.</p>
+</div>
+</div>
+
    +
  • Then, add this section to the index.html file created above.
  • +
+ +
{{ partial "featured_species.html" . }}
+
    +
  • You will probably need to restart the Hugo server to see the changes appear on the site.

  • +
  • Now, you need to edit the CSS! In your custom.css file, add the following lines.

  • +
+

+.featured-species{
+    height:300px;
+    background-color: #1d1f20;
+    color:white;
+}
+
+.species-image{
+    height:300px;
+    float:left;
+}
+
+.featured-species h3{
+    color:white;
+    font-size:1.5em;
+}
+
+.species-description{
+    float:left;
+    padding:20px;
+    font-size:2em;
+}
+

Modify this as you see fit!

+
+
+ +
+

iFrames

+

An iFrame is a HTML tag that essentially allows you to embed another web page inside of your site.

+
+

Exercise 5

+

Find a Youtube video and click on the share option below the video. Find the Embed option and copy the code that starts with <iframe> to a new partial that will be shown on a new page. Surround the iframe with a div tag with class="video". For example:

+
<div class="video">
+<iframe 
+width="560" 
+height="315" 
+src="https://www.youtube.com/embed/42GAn4v5MgE" 
+frameborder="0" 
+allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
+allowfullscreen>
+</iframe>
+</div>
+

Edit the custom.css file and add this section

+
.video{
+    width:100%;
+    background-color:black;
+    text-align:center;
+}
+ + +
+
+
+ +
+ +
+ + + + \ No newline at end of file diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/bryo_belg.csv b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/bryo_belg.csv new file mode 100644 index 0000000..ab29729 --- /dev/null +++ b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/bryo_belg.csv @@ -0,0 +1,421 @@ +richness,forest,wetland,x,y +9,0.255672132963233,0.50366141003669,228.951607822788,220.886944431353 +6,0.644911410459628,0.117206805903474,227.671366224963,219.861329849732 +5,0.5039905485024,0.632700276063605,228.825242647317,220.107306463101 +3,0.598732862396518,0.243294205736217,229.277537864747,218.90353482465 +2,0.760077519664696,0.116353831123995,209.243488725156,215.24141839558 +10,0.686543417214699,0,210.414246586351,216.557947827045 +3,0.839785092498975,0.015538612102486,213.35071759892,216.381539931761 +9,0.545333226605267,0,211.953414484825,215.445025617645 +11,0.236233553145835,0,211.185016871396,215.07926379672 +12,0.683422057139334,0,213.858801163615,215.269940181558 +16,0.833143045310801,0.010464518189639,213.568754058911,214.720146270391 +4,0.386832798463236,0.917568925751701,218.606772119611,218.134452479666 +3,0.237892620294049,0.294337397498728,222.004839916595,217.342196244754 +2,0.326475560104635,0.33457840680573,225.365902766001,217.923120138243 +4,0.247171095971234,0.353138240630657,222.437375678182,214.725705306434 +12,0.432202454471177,0.066190146635152,225.404113305381,215.783186903379 +3,0.054521149850561,0.00272450064386,224.017881092031,215.053837641996 +1,0.41750622593567,0.552442874725074,209.653346959616,212.996029269656 +1,0.09313453255658,0.247639982308695,212.287925228591,213.237901107881 +3,0.242450857976134,0.016997179326783,212.598771245333,212.735224387849 +7,0.070079594871794,0.044526867577727,213.284989649311,210.963997031485 +5,0.205714668698186,0.149512096461684,216.345099675583,211.526611509655 +4,0.846200300177145,0.0111289062932,217.546469383056,211.469112909554 +5,0.806053764368796,0,219.479313939311,211.691102450403 +9,0.897819687399119,0,218.641194283696,210.922435746684 +15,0.317400629425931,0,222.82993507475,213.652823046323 +10,0.162952614619299,0.06508764755234,225.862702553275,212.995897779714 +5,0.359877554555672,0.493281465863541,211.977431431845,208.494158523398 +14,0.538842307575382,0.165990434148626,213.683334402156,210.074828999357 +12,0.732052631429766,0.011652167958043,214.554797236308,209.83968815767 +9,0.636560029908448,0,215.977712049115,209.540641786538 +6,0.73312707547674,0,216.918325265518,209.803694891518 +8,0.582986838771166,0,217.686071317757,209.311901743298 +13,0.806018714044108,0.03755755880632,217.445247110094,208.20885661315 +15,0.373730549056661,0.088201342030938,214.962591384038,207.995466389849 +19,0.898970754752079,0.005125478403177,215.729296183879,208.058930394162 +14,0.59959511764381,0.061633296018803,214.884730953224,206.248005662967 +13,0.991073776781543,0,215.814241121722,206.210811649605 +4,0.963036796545212,0,216.886567361069,207.919480542808 +9,1,0,217.020653277284,207.56411442246 +11,0.925863396689083,0.005522322834792,216.200961837194,206.588854345183 +12,0.893398991502121,0.071259282735658,217.997097307698,206.782924575421 +14,0.905488214017747,0.037040375209397,218.478319770157,208.751644597396 +9,0.628923508490665,0.243253293741298,219.541139605422,208.418450036094 +12,0.44971977435466,0.307933324600955,220.257624379706,209.410394225975 +16,0.930250400468735,0,218.649463569479,207.516463450777 +7,0.959595359868729,0,219.989120836336,207.67922860353 +18,0.938469181195725,0,218.343474617427,206.295339543295 +5,0.709797251878674,0,219.619331102319,206.755302970919 +1,0.078031204866893,0.317439942198598,222.312934317593,209.184763150297 +6,0.130111982183339,0.34403246289178,225.031063409869,209.364909661708 +1,0.191211522906989,0.064286245667469,225.028652517007,209.036222372677 +3,0.327305963227021,0.145034049383414,223.636706463261,208.011649650444 +7,0.241883186666779,0.075673299027012,209.09858030651,202.700542042886 +10,0.104530469325793,0.286516734952814,212.32061580743,204.507528593538 +8,0.105065242134117,0.724730319552925,210.114636519192,204.08843704771 +6,0.272198713888069,0.035153852685559,217.612596377845,204.273174139911 +7,0.681901746591088,0.197476817570095,218.785741977127,205.336217094919 +7,0.857247763709511,0.07559386486936,219.462643934613,205.880022106234 +10,0.30037289339566,0.022117121154591,218.494519404801,203.518920566809 +17,0.703507016547953,0.043316657346558,218.622144247837,202.299452166228 +8,0.054898941696333,0.11776087809303,223.354960104417,206.089872799588 +6,0.202289861140164,0.245385705245707,224.689440158077,204.063344389821 +3,0.324003657233618,0.078912429145439,205.022956916013,200.456432671526 +10,0.114432759785138,0.015164367239953,204.96930957434,198.495383623444 +2,0.488989507946688,0,205.780150531673,198.523554706636 +10,0.493931777866819,0.059233079584461,208.654589125768,202.044640318964 +10,0.538407993635859,0.039307236692964,208.98473942105,200.67711363687 +6,0.373300068647369,0,207.357724462602,199.613352831143 +4,0.737745279730818,0.006451135518259,208.084038331986,199.873707787755 +3,0.074915617250855,0,212.051153537,200.472886545591 +6,0.66548789400519,0,217.673588362171,201.931088289719 +3,0.411708946073968,0,216.604005185303,200.440390049255 +9,0.146853160041507,0,218.000062064848,200.501802021179 +8,0.63684469721126,0.024999316874342,215.980778944179,199.556076929129 +9,0.623801984449809,0,214.902806517402,198.575370579415 +9,0.240892057028899,0,216.721542314974,199.841972498146 +8,0.448949557052735,0.04256897042583,216.246273476279,198.563355480476 +5,0.489965843717197,0.020423136710528,218.741825221771,200.903396039976 +5,0.189512868823355,0.017990478742869,219.389598805889,200.800276339294 +10,0.395190358147612,0.003255425805645,220.339138794339,200.807679977275 +11,0.593923038205917,0.211758971133065,221.514106545246,200.697687593762 +6,0.550140398796626,0.039851820099443,219.084801701562,199.760624075231 +14,0.052197448581771,0.295006129096471,218.75473564627,198.986366345703 +12,0.253965921311504,0.018146108665962,220.47948701924,199.310831484307 +8,0.366469005565553,0.217965334380958,221.505065053117,199.506402178124 +8,0.133568004417841,0.173285463603526,220.713889310949,199.163916963075 +8,0.187611156836221,0.177197713465518,222.459185125738,201.297864555389 +11,0.309096698237447,0.342837510850109,228.615328102254,217.289718345979 +7,0.651578484500222,0.185707002505798,229.716277493278,218.145475464648 +3,0.257388671597406,0.232445417793957,228.23612608935,216.826131501243 +8,0.24137806484115,0.503581788650103,228.095995545967,215.537156428831 +3,0.30506490288822,0.563580610571989,228.14402269793,214.205557736258 +9,0.441479068025028,0.096087733951791,229.353747794053,212.710467239384 +7,0.613292125798638,0.002629604989172,227.527525683831,211.403095080673 +7,0.181905193482368,0.26163185487612,226.673558832113,210.895898237514 +4,0.822925177562963,0.035942596561122,227.084193297163,210.883226179906 +5,0.301066740181019,0.37322296264496,228.463843530857,211.242928994975 +6,0.416887010625483,0.022420315495688,229.633711704167,211.908856592529 +9,0.438163510852438,9.13762735999e-4,229.270067605304,210.538679596891 +3,0.520880381100545,0.372906841571957,231.41153741904,211.254916642249 +2,0.485619875789438,0.44454341578727,232.829102384507,211.471108543376 +1,0.118140929106265,0.261715877533808,233.519745153955,211.921215641933 +9,0.076770457514115,0.541434944623631,234.664110587411,211.529666997415 +5,0.557513588869212,0.080082708707973,228.016250244075,210.116825470941 +5,0.390759194683692,0.226113148949314,227.822561590899,208.809930715485 +7,0.3137155381918,0.353653764971031,229.560700483036,209.08212285606 +9,0.196738109250204,0.101030597888008,226.427726715071,207.637613745794 +11,0.120738910176588,0,227.894035231754,208.054007303125 +7,0.199550260252839,0.094610619583985,228.697055246795,207.342733158653 +5,0.481904016280245,0.348687172139544,229.482671852105,207.800410592153 +9,0.119358212654253,0.417168586159651,231.242276708329,207.58863175187 +3,0.420265748498091,0.00762321204544,230.7475445212,206.759342786313 +13,0.340362312666828,0.066620322422259,231.413764023887,206.473574498824 +2,0.389358812820288,0.22135747048566,232.378266171899,206.884897445251 +3,0.088595110223195,0.146683457672303,237.639833904452,210.046429653659 +2,0.168533852249303,0.722336639663194,238.929765467033,208.175471728908 +7,0.22188733074692,0.958819437675011,240.835347808779,208.365421972943 +8,0.311237820957865,0.929777419805353,240.913294469586,207.868790189891 +4,0.52313469957026,0.805904675791075,242.827513691004,208.164811096542 +5,0.349430998633473,0.447565999043066,243.395717369359,207.668134692513 +2,0.017051094754169,0.320015294662557,247.054143822951,206.792421698958 +11,0.118294012864967,0,227.62197822981,206.126604790574 +4,0.253769363217221,0.154091211696475,228.218897127195,202.637755089362 +1,0.340621050466506,0,230.733952098725,205.579421385665 +6,0.420877357384296,0.017586695878432,231.554992995657,205.928933006253 +2,0.292679102251731,0.007420515634999,231.061728245778,203.547547935198 +7,0.275722709361746,0.073719216280676,232.891587466814,202.925657427327 +4,0.101366760404063,0.604076406209157,244.783748422398,205.310926347047 +2,0.041893863180383,0.625551405749869,242.682719783591,203.448361713827 +5,0.154577468174354,0.859243798228719,243.044094548294,202.996580307993 +1,0.099842942097012,8.28029375159e-4,252.809710265717,204.398821636111 +9,0.10390340023362,0.150261269920533,229.119493072501,201.573915555382 +8,0.074323537144875,0.172112073892936,229.456656180437,200.803917865276 +10,0.673493237701275,0.006682810815461,232.942259044035,199.871755507232 +9,0.11157931869232,0.19217022662416,234.682031050058,200.986511375064 +6,0.188592441319189,0.360453083386312,235.370647990344,200.704883745413 +7,0.097319310754023,0,235.796804543085,200.028525104902 +5,0.096329727200605,0.064871412888736,235.023275528768,199.092767369623 +9,0.411435613646839,0.317929499251582,238.841892895022,201.120076133411 +9,0.737520222923866,0,239.424452226808,200.072127787552 +11,0.753215858723829,0,239.659221200472,198.870053293339 +9,0.460616318462916,0.50534304077607,245.221346482749,201.568805890398 +16,0.843692213548856,0.305816063827816,245.264620125641,200.339471037274 +2,0.036291495030472,0,243.104114289828,199.87206436942 +4,0.116283745644645,0.040825230570817,244.462311610228,199.321823050656 +2,0.859794776504313,0.069822566622687,193.31255746784,192.480938102126 +1,0.591055693940555,0.199441204905622,193.11042190308,191.473180413867 +1,0.068072454466747,0.440435309935511,194.689925446141,195.020335711228 +7,0.246816188998233,0.138726783916658,197.484372533041,194.399574099962 +8,0.297189170699698,0.33378141592343,198.703301101424,196.193960380515 +7,0.652509842238649,0,198.932333543397,194.654703705494 +4,0.17344088748221,0.114065222252845,205.62249613914,197.693774098072 +7,0.396916207379897,0.480456728421045,207.697367315846,198.064442444833 +1,0.062199367931301,0.307018471122576,209.041061835944,194.254361677605 +5,0.360537145073111,0.006214786523577,213.213020425637,197.29388739053 +9,0.182287682694003,0.337603435519346,213.074165323398,196.226933895385 +4,0.863852326690376,0,216.191329275605,196.330443559222 +5,0.274489903003796,0.056773979515199,215.055739647442,195.534611821563 +6,0.226646157959808,0.056411467574208,214.408803381225,194.23791899501 +12,0.903974886605691,0.027299806114684,216.972516107953,195.46266090606 +11,0.582784395154036,0.255599743257333,217.245901543761,195.958466230581 +7,0.344379125104577,0.434967664729536,216.430173572034,194.282300431204 +14,0.213118845445733,0.257654522102007,220.564416454754,197.412937678171 +6,0.495369988418776,0.027581778006566,221.615787848013,196.411559216918 +7,0.184108983233606,0.086336180598,218.719679965371,195.943728574241 +6,0.584444397602811,0,219.484820175184,195.72838926261 +4,0.407412380493603,0,218.508921551485,194.312945777939 +9,0.447185489491555,0.068947204307782,223.10728807418,194.544539804959 +5,0.453499510719722,0.364891399974781,194.322643665796,193.188068907017 +5,0.764493401623906,0,195.045228108963,193.481510022197 +3,0.449063776150673,0.242657812680184,194.342836561812,192.935290895876 +9,0.397120679909248,0.01046681571361,195.832907516476,192.060988742082 +6,0.115777602154823,0.157051747131857,195.858834995622,190.919993595143 +4,0.133840330445387,0.431681630396225,197.498686519566,190.945661417364 +2,0.10786861639932,0.284428511519269,201.347304124267,193.679169400603 +6,0.247750608523399,0.320429233435654,199.725630721277,190.730370974556 +7,0.082745396348598,0.768337150905717,200.329890241961,190.443080802836 +7,0.064352301401036,0.298150106241741,202.066732901348,192.443411274355 +3,0.095930374408417,0.008224928866673,205.872520885777,192.585991062464 +2,0.027328211112741,0.244413048947032,209.309513368991,192.871708766099 +2,0.171263967959636,0.329746254491836,211.173722972594,192.347909873592 +7,0.216257149499731,0.363498587813353,211.581629159827,191.641141014096 +7,0.091945612923398,0.211997074658994,216.59668104362,193.61540415162 +5,0.138380952838482,0.708102595924613,215.749335400028,191.834503655943 +13,0.122884533214224,0.349881156648444,217.151865315505,191.612465917521 +1,0.228991907971681,0.630831491173093,219.02195138737,193.601260570118 +9,0.268980945648373,0.595745187507211,219.425563793829,192.531890993247 +1,0.200007130773287,0.141005767123193,220.884577388524,193.484273196438 +5,0.250441385231086,0.274670942076167,221.405491806914,194.159952028429 +3,0.160059281907206,0.14913110997487,219.755507123157,191.613790818878 +7,0.215440554633564,0.433194811966389,218.727575791733,190.47119401178 +10,0.528519816322015,0.252098887009346,222.156377808623,194.119821420645 +4,0.316748287609391,0,222.175541834174,192.29033245147 +8,0.266817831735713,0.089524263351206,222.5120587628,190.340222502748 +7,0.413780255083996,0.330234668120414,223.132817707224,191.039262460002 +11,0.450601335142655,0.13868044785577,224.875719845642,191.467699392388 +12,0.656595255809833,0.117588639640161,225.309353867893,191.887122439143 +8,0.414557313770071,0.246180377795,224.46278800105,190.44016202741 +2,0.075349659661953,0.347365860170834,195.14818458442,189.770705013311 +3,0.267657277900025,0.666854412331198,198.621680796346,189.682613911813 +5,0.602884985577117,0.502749508307253,201.392775618586,186.251882830324 +7,0.240349464435656,0.020648502941758,202.512050327811,187.208936817168 +7,0.186300526702303,0.329195654973988,204.70373445784,186.38461815302 +1,0.069365588346621,0.28771761490623,206.702872501187,190.092771717355 +4,0.149046084023257,0.183644304037706,208.402800492591,188.853193028139 +7,0.154133708730482,0.354673339769989,209.900562596855,187.463081664561 +7,0.213536470843008,0.66437867544473,210.460760909099,188.854875854457 +6,0.134583215984366,0.702164441730901,211.357484206757,188.30594702415 +3,0.218504627598824,0.074014529758988,213.318484203073,189.062752437552 +3,0.150172740147415,0.522790136420589,210.291311714066,186.509784204109 +22,0.219187982702232,0.35102960825395,212.228336020254,187.930682234621 +5,0.285119688145426,0.406489276252406,214.73261866622,188.840642078321 +12,0.392319932220216,0.700436265293815,215.280201794779,189.133517368471 +9,0.426624565390529,0.455774769513386,216.433542421901,188.359304247664 +5,0.458342006746162,0.594757280043226,215.481106809074,188.08379908364 +7,0.165548097877374,0.937564661482529,220.269998813861,190.124149394462 +10,0.202758996239183,0.010479252624958,221.98652166745,188.600745817654 +8,0.404493674905881,0,222.718415867969,189.125859798871 +8,0.470289476174708,0.408754569491849,225.712445708572,188.521385230597 +11,0.308854601305812,0.08951467449322,224.196361263863,187.470759199156 +11,0.311425922445102,0,224.478133692753,186.33228808005 +11,0.862787839672752,1.54407764578e-4,225.739354371906,186.373468202694 +7,0.00875834026265,0.492610028960063,201.192879859705,182.72353839494 +2,0.172749078737212,0.887011033043017,204.602029494124,183.01713158881 +1,0.10406523283154,0.927128274637828,206.750711838448,185.014728097951 +5,0.281818042615839,0.22982172760733,210.62090438764,185.266848608859 +15,0.427625580984462,0.059614484959277,211.791090785725,185.399856247481 +2,0.143114595509879,0.325519393263516,211.217608991977,184.732351408347 +6,0.101698325140498,0.302999012638732,212.001234364429,182.29507518063 +7,0.375808985131664,0.514560069911685,215.063935345937,185.011706446771 +7,0.207047470054536,0.708063265649756,216.029682501799,185.937526660979 +4,0.174064772391328,0.693043638020041,214.320746369161,183.637909867025 +7,0.399363136377605,0.365041228188653,220.398857175487,183.634347977738 +8,0.634553181372702,0.198044117823302,223.6531001215,184.933834102944 +20,0.305463864931211,0.187064290625165,225.076379847594,185.764742776759 +13,0.514071069381867,0.212553069404129,223.024583916379,183.511843726893 +6,0.543809860110861,0.18237461757918,224.097044453838,183.610437178674 +8,0.098399771962018,0.03324822526199,214.400208072005,181.613562049584 +13,0.401418375763223,0.289246640991857,225.221088121294,181.33632288385 +5,0.022439195391131,0.256070262493683,229.67612651747,197.534191641964 +11,0.369402831067038,0,228.367165823349,195.483139848725 +9,0.077866797562339,0,231.033676331829,197.44083031128 +9,0.024781531024641,0.191924405372817,230.310417296331,197.149304173894 +13,0.342969770297071,0.015336916146439,232.939383522023,197.310337958399 +6,0.130766460733172,0.004181243809966,233.917114466776,196.284342722509 +8,0.452312990822117,0.024636676148052,230.426773284761,194.325501728958 +10,0.655909489936721,1.703168355e-6,232.284461283938,196.171928808248 +8,0.519295774774994,0.073612133718094,232.938791793885,194.398029101469 +10,0.852061798945386,0.066492745013665,233.073816590591,194.740065407862 +9,0.331068776990221,0.01353584937029,235.883974585881,196.398147108972 +15,0.772682783771421,0,236.868068707523,197.233488977894 +11,0.88906588881144,0,236.102753827928,196.225580204751 +10,0.664081791260882,0,237.686660825389,196.99862416392 +8,0.731489367023291,0,234.141861796346,195.131131708777 +12,0.362635834697094,0,235.672187145533,194.47134412049 +10,0.874496817601053,0,238.920266085271,198.107718586929 +4,0.050112900607473,0.389605637110696,241.412610267636,197.725468081197 +16,0.266455879019322,0.27598395734054,240.606436054337,196.60072067404 +14,0.774960472804038,0.15642326206579,241.216605116029,196.975929771325 +11,0.383071258051512,0.101780653601336,240.957486132973,195.406315603449 +7,0.807351277974193,0,241.475388609686,195.465788928249 +13,0.358856394472193,0,240.772132986572,194.854749757719 +8,0.818555064892557,0,241.757111478478,194.451801917671 +10,0.596551270916035,0.249267831328795,242.873756232871,196.833324276384 +6,0.418517305509841,0.585188943762894,245.160273739717,198.124020094292 +11,0.294766039801396,0.050518902410791,243.129785811728,195.800551991134 +10,0.853592807165992,0,242.997616162257,194.498328669618 +11,0.141261037614223,0,228.422645422512,193.719340779128 +3,0.300120460805254,0.286790402907373,228.917237810439,192.862169465523 +10,0.744789554616801,0.286790402907373,229.997154923736,192.222148256617 +7,0.181443938524796,0.029641523371856,229.136680828522,191.436124233219 +7,0.108163141579576,0.036503355036105,228.744504419968,190.32668215308 +8,0.437426569523215,0.03073955006527,229.987663060774,191.151917433987 +4,0.623582860694328,0,230.163258929005,193.182437088115 +5,0.525444652931691,0,231.861177374575,194.17022486381 +10,0.699627531667615,0.01537613084117,232.191973458391,193.632691712825 +5,0.23889929810453,0,231.316329375807,190.785902161074 +10,0.45334596819066,0,232.048723764832,191.922252220956 +10,0.68948353350018,0,233.041238296426,191.204489667124 +12,0.73217147547930606,0,232.541671380049,190.781368417588 +16,0.972167213901594,0,233.695035831884,190.541830168261 +10,0.274799758206897,0.274157313646949,237.023117314673,193.447258584442 +11,0.215959233487273,0.730507227250739,236.578000455045,192.277234040208 +15,0.608765987121137,0,234.507571385674,190.805121647815 +17,0.34523174547835,0,240.572312620816,193.679402071524 +9,0.295645586946917,0,238.869916432736,192.172619730157 +13,0.543838682335585,0.015796329055571,238.053117719445,191.094014324869 +12,0.571284123312305,0.023436541032264,239.42450686308,190.706752092733 +6,0.672679693351292,0,241.733270446419,192.089912550214 +10,0.964664946682806,0,240.926805591325,190.597748214302 +12,0.913751290253668,0,241.802022511487,190.964709856004 +8,0.816008099544425,0,242.797656817561,192.289800557315 +13,0.730968475601645,0,242.017870460603,190.370173398095 +7,0.333036304799038,0.072406172003692,226.905482346391,189.311110338204 +9,0.585992746277046,0.017359574841173,227.735729606556,189.250598797116 +9,0.593910283725974,0,227.93287054446,188.247132098077 +7,0.390197269184134,0,229.484012731,188.067548175265 +10,0.328396303480482,0,231.13908321896,190.158773085808 +16,0.37196366330786,0,232.429098963852,189.843791767729 +3,0.08657167707614,0.525210156353128,231.961732912775,187.856317112145 +18,0.808731283731665,0.103060458071621,233.830741408628,187.458220660842 +9,0.377162383781487,0.195365013625709,232.889646038993,186.234377095398 +9,0.713365902060247,0,233.630346628719,186.753950352703 +13,0.222101058070887,0.030371767779642,235.320665234666,188.853828549858 +12,0.400488826891154,0,237.314508856389,189.780444624143 +16,0.20670911104178,0,237.390508221344,189.157492904233 +6,0.786300533684056,0,235.355882848579,187.177020169717 +12,0.936113157152227,0,234.24545014134,187.077282052875 +13,0.919934268120961,0,235.224275753101,186.813674678949 +8,0.777222888908817,0,238.461789356511,189.379537350738 +14,0.441864861015146,0,238.617502797129,189.017888875453 +7,0.850022798963408,0,240.368320363222,189.43947059592 +12,0.888212074506699,0,241.544954000155,189.889480078367 +13,0.814175895390015,0,240.969655266612,188.317078721484 +14,0.351337951248199,0,238.32376810253,187.78351135451 +22,0.861700716066725,0,239.908256158432,187.560941514947 +15,0.708025074893825,0,239.993842805935,187.112354635649 +17,0.880827971280732,0,240.140550704787,188.161883626754 +9,0.930052910788577,0,240.345708510487,186.21317649136 +10,0.619506935655564,0,242.764255723184,189.973776053645 +7,0.247081305957572,0.107417118695954,227.243236385019,184.430953320356 +8,0.218677458984958,0.07178386960703,229.130744248976,185.492536291022 +13,0.242752986957132,0.012807618078615,229.733996701774,182.431449442093 +5,0.205481626642831,0.080062842103102,230.134248054553,185.080376462087 +7,0.461555126054609,0.213419493685365,231.745451595601,184.683822622297 +12,0.647605898156674,0,233.290083441299,186.12527099462 +9,0.563899484748005,0.048800053173081,232.479535763965,184.96246592515 +10,0.554396370606929,0,233.474044984554,184.270082135227 +11,0.418570569220974,0,230.255322002074,183.26821389903 +8,0.686524867746505,0.049096184938909,231.056592635078,183.304167858946 +6,0.434431276479393,0,230.977980577586,182.668114551033 +11,0.816076627759056,0,231.771137185827,182.399804950847 +9,0.908753009333477,0,232.140735939259,183.747496622537 +8,0.810043186978443,0,232.024970197699,183.047845091128 +17,0.880808316303563,0,234.575592227014,185.464800857015 +15,0.997243741876103,0,235.156204777271,185.756097224781 +15,0.916557064440092,0,234.381770558156,184.959790421657 +17,0.926516193864315,0,235.434067914462,184.607723614907 +6,0.920353753179795,0,236.712038110823,185.016378120992 +11,0.86744863246037,0,237.838247766367,184.253267946661 +12,0.696358472389305,0,234.385039721582,183.06024981585 +9,0.478827968958284,0,235.666378215853,183.132373768293 +16,0.6696733483393,0,236.545523323699,182.48142014017 +14,0.961041047029714,0,237.611466180182,182.766651967696 +4,0.141487078138864,0,238.716890638195,185.441385589547 +16,0.427711793625826,0,239.427625257721,185.116114136538 +13,0.571986702508531,0,240.032396138993,185.360708173139 +11,0.341747850694316,0,241.92557831283,186.125438534196 +16,0.850253077609603,0,240.136643470147,185.100512495039 +16,0.83162106751941,0.024065764520183,238.120586210828,183.014167806056 +10,0.360195479660491,0,240.770737110519,183.430888927464 +10,0.605704266928258,0,240.784231437252,182.515410704228 +15,0.212779065353193,0.132424795848242,227.285386347877,179.469063458188 +13,0.49538206831463,0.048396812567486,227.369996989578,178.802495906983 +20,0.714247273646312,0.174629665651134,228.738683217785,178.360578924107 +10,0.257352414101499,0.294586691705762,229.540127825106,178.912530408629 +7,0.446893214478318,0,231.000922500122,181.513394945541 +14,0.029273173237805,0.241322726884003,231.719721527504,178.893038572433 +13,0.468822968479505,0.260002617022931,233.926477068218,180.12010563553 +8,0.616885846558249,0,234.959211827688,182.158024311539 +14,0.588511705984476,0,236.287915442253,181.177113393795 +12,0.999840067598109,0.0146957200742,237.765427949254,182.1155874373 +8,0.879414492925857,0,237.456040126619,181.044228525141 +9,0.401056671321194,0.06140756063985,234.926103692701,179.666401440899 +7,0.49285963509343,0,235.490408949986,179.374159024951 +3,0.470496041623232,0.256460259617822,234.801705796005,178.503902609383 +13,0.561578472365472,0.005645226298569,237.78649625799,179.857291438539 +7,0.519953440359642,0,236.767818813327,178.370631127774 +13,0.778068710304925,0.00697293941288,237.550051082273,178.301802402052 +17,0.88833000371013,0.115920347495792,238.923253415352,181.428194390152 +16,0.787198933038092,0.193355716737551,238.05305081882,180.565637640895 +16,0.407056101159396,0.546929813333385,241.861017397952,181.474524368772 +12,0.503473949382887,0.266130927167524,238.479146871682,179.821416454778 +12,0.750250943110173,0.088274866484203,239.586348680746,179.492352821088 +12,0.898378177037429,0.031695524023633,238.825574050391,178.648248571127 +11,0.976800140641659,0,239.312048672199,178.97762583072 +4,0.328981249717655,0.21620643202282,241.140817202276,179.803767588145 +5,0.159372798687665,0.574394745940427,220.772124744833,174.253718842442 +2,0.023530274520119,0.564439341445688,225.219131103598,177.080054183265 +11,0.217675440295018,0.843118809026025,224.857810804269,174.314328254356 +5,0.46544779321773,0.575950473586496,205.196988245587,170.898487445821 +5,0.50469192419079,0.276436552520462,209.86407521914,173.020004537197 +8,0.272092203818101,0.348288958639298,209.967716537996,171.594972552421 +1,0.355732294578319,0.629215236860365,217.950187389388,171.632398202938 +2,0.156328629640038,0.410836941541571,207.511375086814,170.012801437879 +5,0.034468606144983,0.047542709926409,207.04332431449,168.922431047315 +7,0.030192081282074,0,218.517928696437,169.126378878726 +3,0.031089690755586,0.027657873472612,218.805400485139,167.755030993993 +3,0.28906329046094,0.277357505011612,223.452040408937,169.542669137714 +2,0.188820825034041,0.388562338791239,214.855552705204,163.704207959275 +4,0.060199165730183,0.076343598203434,218.768327417517,165.753466488801 +4,0.132240246255699,0.243869238566824,219.429578383187,163.101583624181 +4,0.049621349274544,0.079749944399423,222.40325553479,164.561862498529 +4,0.048393916424625,0.078111675494354,223.955212892232,164.888114870766 +1,0.079229441266836,0.135000779100803,225.708898752809,164.980126784889 +3,0.153301851721584,0.237212012641058,223.741223296583,163.745299850979 +5,0.078528238820038,0.07692078066154,211.048951086089,158.608388236414 +2,0.091798149579948,0.159850735885966,219.06509179735,161.866518094677 +5,0.217566216774737,0.002042357789285,230.774427937077,177.692399479922 +8,0.1828799281069,0.179164339729915,231.295331332799,177.395573437221 +13,0.254034752015561,0.460975411818068,231.172951872194,177.168257460937 +8,0.500001807808926,0.030307325275892,232.651226275016,177.718634266879 +2,0.235710109869508,0.76447115782243,230.560324593646,175.583924819405 +8,0.694036605866065,0.218512965940107,235.071023471387,177.981439611183 +9,0.286221165213657,0.362667390206112,234.682635690983,177.123668693246 +5,0.784189998518492,0.106179700499499,236.791344978728,177.917558759691 +7,0.91642433640644,0,237.347889207884,177.728155178025 +10,0.617262181175951,0.142120146340396,236.853628635754,176.821790837923 +1,0.132303009745898,0.077402731712204,236.798258755936,175.388127149704 +2,0.109399946044153,0.399385400931671,236.262602123779,174.957719136418 +3,0.380129492215339,0.075260081234083,239.213275327779,177.306216075093 +3,0.086288377933151,0.571249331919913,227.598333372002,173.269457476687 +2,0.148133970510821,0.021012537395593,228.521470118196,168.139270594499 +5,0.135699231994935,0.200504505054397,229.121841397018,167.884573544531 +3,0.061528159528463,0.051838977629084,228.46865988767,165.216637260754 +5,0.136265985476486,0.636277916062792,228.914040987727,163.634493619825 +1,0.185602476872788,0.632340997942396,230.612346253091,164.029408547251 +4,0.07177875927193,0.18019830892057,211.800995171037,158.0176978577 +6,0.063370948172616,0.054618115519448,212.985444801741,156.926653554438 diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/fir.csv b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/fir.csv new file mode 100644 index 0000000..d71b57c --- /dev/null +++ b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/fir.csv @@ -0,0 +1,823 @@ +x,y,status +31.5,1,A +85.25,30.75,D +83.5,38.5,A +84,37.75,A +83,33.25,A +33.25,0.25,A +99.5,33.25,A +99.5,32.5,A +94,31.25,D +96.5,32,A +100,31,A +98,31.75,A +34.75,1,A +98,34.75,D +94,39.5,A +91.25,39.25,A +90.75,39,D +34.25,1.5,A +9,41.25,A +9.75,48,D +9,49.5,D +3,49.25,A +2.75,49,A +3.25,47,A +5,48,D +6.75,41.75,A +7,43,A +6,44,A +4.75,41.5,A +3,40.25,A +1,44.5,A +35.25,3.25,A +12,42,D +32.5,2.75,A +19.75,48,A +16.5,45.5,D +16.25,41.25,D +11.25,40.5,D +10.75,46.5,A +30.25,5.25,A +29.75,49,A +31,4.75,A +29.75,45.25,A +29.75,42.25,A +29.75,40.75,A +27,44,A +31.25,7.75,D +26.5,44.75,A +22.25,44.25,D +22.5,47,A +23,48.5,D +30.25,8.5,A +34.5,9.5,A +30.75,42.75,A +32,44.25,A +31,45,A +31.5,45.75,D +33,47,A +33.5,47.25,A +32.5,49,A +34.75,7.75,A +38.5,49.25,A +39,42,A +36,42.25,A +35,42,D +36.75,45.75,A +30,41.75,A +42,48.25,D +47.5,48.75,A +42.5,40,D +35,4.25,A +41.25,41,D +41.75,41.25,A +43,43,A +43,45,A +43,41.25,D +46.75,40.5,A +35.25,4,D +49,43,A +49.75,47,D +37,7,A +36.25,7.25,D +37.5,8.75,A +55.25,41.75,A +39.5,7.75,A +50,40.5,A +63.25,45.75,A +68.75,46.5,A +68,43.25,D +65,43,D +64,43,A +71.75,49.25,A +77.75,49.25,D +78.75,49.75,A +84.5,45.75,A +85.5,45.5,D +90.75,40.25,A +92.25,41.5,A +93.75,42.75,A +95.5,40.5,A +99,42,A +97.25,49,A +98,49,D +97.75,49.75,D +90.25,45.75,D +94.5,45,A +6,51,A +6.5,50.5,A +7.25,52.25,A +6.5,53,A +7,54.25,A +8.25,56.25,A +9.5,57.5,A +9.25,58.75,A +5.5,55,A +6.5,59,A +5.25,59,A +4.25,56.5,A +1,57.75,A +1.75,57.5,A +0.5,55,A +0.5,53.25,A +1,53,A +42,1.25,A +17,57.5,A +18.5,59.75,A +43.75,2.75,A +16.25,58.75,A +15.25,58.75,A +14,59,A +13.75,59.75,A +13.25,58.75,A +12.5,59,A +12,58.75,A +12.25,58.5,A +12,57.5,A +43.75,3.75,A +15,54.25,A +14,54.5,A +12,52,A +11.75,50.75,A +11.25,50.25,A +14.25,50.5,A +43.25,6.5,A +16.5,50,A +28.25,51,A +29.5,52.75,A +27.75,55.5,D +29.75,56,D +29.5,57.75,D +27.5,58.5,A +26.75,59.5,A +26,59,D +25,58.25,A +41,7.5,D +24.25,59.25,A +25,57,A +22.25,55.5,A +21,58.75,A +23,53.5,D +22,52,D +22.25,51,D +23.25,50.75,D +30.25,55.5,A +43.5,9,A +31.5,53,D +30.75,50.25,A +36.5,50.75,A +41.5,51.25,D +43,57,A +46,3.25,D +41.75,58,D +46.5,4,D +46.75,55,A +47.5,50.75,A +54,53,D +53,55.75,A +53,56,D +47.25,4.75,D +53.25,56,D +57.5,50.25,A +48,5,A +49,5,D +67.25,58.75,D +68,53.25,D +49.25,5.5,A +64.75,51.75,A +70,53.5,A +71,52,A +79.5,56.25,A +99.75,53,A +100,55,A +46,8,A +97,53.2,A +49,9,D +93,50.75,A +8.5,69.5,A +0.5,69,A +0.5,68.25,A +48,9,D +0.5,65.5,A +1.5,63.25,A +4,61.5,A +5,63.75,A +4.75,64,A +5,64.5,A +7.75,61,A +7.75,60.75,A +9,60.25,A +9,66.75,A +9.5,68,A +6.5,67.75,A +5.75,67.75,A +5.75,68.5,A +6.25,68.75,A +19,65.5,A +10,60.25,A +13,63.25,A +12.75,62.75,A +12,62,A +11.25,62,A +10.5,63,A +11.25,63,A +12,63.75,A +10.5,65.25,A +10.75,65.75,A +11.5,66.25,A +10,66.5,A +10.75,68.25,A +10.25,69.25,A +12,69,A +13,68.5,A +14,68.25,A +16,69.75,A +17,68,A +17,67,A +18,66,A +7,2.5,A +15,64.25,A +17.75,64.25,A +16.75,63,A +16,62,A +17,60.75,A +18.75,60.25,A +59.5,8,A +20.25,67.75,A +23,65.5,A +29.75,69.25,A +29.25,67.25,A +29.25,65.5,A +20.75,61.25,A +58,7,D +23.75,60.75,A +25.5,60,A +39.75,65,D +57,8,A +39,66,A +34,64.25,A +35,63,A +35,62,A +30.75,65.25,A +31.75,66,D +49.5,65,A +44.75,69.5,D +42.75,69.25,A +58.5,68.25,A +58,64.25,D +55,64.5,D +51.5,8.75,A +51,66.5,D +50,66.5,D +69.75,67.25,A +62,69,A +53.5,5.25,A +50.75,6,D +50.75,4.75,D +73.25,61,A +80.75,68.75,A +52,3.5,D +82,64.75,A +85,65,A +81.5,62.5,A +53.75,2.75,A +97,68.75,D +95.25,62,A +95,64,D +99.25,65.5,A +9.25,72.5,A +9.75,71,A +6.5,73,A +8,75.5,A +8,76.75,A +8,79,A +3.5,76,A +57.25,3,A +1.25,78.5,D +0.5,79,A +2,74.25,A +0.5,73.25,A +0.25,72.5,A +0.25,70.25,A +58.5,2.5,D +12.25,79,D +19.5,72.25,A +19.5,74.25,D +17.75,77.5,A +17.5,75,A +16.25,74,A +13.5,71.5,A +14.75,74,A +14.25,77.5,A +14,79.75,A +12.5,77.75,A +12,77,A +13,77.75,A +10.25,78.75,A +11,77.75,A +10.75,74.5,A +10.25,72.75,A +11.5,70,A +20.25,76.5,A +21.75,74.75,A +23.25,72.25,D +29.25,76.75,A +25.75,77.75,A +24.75,78.5,A +25,74.5,A +25,76,D +24,74.5,A +22,76.75,A +22.5,77.25,D +21,78.5,A +20.5,78,A +1.5,1.25,A +30.75,72.75,A +31.25,74.75,D +31,76,A +63,8,A +35.75,73,A +63.5,6.5,D +47,78.25,A +65,9.5,D +65,6,D +51.5,74.25,A +51.75,75.75,A +67.75,6,D +56,79.5,D +67.5,3.75,A +62.25,73,A +62,74.5,A +62.25,74.5,A +60,79.25,A +65.5,78,A +67.75,79.5,A +2,1.75,A +63,2.5,D +78,74.75,D +75.5,78.75,D +73,72.75,A +72,70.25,A +75,70.75,A +72.75,74,A +84.75,73,A +93,74.25,D +92.25,73.25,D +95,78,A +93,70.75,A +2,86.25,D +73.75,1.25,A +0.25,89,A +8.75,83,A +9.25,87,D +3.5,84,D +9.5,82.5,D +1.75,83.75,D +79,1,A +10,82,A +10.5,85.75,A +19,84,A +16.5,83,A +19,86,A +17.5,85.5,A +14.75,86,A +12,81.5,D +12,82.5,A +10.25,89.25,A +78.25,6.5,D +11,85,A +79.75,7,A +25,87.5,A +25,86.5,A +24.75,84.75,A +79,9.5,D +23.75,80.25,A +23.5,81.5,A +23,83.25,A +21.5,89,A +33,83.5,A +76.75,8.75,D +37.25,84.75,A +36,85.75,A +36.5,88.75,A +32,88.75,D +76.25,8.5,D +3.25,2.5,A +44,86.25,A +45.5,82.75,A +54,81.75,A +72.5,8.25,D +51,85,A +62.75,81.25,A +72,5,D +68.75,82,D +67.5,86,D +67.5,89,A +67,88.25,A +70.25,84.75,A +74,81,A +75.5,84.25,A +73,84,A +73.25,85,A +85,84.5,A +88.5,84.25,A +85.25,83,A +83,80,A +82,84,A +2.75,3.75,A +95,87,A +95.5,81.5,A +93.25,81,A +91.5,85,D +0.25,92.5,A +1.25,96.5,A +1.25,99.75,A +3.75,100,A +2.5,97.75,A +5,94,A +9,92.75,A +8.25,100,A +8,94.25,A +8.5,99,A +7.5,99,A +84,8.25,A +19.25,90,D +10.5,90,A +81.25,9,D +10,95,A +10.75,97.5,A +10.75,100,A +12.25,99.75,A +13.75,98.75,A +17,97.5,A +18.5,90.75,A +80.75,7,A +14.25,94.5,A +20,95.25,A +21.25,92.5,A +22,95,A +23,99.25,A +25.5,100,A +26,97.25,A +25.5,94,A +83.75,6,D +28.25,95.75,A +83,4.75,D +35,95,A +86,5,A +85.25,2.5,A +48,90.75,A +46.75,92.75,A +43.25,91,A +85,2.5,D +53.75,90,A +52,94,A +83.75,2,A +0.25,2,A +63,90,A +60.25,96.5,D +62.75,99,A +67,97,A +66.75,93,A +69.5,90.5,A +72,96.25,A +74,94,A +75.5,93.75,A +75.75,97,A +74.75,99,A +79.75,99,A +79,91,A +82.75,93.5,A +80.25,94,A +80.75,96.25,A +84.75,99.25,A +85.25,97,A +86.75,94.25,A +87.75,94.75,D +88,97.5,A +87.25,90,A +99.25,9,A +99.25,7,A +92,92,D +92.25,94,A +1.75,6,A +93.5,92.75,A +99,0,A +98,0.25,D +98.5,3,D +98.75,4,A +98,6,D +96,7,A +95,8,D +94,7.5,D +93,7,A +92,5.25,D +96.25,3.25,A +95.5,3,D +95.25,2,A +93,0.5,D +92,1,A +5.25,5.5,A +91.75,1.75,D +90.25,1,D +90.25,2.5,A +5.5,10.25,A +1,12,A +0.5,14,A +0.75,16.5,D +3.75,16.25,A +4.25,17,A +3,19,A +1,18.5,A +1,17.75,A +1.75,18.25,A +2,12.75,A +6,14,A +7,13.25,A +7.5,13.25,A +7.5,15,A +9,5.25,A +5.75,19.5,D +7.75,17.75,D +8.75,17,D +14,13,A +13.5,16,A +18.75,19.5,A +14.25,16,A +29,18,A +26.5,12.25,A +26.25,13.25,A +24.25,15.25,A +26.25,18,A +23.75,14,A +25,12,A +26,11.25,A +22,11.25,A +21.75,12,A +39.25,10.5,A +37.75,14,A +30.5,10,A +30.5,11.5,D +30.75,11,A +31.5,11,A +31.5,12.5,A +34.5,12,A +35.25,11.5,A +33.5,14,A +35,16,D +36.25,19.5,A +38,18.75,D +48.75,10.5,D +48.5,12,D +46.5,12,D +47.5,12.5,D +47.75,15.25,D +48.5,16.3,A +45,15.75,D +43.75,18,D +45.25,18,D +45.5,19.5,A +47,19,A +48,19.75,A +41,19,D +40.75,16,D +14.25,6,A +44,11,D +44.75,12.5,A +41,10.25,A +13,4,A +50.5,14.75,A +54.25,10.25,D +54.75,10.25,D +56.25,11.75,A +57.5,12,A +57,14,D +11.5,2,A +58.25,14.75,A +58.25,19,D +56,19,A +55,16.5,A +51.75,18,A +51.25,17,A +52,15.5,D +52,15,D +12,0.25,A +50.5,10.5,A +69.25,14,D +68,14,D +67,15,A +66,15,A +69.75,18.5,D +68.75,17.75,A +63.75,18.5,D +64.25,17,D +60,11.75,D +65.5,12.5,D +74.5,10,D +16.75,0.25,A +73.75,10.75,A +72.5,12.75,D +71.25,14,D +76,16.75,D +79.25,14,D +17,2.5,A +81.25,11,D +16.25,3,D +81,15,D +84.25,13,D +85,15,D +85.5,14,D +87.75,17.5,A +86,19.5,A +82.25,18.75,D +82,17.5,D +89.5,19,A +89,18,A +89.5,14.25,D +88,12,D +94.75,11.25,A +95,15,A +93.25,14.5,D +92,15,D +91.5,18.25,A +94,18,D +93.5,19,D +97,19,A +19,1,D +96.25,17,A +99.25,15,A +98,12.75,A +99,11.25,A +99.25,10.75,D +0.5,21.25,A +0.75,24.5,A +0.25,26.75,A +1,26.75,A +2,24.75,A +7,29,A +6.5,28,A +4,21.25,A +3.75,22.5,A +3,21,A +18.5,25,A +18,24.5,A +13.5,26.25,A +28.75,28.75,D +31.5,21,D +34.5,21.5,A +38,21,D +38.25,20.25,A +39,25.25,A +31.75,29,D +33,26.25,A +34.5,25,D +20,1.75,D +42,23.25,D +42.25,23,D +43,29,D +47.25,29.25,D +46.75,28.75,A +44.5,21,A +46,22.5,A +44,23,D +43.75,29.75,D +9,8.75,A +20.75,6.5,D +52.5,20,A +55.25,21.5,A +57.75,22,A +57.75,22.72,A +59.25,26,A +58,27.5,D +20.75,6.75,A +56.75,27.5,A +55.5,28.25,A +51.75,27,A +54.75,25,A +53,23,A +55.75,24,A +24.5,8.5,A +55.75,25.25,A +59.75,27.75,D +52,20.25,D +60.25,21,A +60,23.5,A +61.75,26.75,A +61.25,26.75,A +63,29,D +64.5,29,D +69,25,A +67.25,26.75,D +28.75,7.75,D +63.25,21.25,A +70,20.25,A +70.75,22.5,D +79,28.5,A +78.5,21.25,D +74.5,20,D +83.5,21.25,D +85.25,21.25,D +85,24,A +88.75,27,D +28,5.75,A +86.5,28.5,D +83,28.25,A +81,28.25,A +82,26,D +92.5,20.5,D +94.75,20.5,A +26,8,A +98,23,D +98.25,23.75,A +99,23.75,A +96.75,28.75,A +92.5,28.25,A +93,26,D +26,7.75,A +100,25.5,A +1.25,30.75,A +0.75,31.25,A +0.25,31.5,A +1.75,32,A +1.5,36.5,D +4.25,34.25,A +8.25,38.75,A +7.75,37.25,D +7,36,A +10,34.25,A +12.25,38.5,A +10.75,34,A +12,34,A +12.5,33,A +23,4.5,A +13,32.5,A +14.5,36,D +14.5,39.5,D +16,39,A +23.25,3.75,A +19.75,36.75,D +19.75,30.25,D +16.5,30.75,D +15.75,31.75,A +15.5,30.25,A +20,31.5,A +26.75,0.75,A +24.5,30.25,D +22.25,37,A +22.5,36.5,D +25,36.5,D +25.75,35,A +29.5,39,A +29.5,1.5,A +27.75,32,A +39.75,36.25,D +36.5,37,D +30.75,32.75,A +31,32.25,A +32,34.5,A +31.75,35.5,A +30.5,34.25,A +30.25,33,A +38,31.25,D +38.5,30,A +40.75,33,A +42,31,D +43,30.25,D +49.25,31.5,A +49,30.75,A +48.25,35.75,D +49,37.75,D +45.25,36,A +46.5,36.25,D +58.25,30,A +50,39,D +51.5,32,D +51,37.5,A +53.25,37.5,A +59,35,D +59,31.5,D +55.75,31,D +54.25,31,D +57.25,39.5,D +61.25,33.5,A +62,34.25,A +65,32.25,D +64.25,33,D +64.5,33,D +63.75,39.25,A +63.25,38.75,D +64,38,A +67,35,A +70,38.75,D +70.25,31.25,A +72.75,31.25,D +78.25,38,D +78.25,33.75,D +78.25,36.25,D +76.75,31.75,A +77,30.5,D +81,36.25,A +81.25,31.5,A +81,35.5,A +87.5,39,A diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/gambia.csv b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/gambia.csv new file mode 100644 index 0000000..50d63b1 --- /dev/null +++ b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/gambia.csv @@ -0,0 +1,2036 @@ +id_village,x,y,pos,age,netuse,treated,green,phc +1,349.6313,1458.055,1,1783,0,0,40.85,1 +1,349.6313,1458.055,0,404,1,0,40.85,1 +1,349.6313,1458.055,0,452,1,0,40.85,1 +1,349.6313,1458.055,1,566,1,0,40.85,1 +1,349.6313,1458.055,0,598,1,0,40.85,1 +1,349.6313,1458.055,1,590,1,0,40.85,1 +1,349.6313,1458.055,1,589,1,0,40.85,1 +1,349.6313,1458.055,0,609,1,0,40.85,1 +1,349.6313,1458.055,0,791,1,0,40.85,1 +1,349.6313,1458.055,1,829,0,0,40.85,1 +1,349.6313,1458.055,0,876,0,0,40.85,1 +1,349.6313,1458.055,0,967,1,0,40.85,1 +1,349.6313,1458.055,1,972,1,0,40.85,1 +1,349.6313,1458.055,0,1001,1,0,40.85,1 +1,349.6313,1458.055,1,1005,0,0,40.85,1 +1,349.6313,1458.055,0,1063,1,0,40.85,1 +1,349.6313,1458.055,0,1126,1,0,40.85,1 +1,349.6313,1458.055,0,1177,1,0,40.85,1 +1,349.6313,1458.055,0,1191,1,0,40.85,1 +1,349.6313,1458.055,1,1237,1,0,40.85,1 +1,349.6313,1458.055,1,1377,0,0,40.85,1 +1,349.6313,1458.055,1,1385,1,0,40.85,1 +1,349.6313,1458.055,1,1411,1,0,40.85,1 +1,349.6313,1458.055,0,1478,1,0,40.85,1 +1,349.6313,1458.055,1,1484,1,0,40.85,1 +1,349.6313,1458.055,1,1506,0,0,40.85,1 +1,349.6313,1458.055,1,1520,1,0,40.85,1 +1,349.6313,1458.055,1,1581,1,0,40.85,1 +1,349.6313,1458.055,0,1625,1,0,40.85,1 +1,349.6313,1458.055,1,1633,1,0,40.85,1 +1,349.6313,1458.055,1,1648,1,0,40.85,1 +1,349.6313,1458.055,0,1686,1,0,40.85,1 +1,349.6313,1458.055,0,1755,1,0,40.85,1 +2,358.5431,1460.112,1,1836,1,0,40.85,1 +2,358.5431,1460.112,1,1774,1,1,40.85,1 +2,358.5431,1460.112,0,371,0,0,40.85,1 +2,358.5431,1460.112,0,382,1,1,40.85,1 +2,358.5431,1460.112,0,371,1,1,40.85,1 +2,358.5431,1460.112,0,368,1,1,40.85,1 +2,358.5431,1460.112,0,400,0,0,40.85,1 +2,358.5431,1460.112,0,400,1,0,40.85,1 +2,358.5431,1460.112,0,394,1,1,40.85,1 +2,358.5431,1460.112,0,431,1,1,40.85,1 +2,358.5431,1460.112,0,464,1,1,40.85,1 +2,358.5431,1460.112,0,529,1,0,40.85,1 +2,358.5431,1460.112,0,531,1,1,40.85,1 +2,358.5431,1460.112,0,596,0,0,40.85,1 +2,358.5431,1460.112,0,591,1,1,40.85,1 +2,358.5431,1460.112,0,664,0,0,40.85,1 +2,358.5431,1460.112,0,709,1,1,40.85,1 +2,358.5431,1460.112,0,748,1,1,40.85,1 +2,358.5431,1460.112,1,758,0,0,40.85,1 +2,358.5431,1460.112,0,812,1,1,40.85,1 +2,358.5431,1460.112,0,788,1,1,40.85,1 +2,358.5431,1460.112,0,913,0,0,40.85,1 +2,358.5431,1460.112,1,955,0,0,40.85,1 +2,358.5431,1460.112,1,951,1,1,40.85,1 +2,358.5431,1460.112,0,976,1,1,40.85,1 +2,358.5431,1460.112,1,1052,1,1,40.85,1 +2,358.5431,1460.112,0,1083,1,1,40.85,1 +2,358.5431,1460.112,0,1111,0,0,40.85,1 +2,358.5431,1460.112,1,1121,1,0,40.85,1 +2,358.5431,1460.112,0,1131,1,1,40.85,1 +2,358.5431,1460.112,1,1138,1,1,40.85,1 +2,358.5431,1460.112,1,1122,1,1,40.85,1 +2,358.5431,1460.112,0,1176,1,1,40.85,1 +2,358.5431,1460.112,0,1176,1,1,40.85,1 +2,358.5431,1460.112,1,1176,1,1,40.85,1 +2,358.5431,1460.112,0,1201,1,1,40.85,1 +2,358.5431,1460.112,0,1200,1,1,40.85,1 +2,358.5431,1460.112,1,1199,0,0,40.85,1 +2,358.5431,1460.112,0,1281,1,1,40.85,1 +2,358.5431,1460.112,1,1285,0,0,40.85,1 +2,358.5431,1460.112,0,1332,1,1,40.85,1 +2,358.5431,1460.112,0,1320,1,1,40.85,1 +2,358.5431,1460.112,1,1319,1,0,40.85,1 +2,358.5431,1460.112,0,1407,1,0,40.85,1 +2,358.5431,1460.112,0,1443,1,1,40.85,1 +2,358.5431,1460.112,0,1441,1,1,40.85,1 +2,358.5431,1460.112,0,1458,1,1,40.85,1 +2,358.5431,1460.112,1,1459,1,1,40.85,1 +2,358.5431,1460.112,1,1472,1,1,40.85,1 +2,358.5431,1460.112,0,1505,0,0,40.85,1 +2,358.5431,1460.112,0,1504,0,0,40.85,1 +2,358.5431,1460.112,0,1503,1,1,40.85,1 +2,358.5431,1460.112,1,1505,1,1,40.85,1 +2,358.5431,1460.112,1,1618,0,0,40.85,1 +2,358.5431,1460.112,0,1652,0,0,40.85,1 +2,358.5431,1460.112,0,1667,1,1,40.85,1 +2,358.5431,1460.112,0,1698,0,0,40.85,1 +2,358.5431,1460.112,0,1680,0,0,40.85,1 +2,358.5431,1460.112,0,1699,1,1,40.85,1 +2,358.5431,1460.112,1,1687,1,1,40.85,1 +2,358.5431,1460.112,0,1711,1,1,40.85,1 +2,358.5431,1460.112,1,1758,0,0,40.85,1 +2,358.5431,1460.112,0,1838,1,0,40.85,1 +3,360.30809999999997,1460.026,0,403,1,0,40.1,0 +3,360.30809999999997,1460.026,0,395,1,0,40.1,0 +3,360.30809999999997,1460.026,1,394,1,0,40.1,0 +3,360.30809999999997,1460.026,1,704,1,0,40.1,0 +3,360.30809999999997,1460.026,0,782,1,0,40.1,0 +3,360.30809999999997,1460.026,1,841,1,0,40.1,0 +3,360.30809999999997,1460.026,0,912,1,0,40.1,0 +3,360.30809999999997,1460.026,0,910,1,0,40.1,0 +3,360.30809999999997,1460.026,1,998,1,0,40.1,0 +3,360.30809999999997,1460.026,0,1045,1,0,40.1,0 +3,360.30809999999997,1460.026,0,1091,1,0,40.1,0 +3,360.30809999999997,1460.026,0,1110,1,0,40.1,0 +3,360.30809999999997,1460.026,1,1315,1,0,40.1,0 +3,360.30809999999997,1460.026,0,1450,1,0,40.1,0 +3,360.30809999999997,1460.026,0,1436,1,0,40.1,0 +3,360.30809999999997,1460.026,1,1467,1,0,40.1,0 +3,360.30809999999997,1460.026,1,1521,1,0,40.1,0 +4,363.7957,1496.919,0,413,0,0,40.85,0 +4,363.7957,1496.919,0,473,0,0,40.85,0 +4,363.7957,1496.919,1,468,0,0,40.85,0 +4,363.7957,1496.919,0,591,0,0,40.85,0 +4,363.7957,1496.919,0,685,0,0,40.85,0 +4,363.7957,1496.919,0,765,0,0,40.85,0 +4,363.7957,1496.919,0,860,1,0,40.85,0 +4,363.7957,1496.919,1,960,0,0,40.85,0 +4,363.7957,1496.919,0,1010,0,0,40.85,0 +4,363.7957,1496.919,1,1116,1,0,40.85,0 +4,363.7957,1496.919,0,1146,0,0,40.85,0 +4,363.7957,1496.919,0,1206,1,0,40.85,0 +4,363.7957,1496.919,0,1247,0,0,40.85,0 +4,363.7957,1496.919,0,1248,0,0,40.85,0 +4,363.7957,1496.919,1,1264,0,0,40.85,0 +4,363.7957,1496.919,0,1303,0,0,40.85,0 +4,363.7957,1496.919,0,1333,0,0,40.85,0 +4,363.7957,1496.919,0,1372,0,0,40.85,0 +4,363.7957,1496.919,1,1475,0,0,40.85,0 +4,363.7957,1496.919,0,1496,0,0,40.85,0 +4,363.7957,1496.919,1,1598,0,0,40.85,0 +4,363.7957,1496.919,1,1597,0,0,40.85,0 +4,363.7957,1496.919,1,1659,0,0,40.85,0 +4,363.7957,1496.919,0,1794,1,0,40.85,0 +5,366.4005,1460.248,1,1839,1,0,40.85,0 +5,366.4005,1460.248,0,416,1,0,40.85,0 +5,366.4005,1460.248,0,450,1,0,40.85,0 +5,366.4005,1460.248,1,450,1,0,40.85,0 +5,366.4005,1460.248,0,489,1,0,40.85,0 +5,366.4005,1460.248,0,488,1,0,40.85,0 +5,366.4005,1460.248,0,594,1,0,40.85,0 +5,366.4005,1460.248,0,617,1,0,40.85,0 +5,366.4005,1460.248,0,656,1,0,40.85,0 +5,366.4005,1460.248,1,703,1,0,40.85,0 +5,366.4005,1460.248,1,865,1,0,40.85,0 +5,366.4005,1460.248,0,920,1,0,40.85,0 +5,366.4005,1460.248,0,971,1,0,40.85,0 +5,366.4005,1460.248,0,959,1,0,40.85,0 +5,366.4005,1460.248,0,1016,1,0,40.85,0 +5,366.4005,1460.248,1,1056,1,0,40.85,0 +5,366.4005,1460.248,1,1064,1,0,40.85,0 +5,366.4005,1460.248,0,1138,1,0,40.85,0 +5,366.4005,1460.248,0,1321,1,0,40.85,0 +5,366.4005,1460.248,1,1316,1,0,40.85,0 +5,366.4005,1460.248,0,1537,1,0,40.85,0 +5,366.4005,1460.248,0,1535,1,0,40.85,0 +5,366.4005,1460.248,1,1570,1,0,40.85,0 +5,366.4005,1460.248,1,1603,1,0,40.85,0 +5,366.4005,1460.248,1,1642,1,0,40.85,0 +5,366.4005,1460.248,0,1839,1,0,40.85,0 +6,366.6875,1463.002,0,539,1,0,40.85,0 +6,366.6875,1463.002,0,535,1,0,40.85,0 +6,366.6875,1463.002,1,570,0,0,40.85,0 +6,366.6875,1463.002,0,874,1,0,40.85,0 +6,366.6875,1463.002,1,875,1,0,40.85,0 +6,366.6875,1463.002,0,960,0,0,40.85,0 +6,366.6875,1463.002,0,945,1,0,40.85,0 +6,366.6875,1463.002,0,993,1,0,40.85,0 +6,366.6875,1463.002,0,1240,0,0,40.85,0 +6,366.6875,1463.002,1,1320,1,0,40.85,0 +6,366.6875,1463.002,1,1313,1,0,40.85,0 +6,366.6875,1463.002,1,1312,1,0,40.85,0 +6,366.6875,1463.002,0,1360,0,0,40.85,0 +6,366.6875,1463.002,0,1337,0,0,40.85,0 +6,366.6875,1463.002,0,1376,1,0,40.85,0 +6,366.6875,1463.002,1,1368,0,0,40.85,0 +6,366.6875,1463.002,0,1427,0,0,40.85,0 +6,366.6875,1463.002,1,1710,1,0,40.85,0 +7,368.4205,1460.569,1,1832,1,0,40.85,0 +7,368.4205,1460.569,1,1815,1,0,40.85,0 +7,368.4205,1460.569,1,1781,1,0,40.85,0 +7,368.4205,1460.569,1,380,1,0,40.85,0 +7,368.4205,1460.569,1,396,1,0,40.85,0 +7,368.4205,1460.569,0,452,1,0,40.85,0 +7,368.4205,1460.569,0,433,1,0,40.85,0 +7,368.4205,1460.569,1,426,1,0,40.85,0 +7,368.4205,1460.569,1,560,1,0,40.85,0 +7,368.4205,1460.569,0,589,1,0,40.85,0 +7,368.4205,1460.569,1,596,1,0,40.85,0 +7,368.4205,1460.569,1,591,1,0,40.85,0 +7,368.4205,1460.569,1,614,1,0,40.85,0 +7,368.4205,1460.569,0,729,1,0,40.85,0 +7,368.4205,1460.569,0,726,1,0,40.85,0 +7,368.4205,1460.569,1,739,1,0,40.85,0 +7,368.4205,1460.569,1,738,1,0,40.85,0 +7,368.4205,1460.569,0,771,1,0,40.85,0 +7,368.4205,1460.569,1,774,1,0,40.85,0 +7,368.4205,1460.569,1,790,1,0,40.85,0 +7,368.4205,1460.569,0,843,1,0,40.85,0 +7,368.4205,1460.569,0,908,1,0,40.85,0 +7,368.4205,1460.569,1,903,1,0,40.85,0 +7,368.4205,1460.569,1,933,1,0,40.85,0 +7,368.4205,1460.569,0,957,1,0,40.85,0 +7,368.4205,1460.569,1,1033,1,0,40.85,0 +7,368.4205,1460.569,0,1088,1,0,40.85,0 +7,368.4205,1460.569,1,1146,1,0,40.85,0 +7,368.4205,1460.569,0,1319,0,0,40.85,0 +7,368.4205,1460.569,1,1315,1,0,40.85,0 +7,368.4205,1460.569,1,1344,1,0,40.85,0 +7,368.4205,1460.569,1,1399,1,0,40.85,0 +7,368.4205,1460.569,1,1445,1,0,40.85,0 +7,368.4205,1460.569,1,1441,1,0,40.85,0 +7,368.4205,1460.569,1,1520,1,0,40.85,0 +7,368.4205,1460.569,0,1550,1,0,40.85,0 +7,368.4205,1460.569,0,1745,1,0,40.85,0 +7,368.4205,1460.569,0,1799,1,0,40.85,0 +8,370.3995,1460.301,0,382,0,0,40.85,1 +8,370.3995,1460.301,0,380,1,0,40.85,1 +8,370.3995,1460.301,0,394,1,0,40.85,1 +8,370.3995,1460.301,0,458,1,0,40.85,1 +8,370.3995,1460.301,0,536,0,0,40.85,1 +8,370.3995,1460.301,0,541,1,0,40.85,1 +8,370.3995,1460.301,0,540,1,0,40.85,1 +8,370.3995,1460.301,0,537,1,0,40.85,1 +8,370.3995,1460.301,0,548,1,0,40.85,1 +8,370.3995,1460.301,0,597,1,0,40.85,1 +8,370.3995,1460.301,0,626,1,0,40.85,1 +8,370.3995,1460.301,1,650,1,0,40.85,1 +8,370.3995,1460.301,0,688,1,0,40.85,1 +8,370.3995,1460.301,0,725,0,0,40.85,1 +8,370.3995,1460.301,0,743,1,0,40.85,1 +8,370.3995,1460.301,0,780,1,0,40.85,1 +8,370.3995,1460.301,0,807,1,0,40.85,1 +8,370.3995,1460.301,0,804,1,0,40.85,1 +8,370.3995,1460.301,1,807,1,0,40.85,1 +8,370.3995,1460.301,0,841,0,0,40.85,1 +8,370.3995,1460.301,0,959,1,0,40.85,1 +8,370.3995,1460.301,0,991,1,0,40.85,1 +8,370.3995,1460.301,0,1083,1,0,40.85,1 +8,370.3995,1460.301,0,1069,1,0,40.85,1 +8,370.3995,1460.301,0,1112,1,0,40.85,1 +8,370.3995,1460.301,0,1109,1,0,40.85,1 +8,370.3995,1460.301,1,1109,1,0,40.85,1 +8,370.3995,1460.301,0,1154,1,0,40.85,1 +8,370.3995,1460.301,1,1169,1,0,40.85,1 +8,370.3995,1460.301,0,1192,1,0,40.85,1 +8,370.3995,1460.301,0,1227,1,0,40.85,1 +8,370.3995,1460.301,0,1270,0,0,40.85,1 +8,370.3995,1460.301,0,1273,1,0,40.85,1 +8,370.3995,1460.301,0,1322,1,0,40.85,1 +8,370.3995,1460.301,0,1307,1,0,40.85,1 +8,370.3995,1460.301,1,1322,1,0,40.85,1 +8,370.3995,1460.301,0,1350,1,0,40.85,1 +8,370.3995,1460.301,0,1389,1,0,40.85,1 +8,370.3995,1460.301,0,1454,1,0,40.85,1 +8,370.3995,1460.301,0,1486,0,0,40.85,1 +8,370.3995,1460.301,0,1486,1,0,40.85,1 +8,370.3995,1460.301,0,1503,1,0,40.85,1 +8,370.3995,1460.301,0,1499,1,0,40.85,1 +8,370.3995,1460.301,1,1496,1,0,40.85,1 +8,370.3995,1460.301,0,1605,1,0,40.85,1 +8,370.3995,1460.301,0,1604,1,0,40.85,1 +8,370.3995,1460.301,0,1668,1,0,40.85,1 +8,370.3995,1460.301,0,1653,1,0,40.85,1 +8,370.3995,1460.301,0,1695,1,0,40.85,1 +8,370.3995,1460.301,0,1695,1,0,40.85,1 +8,370.3995,1460.301,1,1680,1,0,40.85,1 +8,370.3995,1460.301,0,1760,1,0,40.85,1 +8,370.3995,1460.301,0,1741,1,0,40.85,1 +8,370.3995,1460.301,0,1737,1,0,40.85,1 +8,370.3995,1460.301,0,1786,1,0,40.85,1 +8,370.3995,1460.301,0,1820,1,0,40.85,1 +9,370.6277,1499.589,0,387,0,0,40.85,0 +9,370.6277,1499.589,0,416,0,0,40.85,0 +9,370.6277,1499.589,0,430,0,0,40.85,0 +9,370.6277,1499.589,0,481,0,0,40.85,0 +9,370.6277,1499.589,0,495,0,0,40.85,0 +9,370.6277,1499.589,0,495,0,0,40.85,0 +9,370.6277,1499.589,0,490,0,0,40.85,0 +9,370.6277,1499.589,0,535,0,0,40.85,0 +9,370.6277,1499.589,0,535,0,0,40.85,0 +9,370.6277,1499.589,1,535,0,0,40.85,0 +9,370.6277,1499.589,0,562,0,0,40.85,0 +9,370.6277,1499.589,0,591,0,0,40.85,0 +9,370.6277,1499.589,0,618,0,0,40.85,0 +9,370.6277,1499.589,0,616,0,0,40.85,0 +9,370.6277,1499.589,0,659,0,0,40.85,0 +9,370.6277,1499.589,1,656,0,0,40.85,0 +9,370.6277,1499.589,0,687,0,0,40.85,0 +9,370.6277,1499.589,0,675,0,0,40.85,0 +9,370.6277,1499.589,0,702,0,0,40.85,0 +9,370.6277,1499.589,0,760,0,0,40.85,0 +9,370.6277,1499.589,0,742,0,0,40.85,0 +9,370.6277,1499.589,0,737,0,0,40.85,0 +9,370.6277,1499.589,0,789,0,0,40.85,0 +9,370.6277,1499.589,0,768,0,0,40.85,0 +9,370.6277,1499.589,0,763,0,0,40.85,0 +9,370.6277,1499.589,0,810,0,0,40.85,0 +9,370.6277,1499.589,0,825,0,0,40.85,0 +9,370.6277,1499.589,0,920,0,0,40.85,0 +9,370.6277,1499.589,0,919,0,0,40.85,0 +9,370.6277,1499.589,0,919,0,0,40.85,0 +9,370.6277,1499.589,1,961,0,0,40.85,0 +9,370.6277,1499.589,0,987,0,0,40.85,0 +9,370.6277,1499.589,0,1087,0,0,40.85,0 +9,370.6277,1499.589,0,1081,0,0,40.85,0 +9,370.6277,1499.589,0,1119,0,0,40.85,0 +9,370.6277,1499.589,0,1151,0,0,40.85,0 +9,370.6277,1499.589,0,1139,0,0,40.85,0 +9,370.6277,1499.589,0,1182,0,0,40.85,0 +9,370.6277,1499.589,0,1295,0,0,40.85,0 +9,370.6277,1499.589,1,1302,0,0,40.85,0 +9,370.6277,1499.589,0,1338,0,0,40.85,0 +9,370.6277,1499.589,0,1330,0,0,40.85,0 +9,370.6277,1499.589,0,1328,0,0,40.85,0 +9,370.6277,1499.589,0,1326,0,0,40.85,0 +9,370.6277,1499.589,0,1434,0,0,40.85,0 +9,370.6277,1499.589,1,1442,0,0,40.85,0 +9,370.6277,1499.589,0,1482,0,0,40.85,0 +9,370.6277,1499.589,0,1479,0,0,40.85,0 +9,370.6277,1499.589,0,1468,0,0,40.85,0 +9,370.6277,1499.589,0,1464,0,0,40.85,0 +9,370.6277,1499.589,0,1605,0,0,40.85,0 +9,370.6277,1499.589,0,1599,0,0,40.85,0 +9,370.6277,1499.589,0,1622,0,0,40.85,0 +9,370.6277,1499.589,0,1660,0,0,40.85,0 +9,370.6277,1499.589,0,1651,0,0,40.85,0 +9,370.6277,1499.589,0,1677,0,0,40.85,0 +9,370.6277,1499.589,1,1690,0,0,40.85,0 +10,374.40259999999995,1501.392,1,1808,0,0,40.85,1 +10,374.40259999999995,1501.392,0,384,0,0,40.85,1 +10,374.40259999999995,1501.392,0,417,0,0,40.85,1 +10,374.40259999999995,1501.392,0,414,0,0,40.85,1 +10,374.40259999999995,1501.392,1,441,0,0,40.85,1 +10,374.40259999999995,1501.392,0,590,0,0,40.85,1 +10,374.40259999999995,1501.392,1,599,0,0,40.85,1 +10,374.40259999999995,1501.392,0,618,0,0,40.85,1 +10,374.40259999999995,1501.392,0,661,0,0,40.85,1 +10,374.40259999999995,1501.392,0,721,0,0,40.85,1 +10,374.40259999999995,1501.392,1,747,0,0,40.85,1 +10,374.40259999999995,1501.392,0,772,0,0,40.85,1 +10,374.40259999999995,1501.392,0,815,0,0,40.85,1 +10,374.40259999999995,1501.392,1,810,1,0,40.85,1 +10,374.40259999999995,1501.392,0,923,0,0,40.85,1 +10,374.40259999999995,1501.392,1,935,0,0,40.85,1 +10,374.40259999999995,1501.392,1,1270,0,0,40.85,1 +10,374.40259999999995,1501.392,0,1330,0,0,40.85,1 +10,374.40259999999995,1501.392,0,1322,0,0,40.85,1 +10,374.40259999999995,1501.392,1,1376,0,0,40.85,1 +10,374.40259999999995,1501.392,0,1599,0,0,40.85,1 +10,374.40259999999995,1501.392,0,1630,0,0,40.85,1 +10,374.40259999999995,1501.392,0,1621,0,0,40.85,1 +10,374.40259999999995,1501.392,0,1692,0,0,40.85,1 +10,374.40259999999995,1501.392,0,1793,0,0,40.85,1 +10,374.40259999999995,1501.392,0,1813,0,0,40.85,1 +11,377.0243,1495.994,0,385,1,1,33.65,1 +11,377.0243,1495.994,0,373,1,1,33.65,1 +11,377.0243,1495.994,0,425,1,1,33.65,1 +11,377.0243,1495.994,0,409,1,1,33.65,1 +11,377.0243,1495.994,0,486,1,1,33.65,1 +11,377.0243,1495.994,0,531,1,1,33.65,1 +11,377.0243,1495.994,0,524,1,1,33.65,1 +11,377.0243,1495.994,0,565,1,1,33.65,1 +11,377.0243,1495.994,0,631,1,1,33.65,1 +11,377.0243,1495.994,0,613,1,1,33.65,1 +11,377.0243,1495.994,0,683,1,1,33.65,1 +11,377.0243,1495.994,0,751,1,1,33.65,1 +11,377.0243,1495.994,0,800,1,1,33.65,1 +11,377.0243,1495.994,0,1109,1,1,33.65,1 +11,377.0243,1495.994,1,1157,1,1,33.65,1 +11,377.0243,1495.994,1,1308,1,1,33.65,1 +11,377.0243,1495.994,0,1322,1,1,33.65,1 +11,377.0243,1495.994,1,1315,1,1,33.65,1 +11,377.0243,1495.994,1,1366,1,1,33.65,1 +11,377.0243,1495.994,1,1343,1,1,33.65,1 +11,377.0243,1495.994,0,1454,1,1,33.65,1 +11,377.0243,1495.994,0,1476,1,1,33.65,1 +11,377.0243,1495.994,0,1501,1,1,33.65,1 +11,377.0243,1495.994,1,1551,1,1,33.65,1 +11,377.0243,1495.994,0,1622,1,1,33.65,1 +11,377.0243,1495.994,0,1646,1,1,33.65,1 +11,377.0243,1495.994,0,1702,1,1,33.65,1 +11,377.0243,1495.994,0,1741,1,1,33.65,1 +11,377.0243,1495.994,0,1778,1,1,33.65,1 +11,377.0243,1495.994,0,1856,1,1,33.65,1 +11,377.0243,1495.994,0,1846,1,1,33.65,1 +12,378.2183,1459.478,1,1803,1,1,40.1,1 +12,378.2183,1459.478,1,385,1,1,40.1,1 +12,378.2183,1459.478,0,441,1,1,40.1,1 +12,378.2183,1459.478,0,435,1,1,40.1,1 +12,378.2183,1459.478,0,507,1,1,40.1,1 +12,378.2183,1459.478,0,523,1,0,40.1,1 +12,378.2183,1459.478,0,527,1,1,40.1,1 +12,378.2183,1459.478,1,519,1,1,40.1,1 +12,378.2183,1459.478,0,562,1,1,40.1,1 +12,378.2183,1459.478,0,624,1,1,40.1,1 +12,378.2183,1459.478,0,685,1,1,40.1,1 +12,378.2183,1459.478,0,713,1,0,40.1,1 +12,378.2183,1459.478,1,714,1,1,40.1,1 +12,378.2183,1459.478,1,811,1,1,40.1,1 +12,378.2183,1459.478,0,995,1,1,40.1,1 +12,378.2183,1459.478,1,986,1,1,40.1,1 +12,378.2183,1459.478,0,1003,1,1,40.1,1 +12,378.2183,1459.478,1,1062,1,0,40.1,1 +12,378.2183,1459.478,0,1114,1,1,40.1,1 +12,378.2183,1459.478,0,1136,1,1,40.1,1 +12,378.2183,1459.478,1,1141,1,1,40.1,1 +12,378.2183,1459.478,0,1162,1,1,40.1,1 +12,378.2183,1459.478,1,1375,1,1,40.1,1 +12,378.2183,1459.478,0,1439,1,1,40.1,1 +12,378.2183,1459.478,1,1449,1,1,40.1,1 +12,378.2183,1459.478,0,1470,1,1,40.1,1 +12,378.2183,1459.478,0,1537,1,0,40.1,1 +12,378.2183,1459.478,0,1559,1,1,40.1,1 +12,378.2183,1459.478,1,1596,1,1,40.1,1 +12,378.2183,1459.478,1,1630,1,1,40.1,1 +12,378.2183,1459.478,0,1652,1,1,40.1,1 +12,378.2183,1459.478,0,1754,1,1,40.1,1 +13,379.0978,1500.023,1,1851,1,1,28.85,1 +13,379.0978,1500.023,1,375,1,0,28.85,1 +13,379.0978,1500.023,1,388,1,1,28.85,1 +13,379.0978,1500.023,0,422,1,1,28.85,1 +13,379.0978,1500.023,0,606,1,1,28.85,1 +13,379.0978,1500.023,0,635,1,1,28.85,1 +13,379.0978,1500.023,0,657,1,0,28.85,1 +13,379.0978,1500.023,0,683,1,1,28.85,1 +13,379.0978,1500.023,1,688,0,0,28.85,1 +13,379.0978,1500.023,1,689,1,1,28.85,1 +13,379.0978,1500.023,0,726,1,1,28.85,1 +13,379.0978,1500.023,1,715,1,1,28.85,1 +13,379.0978,1500.023,1,929,1,1,28.85,1 +13,379.0978,1500.023,1,924,1,1,28.85,1 +13,379.0978,1500.023,0,968,1,0,28.85,1 +13,379.0978,1500.023,0,1033,1,1,28.85,1 +13,379.0978,1500.023,0,1093,1,1,28.85,1 +13,379.0978,1500.023,0,1092,1,1,28.85,1 +13,379.0978,1500.023,0,1157,1,1,28.85,1 +13,379.0978,1500.023,1,1172,1,1,28.85,1 +13,379.0978,1500.023,1,1233,0,0,28.85,1 +13,379.0978,1500.023,0,1260,1,1,28.85,1 +13,379.0978,1500.023,1,1272,1,1,28.85,1 +13,379.0978,1500.023,0,1313,1,1,28.85,1 +13,379.0978,1500.023,1,1445,1,1,28.85,1 +13,379.0978,1500.023,0,1478,1,0,28.85,1 +13,379.0978,1500.023,0,1489,1,1,28.85,1 +13,379.0978,1500.023,0,1525,1,1,28.85,1 +13,379.0978,1500.023,0,1709,1,1,28.85,1 +13,379.0978,1500.023,1,1756,1,1,28.85,1 +13,379.0978,1500.023,1,1750,1,1,28.85,1 +13,379.0978,1500.023,0,1811,1,1,28.85,1 +14,379.752,1459.654,1,1818,1,0,40.1,0 +14,379.752,1459.654,0,461,1,0,40.1,0 +14,379.752,1459.654,0,513,1,0,40.1,0 +14,379.752,1459.654,0,497,1,0,40.1,0 +14,379.752,1459.654,0,712,1,0,40.1,0 +14,379.752,1459.654,0,761,1,0,40.1,0 +14,379.752,1459.654,1,825,1,0,40.1,0 +14,379.752,1459.654,1,866,1,0,40.1,0 +14,379.752,1459.654,0,921,1,0,40.1,0 +14,379.752,1459.654,0,974,1,0,40.1,0 +14,379.752,1459.654,0,1097,1,0,40.1,0 +14,379.752,1459.654,1,1127,1,0,40.1,0 +14,379.752,1459.654,0,1170,1,0,40.1,0 +14,379.752,1459.654,0,1328,1,0,40.1,0 +14,379.752,1459.654,0,1353,1,0,40.1,0 +14,379.752,1459.654,0,1338,1,0,40.1,0 +14,379.752,1459.654,0,1382,1,0,40.1,0 +14,379.752,1459.654,0,1610,1,0,40.1,0 +14,379.752,1459.654,0,1596,1,0,40.1,0 +14,379.752,1459.654,1,1750,1,0,40.1,0 +15,381.7725,1491.676,0,374,1,0,33.65,1 +15,381.7725,1491.676,1,381,1,0,33.65,1 +15,381.7725,1491.676,0,412,1,0,33.65,1 +15,381.7725,1491.676,0,411,1,0,33.65,1 +15,381.7725,1491.676,0,441,1,0,33.65,1 +15,381.7725,1491.676,0,439,1,0,33.65,1 +15,381.7725,1491.676,0,433,1,0,33.65,1 +15,381.7725,1491.676,0,429,1,0,33.65,1 +15,381.7725,1491.676,0,503,1,0,33.65,1 +15,381.7725,1491.676,0,503,1,0,33.65,1 +15,381.7725,1491.676,0,534,1,0,33.65,1 +15,381.7725,1491.676,0,526,1,0,33.65,1 +15,381.7725,1491.676,0,603,1,0,33.65,1 +15,381.7725,1491.676,0,595,1,0,33.65,1 +15,381.7725,1491.676,1,601,1,0,33.65,1 +15,381.7725,1491.676,0,630,1,0,33.65,1 +15,381.7725,1491.676,0,665,1,0,33.65,1 +15,381.7725,1491.676,0,641,1,0,33.65,1 +15,381.7725,1491.676,0,673,1,0,33.65,1 +15,381.7725,1491.676,0,715,1,0,33.65,1 +15,381.7725,1491.676,0,705,1,0,33.65,1 +15,381.7725,1491.676,0,746,1,0,33.65,1 +15,381.7725,1491.676,0,738,1,0,33.65,1 +15,381.7725,1491.676,0,841,1,0,33.65,1 +15,381.7725,1491.676,0,908,1,0,33.65,1 +15,381.7725,1491.676,0,1004,1,0,33.65,1 +15,381.7725,1491.676,0,1059,1,0,33.65,1 +15,381.7725,1491.676,0,1080,1,0,33.65,1 +15,381.7725,1491.676,0,1080,1,0,33.65,1 +15,381.7725,1491.676,0,1080,1,0,33.65,1 +15,381.7725,1491.676,0,1123,1,0,33.65,1 +15,381.7725,1491.676,0,1212,1,0,33.65,1 +15,381.7725,1491.676,0,1233,1,0,33.65,1 +15,381.7725,1491.676,0,1233,1,0,33.65,1 +15,381.7725,1491.676,0,1233,1,0,33.65,1 +15,381.7725,1491.676,0,1233,1,0,33.65,1 +15,381.7725,1491.676,0,1276,1,0,33.65,1 +15,381.7725,1491.676,0,1264,1,0,33.65,1 +15,381.7725,1491.676,0,1259,1,0,33.65,1 +15,381.7725,1491.676,0,1300,1,0,33.65,1 +15,381.7725,1491.676,0,1294,1,0,33.65,1 +15,381.7725,1491.676,0,1325,1,0,33.65,1 +15,381.7725,1491.676,0,1376,1,0,33.65,1 +15,381.7725,1491.676,0,1413,1,0,33.65,1 +15,381.7725,1491.676,1,1426,1,0,33.65,1 +15,381.7725,1491.676,0,1506,1,0,33.65,1 +15,381.7725,1491.676,0,1504,1,0,33.65,1 +15,381.7725,1491.676,0,1534,1,0,33.65,1 +15,381.7725,1491.676,1,1598,1,0,33.65,1 +15,381.7725,1491.676,0,1659,1,0,33.65,1 +15,381.7725,1491.676,0,1688,1,0,33.65,1 +15,381.7725,1491.676,1,1750,1,0,33.65,1 +15,381.7725,1491.676,0,1793,1,0,33.65,1 +16,382.2359,1463.017,0,441,0,0,40.85,1 +16,382.2359,1463.017,0,453,1,1,40.85,1 +16,382.2359,1463.017,0,435,1,1,40.85,1 +16,382.2359,1463.017,0,425,1,1,40.85,1 +16,382.2359,1463.017,0,539,1,1,40.85,1 +16,382.2359,1463.017,0,575,1,0,40.85,1 +16,382.2359,1463.017,0,568,1,0,40.85,1 +16,382.2359,1463.017,0,562,1,1,40.85,1 +16,382.2359,1463.017,0,593,1,1,40.85,1 +16,382.2359,1463.017,0,582,1,1,40.85,1 +16,382.2359,1463.017,1,611,1,1,40.85,1 +16,382.2359,1463.017,0,646,0,0,40.85,1 +16,382.2359,1463.017,0,666,1,1,40.85,1 +16,382.2359,1463.017,0,665,1,1,40.85,1 +16,382.2359,1463.017,1,901,1,1,40.85,1 +16,382.2359,1463.017,0,969,0,0,40.85,1 +16,382.2359,1463.017,0,994,1,1,40.85,1 +16,382.2359,1463.017,0,975,1,1,40.85,1 +16,382.2359,1463.017,0,1231,1,1,40.85,1 +16,382.2359,1463.017,0,1231,1,1,40.85,1 +16,382.2359,1463.017,1,1280,0,0,40.85,1 +16,382.2359,1463.017,0,1327,1,0,40.85,1 +16,382.2359,1463.017,0,1376,0,0,40.85,1 +16,382.2359,1463.017,0,1404,1,0,40.85,1 +16,382.2359,1463.017,0,1443,0,0,40.85,1 +16,382.2359,1463.017,0,1457,1,1,40.85,1 +16,382.2359,1463.017,1,1477,1,1,40.85,1 +16,382.2359,1463.017,0,1546,1,1,40.85,1 +16,382.2359,1463.017,0,1715,0,0,40.85,1 +17,383.1619,1500.986,0,380,1,1,40.85,1 +17,383.1619,1500.986,0,374,1,1,40.85,1 +17,383.1619,1500.986,1,503,1,1,40.85,1 +17,383.1619,1500.986,0,521,1,1,40.85,1 +17,383.1619,1500.986,1,524,1,1,40.85,1 +17,383.1619,1500.986,0,578,1,1,40.85,1 +17,383.1619,1500.986,1,631,1,1,40.85,1 +17,383.1619,1500.986,0,776,1,1,40.85,1 +17,383.1619,1500.986,0,772,1,1,40.85,1 +17,383.1619,1500.986,0,899,1,1,40.85,1 +17,383.1619,1500.986,1,906,1,1,40.85,1 +17,383.1619,1500.986,0,922,1,1,40.85,1 +17,383.1619,1500.986,1,968,1,1,40.85,1 +17,383.1619,1500.986,0,1000,1,0,40.85,1 +17,383.1619,1500.986,0,999,1,1,40.85,1 +17,383.1619,1500.986,1,1022,1,1,40.85,1 +17,383.1619,1500.986,0,1077,1,1,40.85,1 +17,383.1619,1500.986,0,1070,1,1,40.85,1 +17,383.1619,1500.986,0,1140,1,1,40.85,1 +17,383.1619,1500.986,1,1233,1,1,40.85,1 +17,383.1619,1500.986,1,1264,1,1,40.85,1 +17,383.1619,1500.986,0,1341,1,1,40.85,1 +17,383.1619,1500.986,0,1381,1,1,40.85,1 +17,383.1619,1500.986,0,1429,1,1,40.85,1 +17,383.1619,1500.986,0,1457,1,1,40.85,1 +17,383.1619,1500.986,0,1520,1,1,40.85,1 +17,383.1619,1500.986,0,1534,1,1,40.85,1 +17,383.1619,1500.986,0,1599,1,1,40.85,1 +17,383.1619,1500.986,0,1671,1,1,40.85,1 +17,383.1619,1500.986,0,1773,1,1,40.85,1 +18,386.8494,1501.264,1,1849,0,0,40.85,1 +18,386.8494,1501.264,1,1823,0,0,40.85,1 +18,386.8494,1501.264,0,437,0,0,40.85,1 +18,386.8494,1501.264,0,527,0,0,40.85,1 +18,386.8494,1501.264,0,576,0,0,40.85,1 +18,386.8494,1501.264,1,611,0,0,40.85,1 +18,386.8494,1501.264,1,655,1,0,40.85,1 +18,386.8494,1501.264,1,679,0,0,40.85,1 +18,386.8494,1501.264,0,805,0,0,40.85,1 +18,386.8494,1501.264,1,845,0,0,40.85,1 +18,386.8494,1501.264,1,979,0,0,40.85,1 +18,386.8494,1501.264,1,1181,0,0,40.85,1 +18,386.8494,1501.264,1,1236,0,0,40.85,1 +18,386.8494,1501.264,1,1233,0,0,40.85,1 +18,386.8494,1501.264,0,1292,0,0,40.85,1 +18,386.8494,1501.264,1,1374,0,0,40.85,1 +18,386.8494,1501.264,1,1661,0,0,40.85,1 +18,386.8494,1501.264,1,1657,0,0,40.85,1 +18,386.8494,1501.264,1,1652,0,0,40.85,1 +18,386.8494,1501.264,1,1698,0,0,40.85,1 +18,386.8494,1501.264,0,1855,0,0,40.85,1 +19,387.13640000000004,1462.602,0,373,1,0,40.85,1 +19,387.13640000000004,1462.602,1,391,1,0,40.85,1 +19,387.13640000000004,1462.602,0,435,1,0,40.85,1 +19,387.13640000000004,1462.602,0,536,0,0,40.85,1 +19,387.13640000000004,1462.602,0,596,1,0,40.85,1 +19,387.13640000000004,1462.602,0,585,1,0,40.85,1 +19,387.13640000000004,1462.602,1,585,1,0,40.85,1 +19,387.13640000000004,1462.602,0,655,1,0,40.85,1 +19,387.13640000000004,1462.602,0,729,1,0,40.85,1 +19,387.13640000000004,1462.602,0,754,1,0,40.85,1 +19,387.13640000000004,1462.602,0,774,1,0,40.85,1 +19,387.13640000000004,1462.602,0,832,1,0,40.85,1 +19,387.13640000000004,1462.602,0,910,1,0,40.85,1 +19,387.13640000000004,1462.602,0,903,1,0,40.85,1 +19,387.13640000000004,1462.602,0,1070,1,0,40.85,1 +19,387.13640000000004,1462.602,0,1116,1,0,40.85,1 +19,387.13640000000004,1462.602,1,1121,1,0,40.85,1 +19,387.13640000000004,1462.602,1,1170,1,0,40.85,1 +19,387.13640000000004,1462.602,0,1244,1,0,40.85,1 +19,387.13640000000004,1462.602,1,1248,1,0,40.85,1 +19,387.13640000000004,1462.602,0,1334,1,0,40.85,1 +19,387.13640000000004,1462.602,0,1385,1,0,40.85,1 +19,387.13640000000004,1462.602,0,1446,1,0,40.85,1 +19,387.13640000000004,1462.602,1,1459,0,0,40.85,1 +19,387.13640000000004,1462.602,0,1515,1,0,40.85,1 +19,387.13640000000004,1462.602,0,1636,1,0,40.85,1 +19,387.13640000000004,1462.602,0,1852,1,0,40.85,1 +19,387.13640000000004,1462.602,0,1825,1,0,40.85,1 +20,389.747,1466.306,0,391,1,0,40.85,0 +20,389.747,1466.306,0,388,1,0,40.85,0 +20,389.747,1466.306,0,366,1,0,40.85,0 +20,389.747,1466.306,0,461,1,0,40.85,0 +20,389.747,1466.306,1,568,1,0,40.85,0 +20,389.747,1466.306,1,559,1,0,40.85,0 +20,389.747,1466.306,0,598,1,0,40.85,0 +20,389.747,1466.306,0,698,1,0,40.85,0 +20,389.747,1466.306,0,746,1,0,40.85,0 +20,389.747,1466.306,0,874,1,0,40.85,0 +20,389.747,1466.306,1,929,1,0,40.85,0 +20,389.747,1466.306,1,927,1,0,40.85,0 +20,389.747,1466.306,1,918,1,0,40.85,0 +20,389.747,1466.306,0,1035,1,0,40.85,0 +20,389.747,1466.306,1,1059,1,0,40.85,0 +20,389.747,1466.306,1,1063,1,0,40.85,0 +20,389.747,1466.306,0,1103,1,0,40.85,0 +20,389.747,1466.306,1,1223,1,0,40.85,0 +20,389.747,1466.306,0,1270,1,0,40.85,0 +20,389.747,1466.306,0,1310,1,0,40.85,0 +20,389.747,1466.306,1,1334,1,0,40.85,0 +20,389.747,1466.306,0,1361,1,0,40.85,0 +20,389.747,1466.306,0,1349,1,0,40.85,0 +20,389.747,1466.306,0,1446,1,0,40.85,0 +20,389.747,1466.306,1,1523,1,0,40.85,0 +20,389.747,1466.306,0,1603,1,0,40.85,0 +20,389.747,1466.306,1,1599,1,0,40.85,0 +20,389.747,1466.306,1,1664,1,0,40.85,0 +20,389.747,1466.306,0,1715,1,0,40.85,0 +20,389.747,1466.306,0,1713,1,0,40.85,0 +21,390.4019,1463.426,1,1852,1,0,40.85,1 +21,390.4019,1463.426,1,1786,1,0,40.85,1 +21,390.4019,1463.426,0,404,1,0,40.85,1 +21,390.4019,1463.426,1,446,1,0,40.85,1 +21,390.4019,1463.426,1,537,0,0,40.85,1 +21,390.4019,1463.426,1,591,1,0,40.85,1 +21,390.4019,1463.426,0,611,1,0,40.85,1 +21,390.4019,1463.426,0,652,1,0,40.85,1 +21,390.4019,1463.426,0,684,1,0,40.85,1 +21,390.4019,1463.426,0,701,1,0,40.85,1 +21,390.4019,1463.426,1,807,1,0,40.85,1 +21,390.4019,1463.426,0,858,1,0,40.85,1 +21,390.4019,1463.426,1,857,1,0,40.85,1 +21,390.4019,1463.426,1,856,1,0,40.85,1 +21,390.4019,1463.426,0,895,1,0,40.85,1 +21,390.4019,1463.426,1,986,1,0,40.85,1 +21,390.4019,1463.426,0,1012,1,0,40.85,1 +21,390.4019,1463.426,1,1055,1,0,40.85,1 +21,390.4019,1463.426,0,1165,1,0,40.85,1 +21,390.4019,1463.426,0,1233,1,0,40.85,1 +21,390.4019,1463.426,0,1303,1,0,40.85,1 +21,390.4019,1463.426,0,1329,1,0,40.85,1 +21,390.4019,1463.426,1,1451,1,0,40.85,1 +21,390.4019,1463.426,1,1627,0,0,40.85,1 +21,390.4019,1463.426,1,1627,1,0,40.85,1 +21,390.4019,1463.426,1,1692,1,0,40.85,1 +21,390.4019,1463.426,1,1688,1,0,40.85,1 +21,390.4019,1463.426,0,1721,0,0,40.85,1 +21,390.4019,1463.426,0,1707,1,0,40.85,1 +21,390.4019,1463.426,0,1840,1,0,40.85,1 +22,391.9346,1499.785,0,382,0,0,40.85,0 +22,391.9346,1499.785,0,370,0,0,40.85,0 +22,391.9346,1499.785,0,423,1,0,40.85,0 +22,391.9346,1499.785,0,421,1,0,40.85,0 +22,391.9346,1499.785,1,395,0,0,40.85,0 +22,391.9346,1499.785,0,498,0,0,40.85,0 +22,391.9346,1499.785,0,496,1,0,40.85,0 +22,391.9346,1499.785,0,588,1,0,40.85,0 +22,391.9346,1499.785,0,684,0,0,40.85,0 +22,391.9346,1499.785,0,682,0,0,40.85,0 +22,391.9346,1499.785,0,780,1,0,40.85,0 +22,391.9346,1499.785,1,775,1,0,40.85,0 +22,391.9346,1499.785,0,824,0,0,40.85,0 +22,391.9346,1499.785,1,821,0,0,40.85,0 +22,391.9346,1499.785,0,890,0,0,40.85,0 +22,391.9346,1499.785,1,1019,1,0,40.85,0 +22,391.9346,1499.785,0,1043,1,0,40.85,0 +22,391.9346,1499.785,0,1078,1,0,40.85,0 +22,391.9346,1499.785,1,1222,0,0,40.85,0 +22,391.9346,1499.785,0,1251,1,0,40.85,0 +22,391.9346,1499.785,1,1293,0,0,40.85,0 +22,391.9346,1499.785,1,1331,1,0,40.85,0 +22,391.9346,1499.785,0,1421,0,0,40.85,0 +22,391.9346,1499.785,1,1514,0,0,40.85,0 +22,391.9346,1499.785,1,1610,0,0,40.85,0 +22,391.9346,1499.785,1,1689,0,0,40.85,0 +22,391.9346,1499.785,0,1704,1,0,40.85,0 +23,393.3475,1497.573,1,1794,0,0,40.85,1 +23,393.3475,1497.573,1,454,0,0,40.85,1 +23,393.3475,1497.573,0,541,1,0,40.85,1 +23,393.3475,1497.573,1,538,0,0,40.85,1 +23,393.3475,1497.573,0,563,0,0,40.85,1 +23,393.3475,1497.573,1,570,0,0,40.85,1 +23,393.3475,1497.573,0,634,0,0,40.85,1 +23,393.3475,1497.573,0,667,0,0,40.85,1 +23,393.3475,1497.573,0,748,0,0,40.85,1 +23,393.3475,1497.573,0,780,0,0,40.85,1 +23,393.3475,1497.573,0,803,0,0,40.85,1 +23,393.3475,1497.573,0,821,0,0,40.85,1 +23,393.3475,1497.573,1,919,0,0,40.85,1 +23,393.3475,1497.573,1,955,1,0,40.85,1 +23,393.3475,1497.573,0,991,1,0,40.85,1 +23,393.3475,1497.573,1,986,0,0,40.85,1 +23,393.3475,1497.573,1,983,0,0,40.85,1 +23,393.3475,1497.573,0,1063,1,0,40.85,1 +23,393.3475,1497.573,1,1110,0,0,40.85,1 +23,393.3475,1497.573,0,1179,1,0,40.85,1 +23,393.3475,1497.573,0,1322,0,0,40.85,1 +23,393.3475,1497.573,0,1459,0,0,40.85,1 +23,393.3475,1497.573,1,1501,0,0,40.85,1 +23,393.3475,1497.573,0,1567,0,0,40.85,1 +23,393.3475,1497.573,0,1555,0,0,40.85,1 +23,393.3475,1497.573,0,1622,0,0,40.85,1 +23,393.3475,1497.573,0,1670,0,0,40.85,1 +23,393.3475,1497.573,0,1693,0,0,40.85,1 +23,393.3475,1497.573,0,1762,0,0,40.85,1 +23,393.3475,1497.573,0,1784,0,0,40.85,1 +24,395.43359999999996,1490.858,0,504,1,1,47.65,1 +24,395.43359999999996,1490.858,0,535,1,1,47.65,1 +24,395.43359999999996,1490.858,0,606,1,1,47.65,1 +24,395.43359999999996,1490.858,0,603,1,1,47.65,1 +24,395.43359999999996,1490.858,0,594,1,1,47.65,1 +24,395.43359999999996,1490.858,0,645,1,1,47.65,1 +24,395.43359999999996,1490.858,0,756,1,1,47.65,1 +24,395.43359999999996,1490.858,0,735,1,1,47.65,1 +24,395.43359999999996,1490.858,0,776,1,1,47.65,1 +24,395.43359999999996,1490.858,0,820,1,1,47.65,1 +24,395.43359999999996,1490.858,0,966,1,1,47.65,1 +24,395.43359999999996,1490.858,0,959,1,1,47.65,1 +24,395.43359999999996,1490.858,0,987,1,1,47.65,1 +24,395.43359999999996,1490.858,0,987,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1049,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1049,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1080,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1079,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1066,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1154,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1127,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1127,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1173,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1232,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1220,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1263,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1324,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1352,1,1,47.65,1 +24,395.43359999999996,1490.858,1,1534,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1658,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1731,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1786,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1825,1,1,47.65,1 +24,395.43359999999996,1490.858,0,1841,1,1,47.65,1 +25,397.07640000000004,1501.881,0,385,0,0,40.85,0 +25,397.07640000000004,1501.881,0,436,0,0,40.85,0 +25,397.07640000000004,1501.881,1,506,0,0,40.85,0 +25,397.07640000000004,1501.881,0,573,0,0,40.85,0 +25,397.07640000000004,1501.881,1,563,0,0,40.85,0 +25,397.07640000000004,1501.881,1,581,0,0,40.85,0 +25,397.07640000000004,1501.881,0,640,0,0,40.85,0 +25,397.07640000000004,1501.881,0,781,0,0,40.85,0 +25,397.07640000000004,1501.881,1,936,0,0,40.85,0 +25,397.07640000000004,1501.881,1,964,0,0,40.85,0 +25,397.07640000000004,1501.881,1,1015,0,0,40.85,0 +25,397.07640000000004,1501.881,1,1081,0,0,40.85,0 +25,397.07640000000004,1501.881,0,1134,0,0,40.85,0 +25,397.07640000000004,1501.881,1,1141,0,0,40.85,0 +25,397.07640000000004,1501.881,1,1334,0,0,40.85,0 +25,397.07640000000004,1501.881,1,1446,0,0,40.85,0 +25,397.07640000000004,1501.881,1,1435,0,0,40.85,0 +25,397.07640000000004,1501.881,0,1505,0,0,40.85,0 +25,397.07640000000004,1501.881,1,1618,0,0,40.85,0 +25,397.07640000000004,1501.881,1,1683,0,0,40.85,0 +26,486.82809999999995,1502.976,0,404,1,0,44.1,1 +26,486.82809999999995,1502.976,0,443,1,0,44.1,1 +26,486.82809999999995,1502.976,0,498,1,0,44.1,1 +26,486.82809999999995,1502.976,0,580,1,0,44.1,1 +26,486.82809999999995,1502.976,0,589,1,0,44.1,1 +26,486.82809999999995,1502.976,0,626,1,0,44.1,1 +26,486.82809999999995,1502.976,0,657,1,0,44.1,1 +26,486.82809999999995,1502.976,0,673,1,0,44.1,1 +26,486.82809999999995,1502.976,0,754,1,0,44.1,1 +26,486.82809999999995,1502.976,0,739,1,0,44.1,1 +26,486.82809999999995,1502.976,0,766,1,0,44.1,1 +26,486.82809999999995,1502.976,1,853,1,0,44.1,1 +26,486.82809999999995,1502.976,0,858,1,0,44.1,1 +26,486.82809999999995,1502.976,1,969,1,0,44.1,1 +26,486.82809999999995,1502.976,1,961,1,0,44.1,1 +26,486.82809999999995,1502.976,1,1123,1,0,44.1,1 +26,486.82809999999995,1502.976,1,1144,1,0,44.1,1 +26,486.82809999999995,1502.976,0,1200,1,0,44.1,1 +26,486.82809999999995,1502.976,0,1248,1,0,44.1,1 +26,486.82809999999995,1502.976,0,1267,1,0,44.1,1 +26,486.82809999999995,1502.976,0,1312,1,0,44.1,1 +26,486.82809999999995,1502.976,0,1298,1,0,44.1,1 +26,486.82809999999995,1502.976,0,1606,1,0,44.1,1 +26,486.82809999999995,1502.976,0,1622,1,0,44.1,1 +26,486.82809999999995,1502.976,0,1673,0,0,44.1,1 +26,486.82809999999995,1502.976,0,1676,1,0,44.1,1 +26,486.82809999999995,1502.976,0,1693,1,0,44.1,1 +26,486.82809999999995,1502.976,1,1704,1,0,44.1,1 +26,486.82809999999995,1502.976,0,1750,0,0,44.1,1 +27,488.3052,1508.483,0,345,1,0,45.5,1 +27,488.3052,1508.483,0,372,1,0,45.5,1 +27,488.3052,1508.483,0,428,1,0,45.5,1 +27,488.3052,1508.483,0,638,1,0,45.5,1 +27,488.3052,1508.483,0,717,1,0,45.5,1 +27,488.3052,1508.483,0,743,1,0,45.5,1 +27,488.3052,1508.483,0,737,1,0,45.5,1 +27,488.3052,1508.483,0,861,1,0,45.5,1 +27,488.3052,1508.483,0,908,1,0,45.5,1 +27,488.3052,1508.483,1,908,1,0,45.5,1 +27,488.3052,1508.483,1,952,1,0,45.5,1 +27,488.3052,1508.483,1,1036,1,0,45.5,1 +27,488.3052,1508.483,1,1058,1,0,45.5,1 +27,488.3052,1508.483,0,1069,1,0,45.5,1 +27,488.3052,1508.483,1,1084,1,0,45.5,1 +27,488.3052,1508.483,0,1119,1,0,45.5,1 +27,488.3052,1508.483,0,1181,1,0,45.5,1 +27,488.3052,1508.483,1,1242,1,0,45.5,1 +27,488.3052,1508.483,0,1286,1,0,45.5,1 +27,488.3052,1508.483,0,1329,1,0,45.5,1 +27,488.3052,1508.483,0,1314,1,0,45.5,1 +27,488.3052,1508.483,1,1319,1,0,45.5,1 +27,488.3052,1508.483,1,1358,1,0,45.5,1 +27,488.3052,1508.483,0,1390,1,0,45.5,1 +27,488.3052,1508.483,1,1392,1,0,45.5,1 +27,488.3052,1508.483,1,1376,1,0,45.5,1 +27,488.3052,1508.483,0,1479,1,0,45.5,1 +27,488.3052,1508.483,1,1701,1,0,45.5,1 +27,488.3052,1508.483,0,1773,1,0,45.5,1 +28,493.3068,1510.61,0,439,1,1,50.55,1 +28,493.3068,1510.61,0,510,1,1,50.55,1 +28,493.3068,1510.61,0,542,1,1,50.55,1 +28,493.3068,1510.61,0,606,1,1,50.55,1 +28,493.3068,1510.61,0,591,1,1,50.55,1 +28,493.3068,1510.61,0,618,1,1,50.55,1 +28,493.3068,1510.61,0,656,1,1,50.55,1 +28,493.3068,1510.61,0,687,1,1,50.55,1 +28,493.3068,1510.61,1,781,1,1,50.55,1 +28,493.3068,1510.61,0,810,1,1,50.55,1 +28,493.3068,1510.61,0,845,1,1,50.55,1 +28,493.3068,1510.61,0,841,1,1,50.55,1 +28,493.3068,1510.61,0,875,1,1,50.55,1 +28,493.3068,1510.61,0,1006,1,1,50.55,1 +28,493.3068,1510.61,0,990,1,1,50.55,1 +28,493.3068,1510.61,0,1026,1,0,50.55,1 +28,493.3068,1510.61,0,1020,1,1,50.55,1 +28,493.3068,1510.61,0,1096,1,1,50.55,1 +28,493.3068,1510.61,0,1142,1,1,50.55,1 +28,493.3068,1510.61,0,1304,1,1,50.55,1 +28,493.3068,1510.61,0,1332,1,1,50.55,1 +28,493.3068,1510.61,0,1399,1,1,50.55,1 +28,493.3068,1510.61,0,1390,1,1,50.55,1 +28,493.3068,1510.61,0,1434,1,1,50.55,1 +28,493.3068,1510.61,0,1424,1,1,50.55,1 +28,493.3068,1510.61,0,1463,1,1,50.55,1 +28,493.3068,1510.61,0,1585,1,1,50.55,1 +28,493.3068,1510.61,1,1660,1,1,50.55,1 +28,493.3068,1510.61,0,1751,1,1,50.55,1 +28,493.3068,1510.61,0,1825,1,0,50.55,1 +28,493.3068,1510.61,0,1828,1,1,50.55,1 +28,493.3068,1510.61,0,1822,1,1,50.55,1 +29,493.3348,1504.42,0,419,1,1,52.25,1 +29,493.3348,1504.42,0,451,1,1,52.25,1 +29,493.3348,1504.42,0,493,1,1,52.25,1 +29,493.3348,1504.42,0,550,1,1,52.25,1 +29,493.3348,1504.42,0,536,1,1,52.25,1 +29,493.3348,1504.42,0,695,1,1,52.25,1 +29,493.3348,1504.42,0,695,1,1,52.25,1 +29,493.3348,1504.42,0,783,1,1,52.25,1 +29,493.3348,1504.42,0,774,1,1,52.25,1 +29,493.3348,1504.42,0,853,1,1,52.25,1 +29,493.3348,1504.42,0,837,1,1,52.25,1 +29,493.3348,1504.42,0,870,1,1,52.25,1 +29,493.3348,1504.42,0,922,1,1,52.25,1 +29,493.3348,1504.42,0,1024,1,1,52.25,1 +29,493.3348,1504.42,0,1023,1,1,52.25,1 +29,493.3348,1504.42,0,1139,1,1,52.25,1 +29,493.3348,1504.42,0,1232,1,0,52.25,1 +29,493.3348,1504.42,0,1304,1,1,52.25,1 +29,493.3348,1504.42,0,1298,1,1,52.25,1 +29,493.3348,1504.42,0,1285,1,1,52.25,1 +29,493.3348,1504.42,0,1339,1,1,52.25,1 +29,493.3348,1504.42,0,1427,1,1,52.25,1 +29,493.3348,1504.42,0,1410,1,1,52.25,1 +29,493.3348,1504.42,0,1468,1,1,52.25,1 +29,493.3348,1504.42,0,1541,1,1,52.25,1 +30,496.3828,1503.397,0,415,1,0,54.2,0 +30,496.3828,1503.397,0,726,1,0,54.2,0 +30,496.3828,1503.397,0,761,1,0,54.2,0 +30,496.3828,1503.397,0,818,1,0,54.2,0 +30,496.3828,1503.397,0,854,1,0,54.2,0 +30,496.3828,1503.397,0,974,1,0,54.2,0 +30,496.3828,1503.397,0,954,1,0,54.2,0 +30,496.3828,1503.397,0,992,1,0,54.2,0 +30,496.3828,1503.397,0,1433,1,0,54.2,0 +30,496.3828,1503.397,0,1541,1,0,54.2,0 +30,496.3828,1503.397,0,1673,1,0,54.2,0 +30,496.3828,1503.397,0,1721,1,1,54.2,0 +31,496.572,1504.953,0,371,1,0,52.25,0 +31,496.572,1504.953,1,410,1,0,52.25,0 +31,496.572,1504.953,0,432,1,0,52.25,0 +31,496.572,1504.953,0,490,1,0,52.25,0 +31,496.572,1504.953,0,538,1,0,52.25,0 +31,496.572,1504.953,0,533,1,0,52.25,0 +31,496.572,1504.953,0,529,1,0,52.25,0 +31,496.572,1504.953,0,629,1,0,52.25,0 +31,496.572,1504.953,1,627,1,0,52.25,0 +31,496.572,1504.953,0,689,1,0,52.25,0 +31,496.572,1504.953,0,708,1,0,52.25,0 +31,496.572,1504.953,0,708,1,0,52.25,0 +31,496.572,1504.953,0,733,1,0,52.25,0 +31,496.572,1504.953,0,733,1,0,52.25,0 +31,496.572,1504.953,0,793,1,0,52.25,0 +31,496.572,1504.953,0,814,1,0,52.25,0 +31,496.572,1504.953,0,829,1,0,52.25,0 +31,496.572,1504.953,0,867,1,0,52.25,0 +31,496.572,1504.953,0,909,1,0,52.25,0 +31,496.572,1504.953,0,931,1,0,52.25,0 +31,496.572,1504.953,0,1064,1,0,52.25,0 +31,496.572,1504.953,1,1068,1,0,52.25,0 +31,496.572,1504.953,1,1099,1,0,52.25,0 +31,496.572,1504.953,0,1153,1,0,52.25,0 +31,496.572,1504.953,0,1130,1,0,52.25,0 +31,496.572,1504.953,0,1369,1,0,52.25,0 +31,496.572,1504.953,0,1374,1,0,52.25,0 +31,496.572,1504.953,0,1429,1,0,52.25,0 +31,496.572,1504.953,1,1449,1,0,52.25,0 +31,496.572,1504.953,0,1480,1,0,52.25,0 +31,496.572,1504.953,0,1521,1,0,52.25,0 +31,496.572,1504.953,0,1572,1,0,52.25,0 +31,496.572,1504.953,0,1566,1,0,52.25,0 +31,496.572,1504.953,0,1605,1,0,52.25,0 +31,496.572,1504.953,0,1589,1,0,52.25,0 +31,496.572,1504.953,0,1661,1,0,52.25,0 +31,496.572,1504.953,0,1694,1,0,52.25,0 +31,496.572,1504.953,0,1738,1,0,52.25,0 +31,496.572,1504.953,1,1755,1,0,52.25,0 +31,496.572,1504.953,0,1808,1,0,52.25,0 +32,502.8108,1497.501,1,1816,1,1,52.25,1 +32,502.8108,1497.501,0,398,1,1,52.25,1 +32,502.8108,1497.501,0,413,1,1,52.25,1 +32,502.8108,1497.501,0,411,1,1,52.25,1 +32,502.8108,1497.501,0,456,1,1,52.25,1 +32,502.8108,1497.501,0,451,1,1,52.25,1 +32,502.8108,1497.501,0,449,1,1,52.25,1 +32,502.8108,1497.501,0,448,1,1,52.25,1 +32,502.8108,1497.501,1,685,1,1,52.25,1 +32,502.8108,1497.501,0,852,1,1,52.25,1 +32,502.8108,1497.501,0,874,1,1,52.25,1 +32,502.8108,1497.501,0,873,1,1,52.25,1 +32,502.8108,1497.501,0,861,1,1,52.25,1 +32,502.8108,1497.501,0,861,1,1,52.25,1 +32,502.8108,1497.501,0,985,1,0,52.25,1 +32,502.8108,1497.501,0,989,1,1,52.25,1 +32,502.8108,1497.501,1,1023,1,1,52.25,1 +32,502.8108,1497.501,0,1132,1,1,52.25,1 +32,502.8108,1497.501,0,1238,1,1,52.25,1 +32,502.8108,1497.501,0,1269,1,1,52.25,1 +32,502.8108,1497.501,0,1358,1,1,52.25,1 +32,502.8108,1497.501,0,1450,1,1,52.25,1 +32,502.8108,1497.501,0,1481,1,1,52.25,1 +32,502.8108,1497.501,0,1481,1,1,52.25,1 +32,502.8108,1497.501,0,1528,1,1,52.25,1 +32,502.8108,1497.501,0,1695,1,0,52.25,1 +32,502.8108,1497.501,1,1763,1,1,52.25,1 +33,506.4002,1496.196,0,422,1,0,44.1,0 +33,506.4002,1496.196,1,402,1,0,44.1,0 +33,506.4002,1496.196,0,451,1,0,44.1,0 +33,506.4002,1496.196,0,465,1,0,44.1,0 +33,506.4002,1496.196,1,613,1,0,44.1,0 +33,506.4002,1496.196,0,627,1,0,44.1,0 +33,506.4002,1496.196,0,677,1,0,44.1,0 +33,506.4002,1496.196,0,675,1,0,44.1,0 +33,506.4002,1496.196,1,734,1,0,44.1,0 +33,506.4002,1496.196,0,751,1,0,44.1,0 +33,506.4002,1496.196,0,792,1,0,44.1,0 +33,506.4002,1496.196,1,855,1,0,44.1,0 +33,506.4002,1496.196,0,875,1,0,44.1,0 +33,506.4002,1496.196,0,904,1,0,44.1,0 +33,506.4002,1496.196,0,970,1,0,44.1,0 +33,506.4002,1496.196,0,955,1,0,44.1,0 +33,506.4002,1496.196,0,1031,1,0,44.1,0 +33,506.4002,1496.196,0,1146,1,0,44.1,0 +33,506.4002,1496.196,0,1144,1,0,44.1,0 +33,506.4002,1496.196,0,1132,1,0,44.1,0 +33,506.4002,1496.196,0,1172,1,0,44.1,0 +33,506.4002,1496.196,0,1170,1,0,44.1,0 +33,506.4002,1496.196,0,1170,1,0,44.1,0 +33,506.4002,1496.196,0,1162,1,0,44.1,0 +33,506.4002,1496.196,0,1279,1,0,44.1,0 +33,506.4002,1496.196,0,1337,1,0,44.1,0 +33,506.4002,1496.196,1,1358,1,0,44.1,0 +33,506.4002,1496.196,0,1389,1,0,44.1,0 +33,506.4002,1496.196,0,1450,1,0,44.1,0 +33,506.4002,1496.196,1,1450,1,0,44.1,0 +33,506.4002,1496.196,0,1487,1,0,44.1,0 +33,506.4002,1496.196,0,1542,1,0,44.1,0 +33,506.4002,1496.196,0,1664,1,0,44.1,0 +33,506.4002,1496.196,0,1664,1,0,44.1,0 +33,506.4002,1496.196,0,1755,1,0,44.1,0 +34,507.5815,1496.568,1,1802,1,1,44.1,1 +34,507.5815,1496.568,0,385,1,1,44.1,1 +34,507.5815,1496.568,0,375,1,1,44.1,1 +34,507.5815,1496.568,0,420,1,1,44.1,1 +34,507.5815,1496.568,1,435,1,1,44.1,1 +34,507.5815,1496.568,0,471,1,1,44.1,1 +34,507.5815,1496.568,0,602,1,1,44.1,1 +34,507.5815,1496.568,0,623,1,1,44.1,1 +34,507.5815,1496.568,0,660,1,1,44.1,1 +34,507.5815,1496.568,0,677,1,1,44.1,1 +34,507.5815,1496.568,0,763,1,0,44.1,1 +34,507.5815,1496.568,1,764,1,1,44.1,1 +34,507.5815,1496.568,0,874,1,1,44.1,1 +34,507.5815,1496.568,0,905,1,1,44.1,1 +34,507.5815,1496.568,0,1013,1,1,44.1,1 +34,507.5815,1496.568,0,1058,1,1,44.1,1 +34,507.5815,1496.568,0,1092,1,1,44.1,1 +34,507.5815,1496.568,0,1073,1,1,44.1,1 +34,507.5815,1496.568,0,1100,1,1,44.1,1 +34,507.5815,1496.568,0,1115,1,1,44.1,1 +34,507.5815,1496.568,0,1182,1,1,44.1,1 +34,507.5815,1496.568,0,1209,1,1,44.1,1 +34,507.5815,1496.568,0,1421,1,1,44.1,1 +34,507.5815,1496.568,0,1543,1,1,44.1,1 +34,507.5815,1496.568,0,1543,1,1,44.1,1 +34,507.5815,1496.568,0,1615,1,0,44.1,1 +34,507.5815,1496.568,0,1721,1,1,44.1,1 +34,507.5815,1496.568,0,1787,1,1,44.1,1 +34,507.5815,1496.568,0,1817,1,1,44.1,1 +34,507.5815,1496.568,0,1817,1,1,44.1,1 +34,507.5815,1496.568,0,1817,1,1,44.1,1 +35,514.695,1489.011,0,387,1,0,45.5,0 +35,514.695,1489.011,0,448,1,0,45.5,0 +35,514.695,1489.011,0,502,1,0,45.5,0 +35,514.695,1489.011,0,533,1,0,45.5,0 +35,514.695,1489.011,0,570,1,0,45.5,0 +35,514.695,1489.011,0,621,1,0,45.5,0 +35,514.695,1489.011,1,709,1,0,45.5,0 +35,514.695,1489.011,0,753,1,0,45.5,0 +35,514.695,1489.011,0,753,1,0,45.5,0 +35,514.695,1489.011,0,793,1,0,45.5,0 +35,514.695,1489.011,0,819,1,0,45.5,0 +35,514.695,1489.011,0,844,1,0,45.5,0 +35,514.695,1489.011,0,885,1,0,45.5,0 +35,514.695,1489.011,0,897,1,0,45.5,0 +35,514.695,1489.011,0,890,1,0,45.5,0 +35,514.695,1489.011,0,953,1,0,45.5,0 +35,514.695,1489.011,0,1117,1,0,45.5,0 +35,514.695,1489.011,0,1189,1,0,45.5,0 +35,514.695,1489.011,0,1178,1,0,45.5,0 +35,514.695,1489.011,1,1239,1,0,45.5,0 +35,514.695,1489.011,1,1300,1,0,45.5,0 +35,514.695,1489.011,1,1300,1,0,45.5,0 +35,514.695,1489.011,1,1300,1,0,45.5,0 +35,514.695,1489.011,0,1331,1,0,45.5,0 +35,514.695,1489.011,1,1330,1,0,45.5,0 +35,514.695,1489.011,1,1399,1,0,45.5,0 +35,514.695,1489.011,1,1421,1,0,45.5,0 +35,514.695,1489.011,0,1451,1,0,45.5,0 +35,514.695,1489.011,1,1453,1,0,45.5,0 +35,514.695,1489.011,1,1517,1,0,45.5,0 +35,514.695,1489.011,0,1574,1,0,45.5,0 +35,514.695,1489.011,1,1574,1,0,45.5,0 +35,514.695,1489.011,1,1727,1,0,45.5,0 +36,515.7035999999999,1491.979,0,397,1,1,54.2,1 +36,515.7035999999999,1491.979,0,417,1,1,54.2,1 +36,515.7035999999999,1491.979,0,462,1,1,54.2,1 +36,515.7035999999999,1491.979,0,460,1,1,54.2,1 +36,515.7035999999999,1491.979,0,440,1,1,54.2,1 +36,515.7035999999999,1491.979,0,485,1,1,54.2,1 +36,515.7035999999999,1491.979,0,466,1,1,54.2,1 +36,515.7035999999999,1491.979,0,557,1,1,54.2,1 +36,515.7035999999999,1491.979,0,659,1,1,54.2,1 +36,515.7035999999999,1491.979,1,707,1,1,54.2,1 +36,515.7035999999999,1491.979,0,853,1,1,54.2,1 +36,515.7035999999999,1491.979,0,829,1,1,54.2,1 +36,515.7035999999999,1491.979,0,866,1,1,54.2,1 +36,515.7035999999999,1491.979,1,872,1,1,54.2,1 +36,515.7035999999999,1491.979,0,902,1,1,54.2,1 +36,515.7035999999999,1491.979,0,967,1,1,54.2,1 +36,515.7035999999999,1491.979,0,1187,1,1,54.2,1 +36,515.7035999999999,1491.979,1,1179,1,1,54.2,1 +36,515.7035999999999,1491.979,0,1239,1,1,54.2,1 +36,515.7035999999999,1491.979,0,1270,1,1,54.2,1 +36,515.7035999999999,1491.979,0,1342,1,1,54.2,1 +36,515.7035999999999,1491.979,0,1359,1,1,54.2,1 +36,515.7035999999999,1491.979,0,1355,1,1,54.2,1 +36,515.7035999999999,1491.979,0,1355,1,1,54.2,1 +36,515.7035999999999,1491.979,0,1422,1,1,54.2,1 +36,515.7035999999999,1491.979,0,1512,1,1,54.2,1 +36,515.7035999999999,1491.979,0,1786,1,1,54.2,1 +36,515.7035999999999,1491.979,0,1817,1,1,54.2,1 +37,517.5574,1489.346,1,1815,0,0,45.5,1 +37,517.5574,1489.346,0,358,1,0,45.5,1 +37,517.5574,1489.346,0,385,1,0,45.5,1 +37,517.5574,1489.346,0,454,1,1,45.5,1 +37,517.5574,1489.346,1,445,1,1,45.5,1 +37,517.5574,1489.346,0,589,1,0,45.5,1 +37,517.5574,1489.346,0,606,1,1,45.5,1 +37,517.5574,1489.346,1,629,1,1,45.5,1 +37,517.5574,1489.346,1,623,1,1,45.5,1 +37,517.5574,1489.346,0,646,1,1,45.5,1 +37,517.5574,1489.346,0,718,1,1,45.5,1 +37,517.5574,1489.346,0,796,1,1,45.5,1 +37,517.5574,1489.346,1,827,1,1,45.5,1 +37,517.5574,1489.346,1,962,1,0,45.5,1 +37,517.5574,1489.346,0,1002,1,1,45.5,1 +37,517.5574,1489.346,0,995,1,1,45.5,1 +37,517.5574,1489.346,0,1044,1,1,45.5,1 +37,517.5574,1489.346,1,1064,0,0,45.5,1 +37,517.5574,1489.346,0,1160,1,1,45.5,1 +37,517.5574,1489.346,0,1138,1,1,45.5,1 +37,517.5574,1489.346,0,1174,1,1,45.5,1 +37,517.5574,1489.346,0,1282,1,1,45.5,1 +37,517.5574,1489.346,0,1312,1,1,45.5,1 +37,517.5574,1489.346,0,1307,1,1,45.5,1 +37,517.5574,1489.346,0,1358,1,1,45.5,1 +37,517.5574,1489.346,0,1452,1,1,45.5,1 +37,517.5574,1489.346,0,1507,0,0,45.5,1 +37,517.5574,1489.346,0,1571,1,1,45.5,1 +37,517.5574,1489.346,0,1724,1,1,45.5,1 +37,517.5574,1489.346,1,1715,1,1,45.5,1 +38,517.7782,1491.917,0,401,1,0,45.5,1 +38,517.7782,1491.917,0,416,1,0,45.5,1 +38,517.7782,1491.917,0,448,1,0,45.5,1 +38,517.7782,1491.917,0,509,1,0,45.5,1 +38,517.7782,1491.917,0,569,1,0,45.5,1 +38,517.7782,1491.917,0,812,1,0,45.5,1 +38,517.7782,1491.917,0,903,1,0,45.5,1 +38,517.7782,1491.917,0,970,1,0,45.5,1 +38,517.7782,1491.917,0,951,1,0,45.5,1 +38,517.7782,1491.917,0,1050,1,0,45.5,1 +38,517.7782,1491.917,0,1071,1,0,45.5,1 +38,517.7782,1491.917,0,1095,1,0,45.5,1 +38,517.7782,1491.917,1,1072,1,0,45.5,1 +38,517.7782,1491.917,0,1131,1,0,45.5,1 +38,517.7782,1491.917,0,1134,1,0,45.5,1 +38,517.7782,1491.917,1,1180,1,0,45.5,1 +38,517.7782,1491.917,1,1165,1,0,45.5,1 +38,517.7782,1491.917,0,1214,1,0,45.5,1 +38,517.7782,1491.917,0,1209,1,0,45.5,1 +38,517.7782,1491.917,0,1239,1,0,45.5,1 +38,517.7782,1491.917,1,1312,1,0,45.5,1 +38,517.7782,1491.917,0,1334,1,0,45.5,1 +38,517.7782,1491.917,0,1359,1,0,45.5,1 +38,517.7782,1491.917,0,1421,1,0,45.5,1 +38,517.7782,1491.917,1,1502,1,0,45.5,1 +38,517.7782,1491.917,1,1604,1,0,45.5,1 +38,517.7782,1491.917,0,1635,1,0,45.5,1 +38,517.7782,1491.917,0,1787,1,0,45.5,1 +39,519.8289,1496.607,0,399,1,0,45.5,0 +39,519.8289,1496.607,1,437,1,0,45.5,0 +39,519.8289,1496.607,0,486,1,0,45.5,0 +39,519.8289,1496.607,0,529,1,0,45.5,0 +39,519.8289,1496.607,1,590,1,0,45.5,0 +39,519.8289,1496.607,0,722,1,0,45.5,0 +39,519.8289,1496.607,0,719,1,0,45.5,0 +39,519.8289,1496.607,1,722,1,0,45.5,0 +39,519.8289,1496.607,0,792,1,0,45.5,0 +39,519.8289,1496.607,0,784,1,0,45.5,0 +39,519.8289,1496.607,1,855,1,0,45.5,0 +39,519.8289,1496.607,0,910,1,0,45.5,0 +39,519.8289,1496.607,0,895,1,0,45.5,0 +39,519.8289,1496.607,1,909,1,0,45.5,0 +39,519.8289,1496.607,0,936,0,0,45.5,0 +39,519.8289,1496.607,0,949,1,0,45.5,0 +39,519.8289,1496.607,0,1007,0,0,45.5,0 +39,519.8289,1496.607,0,1002,0,0,45.5,0 +39,519.8289,1496.607,0,989,1,0,45.5,0 +39,519.8289,1496.607,1,1038,1,0,45.5,0 +39,519.8289,1496.607,0,1066,1,0,45.5,0 +39,519.8289,1496.607,0,1148,1,0,45.5,0 +39,519.8289,1496.607,0,1135,1,0,45.5,0 +39,519.8289,1496.607,0,1177,1,0,45.5,0 +39,519.8289,1496.607,1,1175,1,0,45.5,0 +39,519.8289,1496.607,0,1203,1,0,45.5,0 +39,519.8289,1496.607,0,1271,1,0,45.5,0 +39,519.8289,1496.607,0,1301,1,0,45.5,0 +39,519.8289,1496.607,0,1301,1,0,45.5,0 +39,519.8289,1496.607,0,1289,1,0,45.5,0 +39,519.8289,1496.607,1,1297,1,0,45.5,0 +39,519.8289,1496.607,0,1341,1,0,45.5,0 +39,519.8289,1496.607,0,1332,1,0,45.5,0 +39,519.8289,1496.607,0,1332,1,0,45.5,0 +39,519.8289,1496.607,0,1360,1,0,45.5,0 +39,519.8289,1496.607,1,1422,1,0,45.5,0 +39,519.8289,1496.607,1,1422,1,0,45.5,0 +39,519.8289,1496.607,0,1513,1,0,45.5,0 +39,519.8289,1496.607,0,1575,1,0,45.5,0 +39,519.8289,1496.607,1,1605,1,0,45.5,0 +39,519.8289,1496.607,0,1657,1,0,45.5,0 +40,523.5379,1485.623,0,341,1,0,50.55,1 +40,523.5379,1485.623,0,400,0,0,50.55,1 +40,523.5379,1485.623,0,411,1,0,50.55,1 +40,523.5379,1485.623,0,431,0,0,50.55,1 +40,523.5379,1485.623,0,471,0,0,50.55,1 +40,523.5379,1485.623,0,465,0,0,50.55,1 +40,523.5379,1485.623,0,484,1,0,50.55,1 +40,523.5379,1485.623,0,545,0,0,50.55,1 +40,523.5379,1485.623,0,588,0,0,50.55,1 +40,523.5379,1485.623,0,605,1,0,50.55,1 +40,523.5379,1485.623,0,629,0,0,50.55,1 +40,523.5379,1485.623,0,721,1,0,50.55,1 +40,523.5379,1485.623,0,789,0,0,50.55,1 +40,523.5379,1485.623,1,870,1,0,50.55,1 +40,523.5379,1485.623,1,925,1,0,50.55,1 +40,523.5379,1485.623,1,1105,0,0,50.55,1 +40,523.5379,1485.623,0,1208,0,0,50.55,1 +40,523.5379,1485.623,0,1208,1,0,50.55,1 +40,523.5379,1485.623,1,1276,1,0,50.55,1 +40,523.5379,1485.623,1,1275,1,0,50.55,1 +40,523.5379,1485.623,1,1335,1,0,50.55,1 +40,523.5379,1485.623,1,1359,1,0,50.55,1 +40,523.5379,1485.623,0,1390,0,0,50.55,1 +40,523.5379,1485.623,0,1403,1,0,50.55,1 +40,523.5379,1485.623,0,1408,0,0,50.55,1 +40,523.5379,1485.623,0,1755,1,0,50.55,1 +40,523.5379,1485.623,0,1816,1,0,50.55,1 +40,523.5379,1485.623,0,1816,1,0,50.55,1 +41,572.2874,1475.233,0,431,0,0,54.2,0 +41,572.2874,1475.233,0,412,1,0,54.2,0 +41,572.2874,1475.233,0,439,1,0,54.2,0 +41,572.2874,1475.233,0,476,1,0,54.2,0 +41,572.2874,1475.233,1,493,1,0,54.2,0 +41,572.2874,1475.233,0,510,1,0,54.2,0 +41,572.2874,1475.233,0,588,1,0,54.2,0 +41,572.2874,1475.233,0,581,1,0,54.2,0 +41,572.2874,1475.233,0,637,1,0,54.2,0 +41,572.2874,1475.233,0,737,1,0,54.2,0 +41,572.2874,1475.233,0,767,1,0,54.2,0 +41,572.2874,1475.233,0,765,1,0,54.2,0 +41,572.2874,1475.233,1,768,0,0,54.2,0 +41,572.2874,1475.233,1,785,0,0,54.2,0 +41,572.2874,1475.233,1,777,1,0,54.2,0 +41,572.2874,1475.233,1,840,1,0,54.2,0 +41,572.2874,1475.233,1,889,1,0,54.2,0 +41,572.2874,1475.233,0,918,0,0,54.2,0 +41,572.2874,1475.233,1,905,1,0,54.2,0 +41,572.2874,1475.233,0,1034,1,0,54.2,0 +41,572.2874,1475.233,0,1110,1,0,54.2,0 +41,572.2874,1475.233,0,1160,1,0,54.2,0 +41,572.2874,1475.233,1,1197,1,0,54.2,0 +41,572.2874,1475.233,1,1309,1,0,54.2,0 +41,572.2874,1475.233,0,1332,1,0,54.2,0 +41,572.2874,1475.233,0,1373,1,0,54.2,0 +41,572.2874,1475.233,0,1353,1,0,54.2,0 +41,572.2874,1475.233,0,1430,1,0,54.2,0 +41,572.2874,1475.233,0,1450,0,0,54.2,0 +41,572.2874,1475.233,0,1459,1,0,54.2,0 +41,572.2874,1475.233,0,1455,1,0,54.2,0 +41,572.2874,1475.233,1,1500,1,0,54.2,0 +41,572.2874,1475.233,0,1547,1,0,54.2,0 +41,572.2874,1475.233,0,1626,0,0,54.2,0 +41,572.2874,1475.233,0,1674,0,0,54.2,0 +41,572.2874,1475.233,1,1698,0,0,54.2,0 +41,572.2874,1475.233,0,1760,0,0,54.2,0 +42,578.7924,1482.075,1,1823,0,0,58.95,1 +42,578.7924,1482.075,1,1813,1,0,58.95,1 +42,578.7924,1482.075,1,378,0,0,58.95,1 +42,578.7924,1482.075,0,533,1,0,58.95,1 +42,578.7924,1482.075,0,633,0,0,58.95,1 +42,578.7924,1482.075,0,718,1,0,58.95,1 +42,578.7924,1482.075,1,801,0,0,58.95,1 +42,578.7924,1482.075,0,820,1,0,58.95,1 +42,578.7924,1482.075,0,840,1,0,58.95,1 +42,578.7924,1482.075,1,880,1,0,58.95,1 +42,578.7924,1482.075,1,905,1,0,58.95,1 +42,578.7924,1482.075,1,972,0,0,58.95,1 +42,578.7924,1482.075,1,1098,0,0,58.95,1 +42,578.7924,1482.075,1,1104,1,0,58.95,1 +42,578.7924,1482.075,1,1223,1,0,58.95,1 +42,578.7924,1482.075,0,1296,1,0,58.95,1 +42,578.7924,1482.075,1,1337,1,0,58.95,1 +42,578.7924,1482.075,0,1357,0,0,58.95,1 +42,578.7924,1482.075,1,1362,0,0,58.95,1 +42,578.7924,1482.075,0,1438,0,0,58.95,1 +42,578.7924,1482.075,1,1427,1,0,58.95,1 +42,578.7924,1482.075,1,1450,1,0,58.95,1 +42,578.7924,1482.075,1,1463,1,0,58.95,1 +42,578.7924,1482.075,0,1472,1,0,58.95,1 +42,578.7924,1482.075,1,1491,0,0,58.95,1 +42,578.7924,1482.075,1,1488,1,0,58.95,1 +42,578.7924,1482.075,0,1585,1,0,58.95,1 +42,578.7924,1482.075,0,1610,1,0,58.95,1 +42,578.7924,1482.075,0,1654,0,0,58.95,1 +42,578.7924,1482.075,0,1765,0,0,58.95,1 +43,582.1807,1485.578,1,1797,0,0,56.6,1 +43,582.1807,1485.578,1,424,0,0,56.6,1 +43,582.1807,1485.578,1,443,0,0,56.6,1 +43,582.1807,1485.578,0,578,0,0,56.6,1 +43,582.1807,1485.578,0,615,0,0,56.6,1 +43,582.1807,1485.578,1,727,1,0,56.6,1 +43,582.1807,1485.578,0,819,0,0,56.6,1 +43,582.1807,1485.578,1,822,0,0,56.6,1 +43,582.1807,1485.578,1,820,0,0,56.6,1 +43,582.1807,1485.578,0,842,0,0,56.6,1 +43,582.1807,1485.578,1,1097,0,0,56.6,1 +43,582.1807,1485.578,0,1175,0,0,56.6,1 +43,582.1807,1485.578,1,1215,0,0,56.6,1 +43,582.1807,1485.578,1,1215,0,0,56.6,1 +43,582.1807,1485.578,1,1232,0,0,56.6,1 +43,582.1807,1485.578,1,1313,1,0,56.6,1 +43,582.1807,1485.578,0,1332,0,0,56.6,1 +43,582.1807,1485.578,0,1369,0,0,56.6,1 +43,582.1807,1485.578,0,1386,0,0,56.6,1 +43,582.1807,1485.578,1,1387,0,0,56.6,1 +43,582.1807,1485.578,0,1426,0,0,56.6,1 +43,582.1807,1485.578,0,1466,0,0,56.6,1 +43,582.1807,1485.578,1,1448,0,0,56.6,1 +43,582.1807,1485.578,1,1460,0,0,56.6,1 +43,582.1807,1485.578,1,1591,0,0,56.6,1 +43,582.1807,1485.578,1,1683,0,0,56.6,1 +43,582.1807,1485.578,1,1702,1,0,56.6,1 +43,582.1807,1485.578,0,1804,0,0,56.6,1 +43,582.1807,1485.578,0,1807,1,0,56.6,1 +44,584.5435,1478.674,0,416,1,0,54.2,1 +44,584.5435,1478.674,0,446,0,0,54.2,1 +44,584.5435,1478.674,0,753,1,0,54.2,1 +44,584.5435,1478.674,0,786,1,0,54.2,1 +44,584.5435,1478.674,1,786,1,0,54.2,1 +44,584.5435,1478.674,1,867,1,0,54.2,1 +44,584.5435,1478.674,0,919,1,0,54.2,1 +44,584.5435,1478.674,1,934,1,0,54.2,1 +44,584.5435,1478.674,0,1025,0,0,54.2,1 +44,584.5435,1478.674,0,1039,1,0,54.2,1 +44,584.5435,1478.674,1,1018,1,0,54.2,1 +44,584.5435,1478.674,0,1090,1,0,54.2,1 +44,584.5435,1478.674,0,1098,1,0,54.2,1 +44,584.5435,1478.674,0,1129,1,0,54.2,1 +44,584.5435,1478.674,1,1121,1,0,54.2,1 +44,584.5435,1478.674,0,1142,1,0,54.2,1 +44,584.5435,1478.674,0,1171,0,0,54.2,1 +44,584.5435,1478.674,0,1177,1,0,54.2,1 +44,584.5435,1478.674,0,1435,0,0,54.2,1 +44,584.5435,1478.674,0,1486,1,0,54.2,1 +44,584.5435,1478.674,0,1473,1,0,54.2,1 +44,584.5435,1478.674,1,1499,1,0,54.2,1 +44,584.5435,1478.674,1,1477,1,0,54.2,1 +44,584.5435,1478.674,0,1517,0,0,54.2,1 +44,584.5435,1478.674,0,1517,1,0,54.2,1 +44,584.5435,1478.674,1,1601,1,0,54.2,1 +44,584.5435,1478.674,1,1669,1,0,54.2,1 +44,584.5435,1478.674,0,1687,1,0,54.2,1 +44,584.5435,1478.674,0,1759,1,0,54.2,1 +45,584.6529,1479.619,1,1833,0,0,52.25,1 +45,584.6529,1479.619,1,1798,0,0,52.25,1 +45,584.6529,1479.619,0,416,0,0,52.25,1 +45,584.6529,1479.619,0,425,1,1,52.25,1 +45,584.6529,1479.619,0,442,0,0,52.25,1 +45,584.6529,1479.619,0,446,1,0,52.25,1 +45,584.6529,1479.619,0,456,1,1,52.25,1 +45,584.6529,1479.619,0,472,0,0,52.25,1 +45,584.6529,1479.619,0,523,1,0,52.25,1 +45,584.6529,1479.619,0,555,1,1,52.25,1 +45,584.6529,1479.619,1,559,0,0,52.25,1 +45,584.6529,1479.619,0,564,1,1,52.25,1 +45,584.6529,1479.619,0,630,0,0,52.25,1 +45,584.6529,1479.619,0,735,0,0,52.25,1 +45,584.6529,1479.619,0,726,1,1,52.25,1 +45,584.6529,1479.619,0,743,0,0,52.25,1 +45,584.6529,1479.619,1,760,0,0,52.25,1 +45,584.6529,1479.619,1,745,0,0,52.25,1 +45,584.6529,1479.619,0,790,1,1,52.25,1 +45,584.6529,1479.619,1,830,1,1,52.25,1 +45,584.6529,1479.619,0,860,1,1,52.25,1 +45,584.6529,1479.619,1,910,0,0,52.25,1 +45,584.6529,1479.619,0,945,1,1,52.25,1 +45,584.6529,1479.619,0,940,1,1,52.25,1 +45,584.6529,1479.619,1,968,0,0,52.25,1 +45,584.6529,1479.619,0,1001,0,0,52.25,1 +45,584.6529,1479.619,0,1029,0,0,52.25,1 +45,584.6529,1479.619,1,1042,0,0,52.25,1 +45,584.6529,1479.619,0,1061,0,0,52.25,1 +45,584.6529,1479.619,1,1127,0,0,52.25,1 +45,584.6529,1479.619,1,1122,0,0,52.25,1 +45,584.6529,1479.619,0,1137,1,1,52.25,1 +45,584.6529,1479.619,0,1169,0,0,52.25,1 +45,584.6529,1479.619,0,1180,1,0,52.25,1 +45,584.6529,1479.619,0,1177,1,1,52.25,1 +45,584.6529,1479.619,1,1193,0,0,52.25,1 +45,584.6529,1479.619,0,1239,1,1,52.25,1 +45,584.6529,1479.619,1,1244,0,0,52.25,1 +45,584.6529,1479.619,0,1287,0,0,52.25,1 +45,584.6529,1479.619,0,1266,0,0,52.25,1 +45,584.6529,1479.619,0,1295,0,0,52.25,1 +45,584.6529,1479.619,0,1364,0,0,52.25,1 +45,584.6529,1479.619,0,1460,1,1,52.25,1 +45,584.6529,1479.619,1,1456,0,0,52.25,1 +45,584.6529,1479.619,1,1461,0,0,52.25,1 +45,584.6529,1479.619,1,1499,0,0,52.25,1 +45,584.6529,1479.619,1,1473,0,0,52.25,1 +45,584.6529,1479.619,0,1513,0,0,52.25,1 +45,584.6529,1479.619,0,1517,1,1,52.25,1 +45,584.6529,1479.619,0,1536,0,0,52.25,1 +45,584.6529,1479.619,1,1534,1,1,52.25,1 +45,584.6529,1479.619,0,1583,0,0,52.25,1 +45,584.6529,1479.619,0,1573,1,1,52.25,1 +45,584.6529,1479.619,0,1618,0,0,52.25,1 +45,584.6529,1479.619,0,1609,1,1,52.25,1 +45,584.6529,1479.619,1,1609,0,0,52.25,1 +45,584.6529,1479.619,0,1653,0,0,52.25,1 +45,584.6529,1479.619,0,1640,0,0,52.25,1 +45,584.6529,1479.619,0,1670,0,0,52.25,1 +45,584.6529,1479.619,1,1683,0,0,52.25,1 +45,584.6529,1479.619,1,1694,0,0,52.25,1 +45,584.6529,1479.619,0,1741,0,0,52.25,1 +46,586.2545,1479.185,0,405,1,1,54.2,1 +46,586.2545,1479.185,0,447,1,1,54.2,1 +46,586.2545,1479.185,0,549,1,1,54.2,1 +46,586.2545,1479.185,0,605,1,1,54.2,1 +46,586.2545,1479.185,0,627,1,1,54.2,1 +46,586.2545,1479.185,0,669,0,0,54.2,1 +46,586.2545,1479.185,0,684,1,1,54.2,1 +46,586.2545,1479.185,0,746,1,1,54.2,1 +46,586.2545,1479.185,0,745,1,1,54.2,1 +46,586.2545,1479.185,0,832,1,1,54.2,1 +46,586.2545,1479.185,1,832,1,1,54.2,1 +46,586.2545,1479.185,0,904,1,1,54.2,1 +46,586.2545,1479.185,0,1038,1,1,54.2,1 +46,586.2545,1479.185,0,1127,1,1,54.2,1 +46,586.2545,1479.185,0,1106,1,1,54.2,1 +46,586.2545,1479.185,0,1146,1,1,54.2,1 +46,586.2545,1479.185,0,1306,1,1,54.2,1 +46,586.2545,1479.185,1,1292,1,1,54.2,1 +46,586.2545,1479.185,0,1336,1,1,54.2,1 +46,586.2545,1479.185,0,1335,1,1,54.2,1 +46,586.2545,1479.185,0,1331,1,1,54.2,1 +46,586.2545,1479.185,1,1332,1,1,54.2,1 +46,586.2545,1479.185,0,1376,1,1,54.2,1 +46,586.2545,1479.185,1,1380,1,1,54.2,1 +46,586.2545,1479.185,0,1483,1,1,54.2,1 +46,586.2545,1479.185,1,1486,0,0,54.2,1 +46,586.2545,1479.185,0,1591,1,1,54.2,1 +46,586.2545,1479.185,0,1580,1,1,54.2,1 +46,586.2545,1479.185,1,1568,1,1,54.2,1 +46,586.2545,1479.185,1,1565,1,1,54.2,1 +46,586.2545,1479.185,0,1652,1,1,54.2,1 +46,586.2545,1479.185,0,1696,1,1,54.2,1 +46,586.2545,1479.185,0,1777,1,1,54.2,1 +46,586.2545,1479.185,0,1776,1,1,54.2,1 +46,586.2545,1479.185,0,1776,1,1,54.2,1 +47,591.2978,1471.011,0,426,1,0,58.95,0 +47,591.2978,1471.011,0,491,1,0,58.95,0 +47,591.2978,1471.011,1,521,0,0,58.95,0 +47,591.2978,1471.011,1,563,1,0,58.95,0 +47,591.2978,1471.011,0,619,0,0,58.95,0 +47,591.2978,1471.011,0,687,1,0,58.95,0 +47,591.2978,1471.011,1,803,1,0,58.95,0 +47,591.2978,1471.011,1,829,0,0,58.95,0 +47,591.2978,1471.011,0,858,1,0,58.95,0 +47,591.2978,1471.011,1,917,0,0,58.95,0 +47,591.2978,1471.011,0,1035,1,0,58.95,0 +47,591.2978,1471.011,1,1027,1,0,58.95,0 +47,591.2978,1471.011,1,1068,1,0,58.95,0 +47,591.2978,1471.011,1,1093,1,0,58.95,0 +47,591.2978,1471.011,1,1143,1,0,58.95,0 +47,591.2978,1471.011,1,1159,1,0,58.95,0 +47,591.2978,1471.011,1,1304,1,0,58.95,0 +47,591.2978,1471.011,0,1444,1,0,58.95,0 +47,591.2978,1471.011,0,1437,1,0,58.95,0 +47,591.2978,1471.011,0,1433,1,0,58.95,0 +47,591.2978,1471.011,1,1420,1,0,58.95,0 +47,591.2978,1471.011,0,1463,1,0,58.95,0 +47,591.2978,1471.011,0,1524,0,0,58.95,0 +47,591.2978,1471.011,1,1565,0,0,58.95,0 +47,591.2978,1471.011,1,1565,1,0,58.95,0 +47,591.2978,1471.011,0,1722,1,0,58.95,0 +47,591.2978,1471.011,1,1736,0,0,58.95,0 +48,594.5996,1468.916,1,1820,1,0,58.95,0 +48,594.5996,1468.916,1,1813,1,0,58.95,0 +48,594.5996,1468.916,1,425,1,0,58.95,0 +48,594.5996,1468.916,0,552,1,0,58.95,0 +48,594.5996,1468.916,1,699,1,0,58.95,0 +48,594.5996,1468.916,1,807,1,0,58.95,0 +48,594.5996,1468.916,1,825,0,0,58.95,0 +48,594.5996,1468.916,0,1135,1,0,58.95,0 +48,594.5996,1468.916,1,1276,1,0,58.95,0 +48,594.5996,1468.916,1,1582,1,0,58.95,0 +48,594.5996,1468.916,1,1717,0,0,58.95,0 +49,594.6102,1467.776,0,490,1,0,58.95,0 +49,594.6102,1467.776,1,549,1,0,58.95,0 +49,594.6102,1467.776,1,653,1,0,58.95,0 +49,594.6102,1467.776,1,646,1,0,58.95,0 +49,594.6102,1467.776,1,696,0,0,58.95,0 +49,594.6102,1467.776,1,1068,1,0,58.95,0 +49,594.6102,1467.776,1,1124,1,0,58.95,0 +49,594.6102,1467.776,1,1245,1,0,58.95,0 +49,594.6102,1467.776,1,1332,1,0,58.95,0 +49,594.6102,1467.776,1,1383,1,0,58.95,0 +49,594.6102,1467.776,1,1433,0,0,58.95,0 +49,594.6102,1467.776,1,1490,1,0,58.95,0 +49,594.6102,1467.776,1,1558,1,0,58.95,0 +49,594.6102,1467.776,1,1541,1,0,58.95,0 +49,594.6102,1467.776,1,1771,1,0,58.95,0 +50,595.1195,1482.908,0,485,1,1,58.95,1 +50,595.1195,1482.908,0,481,1,1,58.95,1 +50,595.1195,1482.908,0,515,1,1,58.95,1 +50,595.1195,1482.908,0,515,1,1,58.95,1 +50,595.1195,1482.908,0,560,1,1,58.95,1 +50,595.1195,1482.908,1,557,1,1,58.95,1 +50,595.1195,1482.908,1,576,1,1,58.95,1 +50,595.1195,1482.908,1,566,1,1,58.95,1 +50,595.1195,1482.908,1,648,1,1,58.95,1 +50,595.1195,1482.908,1,727,1,1,58.95,1 +50,595.1195,1482.908,1,734,1,1,58.95,1 +50,595.1195,1482.908,1,788,1,1,58.95,1 +50,595.1195,1482.908,0,911,1,1,58.95,1 +50,595.1195,1482.908,0,927,1,1,58.95,1 +50,595.1195,1482.908,1,1083,1,1,58.95,1 +50,595.1195,1482.908,0,1123,1,1,58.95,1 +50,595.1195,1482.908,0,1123,1,1,58.95,1 +50,595.1195,1482.908,1,1123,1,1,58.95,1 +50,595.1195,1482.908,1,1182,1,1,58.95,1 +50,595.1195,1482.908,0,1215,1,1,58.95,1 +50,595.1195,1482.908,0,1205,1,1,58.95,1 +50,595.1195,1482.908,1,1348,1,1,58.95,1 +50,595.1195,1482.908,0,1398,1,1,58.95,1 +50,595.1195,1482.908,0,1610,1,1,58.95,1 +50,595.1195,1482.908,1,1610,0,0,58.95,1 +50,595.1195,1482.908,0,1641,1,0,58.95,1 +50,595.1195,1482.908,0,1652,1,1,58.95,1 +50,595.1195,1482.908,0,1705,1,1,58.95,1 +50,595.1195,1482.908,0,1728,1,1,58.95,1 +50,595.1195,1482.908,1,1762,1,1,58.95,1 +50,595.1195,1482.908,0,1818,1,1,58.95,1 +51,596.1815,1474.316,1,1812,0,0,56.6,1 +51,596.1815,1474.316,0,491,0,0,56.6,1 +51,596.1815,1474.316,0,491,0,0,56.6,1 +51,596.1815,1474.316,0,491,0,0,56.6,1 +51,596.1815,1474.316,1,525,1,1,56.6,1 +51,596.1815,1474.316,1,623,0,0,56.6,1 +51,596.1815,1474.316,1,613,0,0,56.6,1 +51,596.1815,1474.316,1,647,0,0,56.6,1 +51,596.1815,1474.316,1,731,0,0,56.6,1 +51,596.1815,1474.316,0,784,1,1,56.6,1 +51,596.1815,1474.316,0,974,0,0,56.6,1 +51,596.1815,1474.316,1,990,0,0,56.6,1 +51,596.1815,1474.316,1,1006,0,0,56.6,1 +51,596.1815,1474.316,0,1042,1,1,56.6,1 +51,596.1815,1474.316,0,1104,1,1,56.6,1 +51,596.1815,1474.316,1,1098,0,0,56.6,1 +51,596.1815,1474.316,1,1123,0,0,56.6,1 +51,596.1815,1474.316,1,1315,0,0,56.6,1 +51,596.1815,1474.316,0,1365,0,0,56.6,1 +51,596.1815,1474.316,0,1365,0,0,56.6,1 +51,596.1815,1474.316,1,1381,0,0,56.6,1 +51,596.1815,1474.316,0,1388,0,0,56.6,1 +51,596.1815,1474.316,1,1407,0,0,56.6,1 +51,596.1815,1474.316,1,1425,0,0,56.6,1 +51,596.1815,1474.316,1,1502,0,0,56.6,1 +51,596.1815,1474.316,1,1501,0,0,56.6,1 +51,596.1815,1474.316,0,1562,1,1,56.6,1 +51,596.1815,1474.316,1,1702,0,0,56.6,1 +51,596.1815,1474.316,1,1702,0,0,56.6,1 +51,596.1815,1474.316,1,1737,0,0,56.6,1 +52,599.2595,1481.671,0,431,1,1,55.4,1 +52,599.2595,1481.671,1,429,0,0,55.4,1 +52,599.2595,1481.671,1,438,1,1,55.4,1 +52,599.2595,1481.671,1,456,1,1,55.4,1 +52,599.2595,1481.671,0,533,1,1,55.4,1 +52,599.2595,1481.671,0,544,1,1,55.4,1 +52,599.2595,1481.671,0,536,1,1,55.4,1 +52,599.2595,1481.671,1,553,0,0,55.4,1 +52,599.2595,1481.671,0,753,1,1,55.4,1 +52,599.2595,1481.671,0,920,1,1,55.4,1 +52,599.2595,1481.671,1,1006,0,0,55.4,1 +52,599.2595,1481.671,0,1063,1,1,55.4,1 +52,599.2595,1481.671,1,1077,1,1,55.4,1 +52,599.2595,1481.671,1,1061,1,1,55.4,1 +52,599.2595,1481.671,0,1093,1,1,55.4,1 +52,599.2595,1481.671,0,1124,0,0,55.4,1 +52,599.2595,1481.671,1,1141,1,1,55.4,1 +52,599.2595,1481.671,0,1178,1,1,55.4,1 +52,599.2595,1481.671,1,1226,0,0,55.4,1 +52,599.2595,1481.671,1,1208,1,1,55.4,1 +52,599.2595,1481.671,1,1326,1,1,55.4,1 +52,599.2595,1481.671,0,1347,1,1,55.4,1 +52,599.2595,1481.671,1,1345,1,1,55.4,1 +52,599.2595,1481.671,1,1331,1,1,55.4,1 +52,599.2595,1481.671,1,1374,0,0,55.4,1 +52,599.2595,1481.671,1,1380,1,1,55.4,1 +52,599.2595,1481.671,1,1362,1,1,55.4,1 +52,599.2595,1481.671,1,1427,0,0,55.4,1 +52,599.2595,1481.671,1,1491,1,1,55.4,1 +52,599.2595,1481.671,1,1586,1,1,55.4,1 +53,600.1578000000001,1470.825,1,1828,0,0,50.1,0 +53,600.1578000000001,1470.825,1,1817,0,0,50.1,0 +53,600.1578000000001,1470.825,1,1795,0,0,50.1,0 +53,600.1578000000001,1470.825,0,428,0,0,50.1,0 +53,600.1578000000001,1470.825,1,459,0,0,50.1,0 +53,600.1578000000001,1470.825,1,506,0,0,50.1,0 +53,600.1578000000001,1470.825,0,595,1,0,50.1,0 +53,600.1578000000001,1470.825,1,576,1,0,50.1,0 +53,600.1578000000001,1470.825,1,679,0,0,50.1,0 +53,600.1578000000001,1470.825,1,711,1,0,50.1,0 +53,600.1578000000001,1470.825,1,718,0,0,50.1,0 +53,600.1578000000001,1470.825,0,749,1,0,50.1,0 +53,600.1578000000001,1470.825,0,919,0,0,50.1,0 +53,600.1578000000001,1470.825,0,946,0,0,50.1,0 +53,600.1578000000001,1470.825,1,944,1,0,50.1,0 +53,600.1578000000001,1470.825,1,938,1,0,50.1,0 +53,600.1578000000001,1470.825,0,993,1,0,50.1,0 +53,600.1578000000001,1470.825,1,1079,0,0,50.1,0 +53,600.1578000000001,1470.825,0,1089,1,0,50.1,0 +53,600.1578000000001,1470.825,0,1128,0,0,50.1,0 +53,600.1578000000001,1470.825,0,1189,0,0,50.1,0 +53,600.1578000000001,1470.825,0,1291,0,0,50.1,0 +53,600.1578000000001,1470.825,0,1380,0,0,50.1,0 +53,600.1578000000001,1470.825,1,1380,0,0,50.1,0 +53,600.1578000000001,1470.825,1,1440,0,0,50.1,0 +53,600.1578000000001,1470.825,1,1435,0,0,50.1,0 +53,600.1578000000001,1470.825,1,1456,1,0,50.1,0 +53,600.1578000000001,1470.825,1,1461,1,0,50.1,0 +53,600.1578000000001,1470.825,0,1544,0,0,50.1,0 +53,600.1578000000001,1470.825,1,1736,0,0,50.1,0 +53,600.1578000000001,1470.825,1,1758,1,0,50.1,0 +54,601.4945,1469.864,1,1798,1,1,50.1,1 +54,601.4945,1469.864,1,490,1,1,50.1,1 +54,601.4945,1469.864,1,593,1,1,50.1,1 +54,601.4945,1469.864,0,611,1,1,50.1,1 +54,601.4945,1469.864,1,624,1,0,50.1,1 +54,601.4945,1469.864,0,689,0,0,50.1,1 +54,601.4945,1469.864,1,689,0,0,50.1,1 +54,601.4945,1469.864,0,758,1,1,50.1,1 +54,601.4945,1469.864,0,787,1,0,50.1,1 +54,601.4945,1469.864,0,806,1,1,50.1,1 +54,601.4945,1469.864,1,790,0,0,50.1,1 +54,601.4945,1469.864,0,854,1,1,50.1,1 +54,601.4945,1469.864,1,891,0,0,50.1,1 +54,601.4945,1469.864,0,965,0,0,50.1,1 +54,601.4945,1469.864,0,965,1,1,50.1,1 +54,601.4945,1469.864,0,1005,1,1,50.1,1 +54,601.4945,1469.864,1,1023,0,0,50.1,1 +54,601.4945,1469.864,1,1083,1,1,50.1,1 +54,601.4945,1469.864,1,1180,1,1,50.1,1 +54,601.4945,1469.864,0,1228,0,0,50.1,1 +54,601.4945,1469.864,1,1250,0,0,50.1,1 +54,601.4945,1469.864,1,1315,1,1,50.1,1 +54,601.4945,1469.864,1,1407,1,1,50.1,1 +54,601.4945,1469.864,1,1507,1,1,50.1,1 +54,601.4945,1469.864,1,1567,1,1,50.1,1 +54,601.4945,1469.864,1,1695,0,0,50.1,1 +54,601.4945,1469.864,1,1740,0,0,50.1,1 +54,601.4945,1469.864,1,1744,1,1,50.1,1 +54,601.4945,1469.864,1,1770,0,0,50.1,1 +55,602.663,1489.336,1,1792,1,0,45.5,1 +55,602.663,1489.336,1,1792,1,1,45.5,1 +55,602.663,1489.336,0,395,1,1,45.5,1 +55,602.663,1489.336,0,392,1,1,45.5,1 +55,602.663,1489.336,0,422,0,0,45.5,1 +55,602.663,1489.336,0,453,1,0,45.5,1 +55,602.663,1489.336,0,453,1,1,45.5,1 +55,602.663,1489.336,0,453,1,1,45.5,1 +55,602.663,1489.336,1,512,1,1,45.5,1 +55,602.663,1489.336,0,545,1,1,45.5,1 +55,602.663,1489.336,0,545,1,1,45.5,1 +55,602.663,1489.336,0,536,1,1,45.5,1 +55,602.663,1489.336,0,575,0,0,45.5,1 +55,602.663,1489.336,1,578,0,0,45.5,1 +55,602.663,1489.336,1,615,1,1,45.5,1 +55,602.663,1489.336,1,606,1,1,45.5,1 +55,602.663,1489.336,1,623,1,1,45.5,1 +55,602.663,1489.336,0,704,1,1,45.5,1 +55,602.663,1489.336,0,734,0,0,45.5,1 +55,602.663,1489.336,0,728,1,1,45.5,1 +55,602.663,1489.336,1,735,1,1,45.5,1 +55,602.663,1489.336,1,757,1,1,45.5,1 +55,602.663,1489.336,0,800,1,1,45.5,1 +55,602.663,1489.336,0,886,1,0,45.5,1 +55,602.663,1489.336,0,866,1,1,45.5,1 +55,602.663,1489.336,0,918,1,1,45.5,1 +55,602.663,1489.336,0,898,1,1,45.5,1 +55,602.663,1489.336,0,897,1,1,45.5,1 +55,602.663,1489.336,1,953,1,1,45.5,1 +55,602.663,1489.336,1,940,1,1,45.5,1 +55,602.663,1489.336,1,974,1,1,45.5,1 +55,602.663,1489.336,0,987,1,0,45.5,1 +55,602.663,1489.336,0,999,1,1,45.5,1 +55,602.663,1489.336,0,1019,1,1,45.5,1 +55,602.663,1489.336,0,1061,1,1,45.5,1 +55,602.663,1489.336,1,1061,1,1,45.5,1 +55,602.663,1489.336,1,1061,1,1,45.5,1 +55,602.663,1489.336,0,1082,1,1,45.5,1 +55,602.663,1489.336,1,1091,1,1,45.5,1 +55,602.663,1489.336,0,1137,1,0,45.5,1 +55,602.663,1489.336,0,1149,1,1,45.5,1 +55,602.663,1489.336,1,1183,1,0,45.5,1 +55,602.663,1489.336,1,1198,1,1,45.5,1 +55,602.663,1489.336,1,1313,1,1,45.5,1 +55,602.663,1489.336,0,1329,1,0,45.5,1 +55,602.663,1489.336,1,1322,1,1,45.5,1 +55,602.663,1489.336,0,1374,1,1,45.5,1 +55,602.663,1489.336,1,1364,0,0,45.5,1 +55,602.663,1489.336,1,1426,1,1,45.5,1 +55,602.663,1489.336,0,1456,1,1,45.5,1 +55,602.663,1489.336,1,1514,1,1,45.5,1 +55,602.663,1489.336,0,1588,1,1,45.5,1 +55,602.663,1489.336,1,1590,0,0,45.5,1 +55,602.663,1489.336,1,1574,1,1,45.5,1 +55,602.663,1489.336,0,1652,1,1,45.5,1 +55,602.663,1489.336,1,1672,1,1,45.5,1 +55,602.663,1489.336,1,1667,1,1,45.5,1 +55,602.663,1489.336,1,1662,1,1,45.5,1 +55,602.663,1489.336,0,1691,1,0,45.5,1 +55,602.663,1489.336,1,1744,1,1,45.5,1 +55,602.663,1489.336,0,1792,1,1,45.5,1 +55,602.663,1489.336,0,1810,1,1,45.5,1 +56,604.6693,1478.886,1,1828,1,1,58.95,1 +56,604.6693,1478.886,1,1828,1,1,58.95,1 +56,604.6693,1478.886,0,391,1,1,58.95,1 +56,604.6693,1478.886,0,575,1,1,58.95,1 +56,604.6693,1478.886,1,651,0,0,58.95,1 +56,604.6693,1478.886,0,663,1,1,58.95,1 +56,604.6693,1478.886,1,674,0,0,58.95,1 +56,604.6693,1478.886,1,806,1,1,58.95,1 +56,604.6693,1478.886,0,858,1,1,58.95,1 +56,604.6693,1478.886,1,895,1,1,58.95,1 +56,604.6693,1478.886,0,916,1,1,58.95,1 +56,604.6693,1478.886,1,945,1,1,58.95,1 +56,604.6693,1478.886,1,978,1,1,58.95,1 +56,604.6693,1478.886,1,997,1,1,58.95,1 +56,604.6693,1478.886,1,1097,1,1,58.95,1 +56,604.6693,1478.886,1,1306,1,1,58.95,1 +56,604.6693,1478.886,0,1420,1,1,58.95,1 +56,604.6693,1478.886,1,1482,1,1,58.95,1 +56,604.6693,1478.886,1,1585,1,1,58.95,1 +56,604.6693,1478.886,0,1615,1,1,58.95,1 +56,604.6693,1478.886,1,1605,1,0,58.95,1 +56,604.6693,1478.886,1,1646,1,1,58.95,1 +56,604.6693,1478.886,1,1707,0,0,58.95,1 +56,604.6693,1478.886,0,1736,1,1,58.95,1 +56,604.6693,1478.886,0,1792,1,1,58.95,1 +56,604.6693,1478.886,1,1786,0,0,58.95,1 +56,604.6693,1478.886,1,1785,1,1,58.95,1 +56,604.6693,1478.886,1,1783,1,1,58.95,1 +56,604.6693,1478.886,0,1828,1,1,58.95,1 +57,604.7312,1485.729,0,473,1,0,54.2,0 +57,604.7312,1485.729,1,543,0,0,54.2,0 +57,604.7312,1485.729,0,638,1,0,54.2,0 +57,604.7312,1485.729,1,659,1,0,54.2,0 +57,604.7312,1485.729,1,695,0,0,54.2,0 +57,604.7312,1485.729,1,708,1,0,54.2,0 +57,604.7312,1485.729,1,712,0,0,54.2,0 +57,604.7312,1485.729,1,743,1,0,54.2,0 +57,604.7312,1485.729,1,741,1,0,54.2,0 +57,604.7312,1485.729,0,797,1,0,54.2,0 +57,604.7312,1485.729,0,809,1,0,54.2,0 +57,604.7312,1485.729,1,880,1,0,54.2,0 +57,604.7312,1485.729,0,902,1,0,54.2,0 +57,604.7312,1485.729,0,935,1,0,54.2,0 +57,604.7312,1485.729,0,925,1,0,54.2,0 +57,604.7312,1485.729,0,1072,1,0,54.2,0 +57,604.7312,1485.729,0,1121,1,0,54.2,0 +57,604.7312,1485.729,0,1148,1,0,54.2,0 +57,604.7312,1485.729,1,1227,1,0,54.2,0 +57,604.7312,1485.729,1,1310,1,0,54.2,0 +57,604.7312,1485.729,0,1435,1,0,54.2,0 +57,604.7312,1485.729,1,1531,1,0,54.2,0 +57,604.7312,1485.729,0,1644,1,0,54.2,0 +57,604.7312,1485.729,1,1642,1,0,54.2,0 +57,604.7312,1485.729,0,1721,0,0,54.2,0 +57,604.7312,1485.729,1,1728,1,0,54.2,0 +57,604.7312,1485.729,0,1744,1,0,54.2,0 +58,606.0828,1475.711,1,467,1,0,56.6,0 +58,606.0828,1475.711,0,645,1,0,56.6,0 +58,606.0828,1475.711,0,872,0,0,56.6,0 +58,606.0828,1475.711,1,909,0,0,56.6,0 +58,606.0828,1475.711,1,959,0,0,56.6,0 +58,606.0828,1475.711,1,1301,1,0,56.6,0 +58,606.0828,1475.711,1,1378,0,0,56.6,0 +58,606.0828,1475.711,0,1497,1,0,56.6,0 +59,610.3596,1477.024,1,428,1,0,50.1,1 +59,610.3596,1477.024,1,527,1,0,50.1,1 +59,610.3596,1477.024,1,609,0,0,50.1,1 +59,610.3596,1477.024,1,762,1,0,50.1,1 +59,610.3596,1477.024,0,882,1,0,50.1,1 +59,610.3596,1477.024,0,1016,1,0,50.1,1 +59,610.3596,1477.024,1,989,1,0,50.1,1 +59,610.3596,1477.024,0,1034,0,0,50.1,1 +59,610.3596,1477.024,0,1034,0,0,50.1,1 +59,610.3596,1477.024,0,1030,1,0,50.1,1 +59,610.3596,1477.024,0,1063,0,0,50.1,1 +59,610.3596,1477.024,0,1134,1,0,50.1,1 +59,610.3596,1477.024,0,1145,1,0,50.1,1 +59,610.3596,1477.024,1,1143,1,0,50.1,1 +59,610.3596,1477.024,1,1176,0,0,50.1,1 +59,610.3596,1477.024,1,1229,1,0,50.1,1 +59,610.3596,1477.024,1,1247,0,0,50.1,1 +59,610.3596,1477.024,0,1282,1,0,50.1,1 +59,610.3596,1477.024,1,1278,0,0,50.1,1 +59,610.3596,1477.024,0,1311,0,0,50.1,1 +59,610.3596,1477.024,0,1443,1,0,50.1,1 +59,610.3596,1477.024,1,1487,0,0,50.1,1 +59,610.3596,1477.024,1,1583,0,0,50.1,1 +59,610.3596,1477.024,0,1597,1,0,50.1,1 +59,610.3596,1477.024,1,1612,0,0,50.1,1 +59,610.3596,1477.024,1,1643,1,0,50.1,1 +59,610.3596,1477.024,1,1733,1,0,50.1,1 +59,610.3596,1477.024,0,1764,1,0,50.1,1 +59,610.3596,1477.024,0,1782,1,0,50.1,1 +59,610.3596,1477.024,0,1816,0,0,50.1,1 +60,611.26,1499.891,1,394,0,0,58.95,0 +60,611.26,1499.891,0,424,0,0,58.95,0 +60,611.26,1499.891,0,424,0,0,58.95,0 +60,611.26,1499.891,1,460,0,0,58.95,0 +60,611.26,1499.891,1,455,0,0,58.95,0 +60,611.26,1499.891,0,486,0,0,58.95,0 +60,611.26,1499.891,1,521,0,0,58.95,0 +60,611.26,1499.891,1,537,0,0,58.95,0 +60,611.26,1499.891,0,577,0,0,58.95,0 +60,611.26,1499.891,1,577,0,0,58.95,0 +60,611.26,1499.891,0,608,0,0,58.95,0 +60,611.26,1499.891,1,607,0,0,58.95,0 +60,611.26,1499.891,1,676,0,0,58.95,0 +60,611.26,1499.891,0,759,0,0,58.95,0 +60,611.26,1499.891,1,789,0,0,58.95,0 +60,611.26,1499.891,1,952,0,0,58.95,0 +60,611.26,1499.891,1,1124,0,0,58.95,0 +60,611.26,1499.891,1,1154,0,0,58.95,0 +60,611.26,1499.891,1,1154,0,0,58.95,0 +60,611.26,1499.891,1,1154,0,0,58.95,0 +60,611.26,1499.891,1,1153,0,0,58.95,0 +60,611.26,1499.891,1,1198,0,0,58.95,0 +60,611.26,1499.891,1,1218,0,0,58.95,0 +60,611.26,1499.891,1,1205,0,0,58.95,0 +60,611.26,1499.891,1,1248,0,0,58.95,0 +60,611.26,1499.891,1,1379,0,0,58.95,0 +60,611.26,1499.891,1,1472,0,0,58.95,0 +60,611.26,1499.891,1,1462,0,0,58.95,0 +60,611.26,1499.891,0,1519,0,0,58.95,0 +60,611.26,1499.891,1,1519,0,0,58.95,0 +60,611.26,1499.891,1,1581,0,0,58.95,0 +60,611.26,1499.891,1,1581,0,0,58.95,0 +60,611.26,1499.891,1,1611,0,0,58.95,0 +60,611.26,1499.891,1,1642,0,0,58.95,0 +60,611.26,1499.891,1,1642,0,0,58.95,0 +60,611.26,1499.891,0,1684,0,0,58.95,0 +60,611.26,1499.891,1,1673,0,0,58.95,0 +61,613.5295,1473.868,1,1830,0,0,50.1,1 +61,613.5295,1473.868,1,1825,0,0,50.1,1 +61,613.5295,1473.868,1,1795,1,0,50.1,1 +61,613.5295,1473.868,1,395,1,0,50.1,1 +61,613.5295,1473.868,1,425,0,0,50.1,1 +61,613.5295,1473.868,0,456,0,0,50.1,1 +61,613.5295,1473.868,0,517,1,0,50.1,1 +61,613.5295,1473.868,1,548,0,0,50.1,1 +61,613.5295,1473.868,1,583,0,0,50.1,1 +61,613.5295,1473.868,0,643,0,0,50.1,1 +61,613.5295,1473.868,1,729,1,0,50.1,1 +61,613.5295,1473.868,1,913,0,0,50.1,1 +61,613.5295,1473.868,0,1059,0,0,50.1,1 +61,613.5295,1473.868,1,1064,0,0,50.1,1 +61,613.5295,1473.868,1,1089,0,0,50.1,1 +61,613.5295,1473.868,1,1143,0,0,50.1,1 +61,613.5295,1473.868,1,1172,1,0,50.1,1 +61,613.5295,1473.868,0,1217,0,0,50.1,1 +61,613.5295,1473.868,0,1208,0,0,50.1,1 +61,613.5295,1473.868,1,1343,0,0,50.1,1 +61,613.5295,1473.868,1,1338,0,0,50.1,1 +61,613.5295,1473.868,1,1393,0,0,50.1,1 +61,613.5295,1473.868,0,1582,0,0,50.1,1 +61,613.5295,1473.868,0,1582,1,0,50.1,1 +61,613.5295,1473.868,1,1582,0,0,50.1,1 +61,613.5295,1473.868,1,1643,0,0,50.1,1 +61,613.5295,1473.868,1,1673,0,0,50.1,1 +61,613.5295,1473.868,1,1767,0,0,50.1,1 +62,614.6655999999999,1482.815,1,1795,1,0,50.1,1 +62,614.6655999999999,1482.815,0,354,1,0,50.1,1 +62,614.6655999999999,1482.815,0,394,1,0,50.1,1 +62,614.6655999999999,1482.815,1,400,0,0,50.1,1 +62,614.6655999999999,1482.815,0,430,1,0,50.1,1 +62,614.6655999999999,1482.815,0,430,1,0,50.1,1 +62,614.6655999999999,1482.815,0,455,0,0,50.1,1 +62,614.6655999999999,1482.815,0,497,1,0,50.1,1 +62,614.6655999999999,1482.815,0,492,1,0,50.1,1 +62,614.6655999999999,1482.815,0,481,1,0,50.1,1 +62,614.6655999999999,1482.815,0,642,0,0,50.1,1 +62,614.6655999999999,1482.815,0,655,1,0,50.1,1 +62,614.6655999999999,1482.815,0,685,0,0,50.1,1 +62,614.6655999999999,1482.815,1,734,0,0,50.1,1 +62,614.6655999999999,1482.815,0,795,1,0,50.1,1 +62,614.6655999999999,1482.815,0,781,1,0,50.1,1 +62,614.6655999999999,1482.815,0,814,1,0,50.1,1 +62,614.6655999999999,1482.815,0,887,0,0,50.1,1 +62,614.6655999999999,1482.815,0,873,1,0,50.1,1 +62,614.6655999999999,1482.815,1,893,1,0,50.1,1 +62,614.6655999999999,1482.815,1,909,1,0,50.1,1 +62,614.6655999999999,1482.815,1,948,0,0,50.1,1 +62,614.6655999999999,1482.815,0,1021,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1077,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1057,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1056,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1107,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1098,1,0,50.1,1 +62,614.6655999999999,1482.815,1,1099,0,0,50.1,1 +62,614.6655999999999,1482.815,1,1099,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1165,1,0,50.1,1 +62,614.6655999999999,1482.815,1,1164,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1178,1,0,50.1,1 +62,614.6655999999999,1482.815,1,1191,0,0,50.1,1 +62,614.6655999999999,1482.815,0,1237,0,0,50.1,1 +62,614.6655999999999,1482.815,0,1253,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1252,1,0,50.1,1 +62,614.6655999999999,1482.815,1,1316,0,0,50.1,1 +62,614.6655999999999,1482.815,0,1436,0,0,50.1,1 +62,614.6655999999999,1482.815,0,1464,0,0,50.1,1 +62,614.6655999999999,1482.815,0,1463,0,0,50.1,1 +62,614.6655999999999,1482.815,1,1464,0,0,50.1,1 +62,614.6655999999999,1482.815,0,1489,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1525,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1569,0,0,50.1,1 +62,614.6655999999999,1482.815,0,1594,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1630,0,0,50.1,1 +62,614.6655999999999,1482.815,0,1617,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1617,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1617,1,0,50.1,1 +62,614.6655999999999,1482.815,1,1617,1,0,50.1,1 +62,614.6655999999999,1482.815,1,1648,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1686,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1709,0,0,50.1,1 +62,614.6655999999999,1482.815,0,1750,1,0,50.1,1 +62,614.6655999999999,1482.815,1,1738,0,0,50.1,1 +62,614.6655999999999,1482.815,0,1800,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1834,0,0,50.1,1 +62,614.6655999999999,1482.815,0,1830,1,0,50.1,1 +62,614.6655999999999,1482.815,0,1830,1,0,50.1,1 +63,614.7225,1474.32,1,1815,0,0,50.1,1 +63,614.7225,1474.32,0,395,0,0,50.1,1 +63,614.7225,1474.32,0,395,0,0,50.1,1 +63,614.7225,1474.32,0,395,0,0,50.1,1 +63,614.7225,1474.32,1,554,0,0,50.1,1 +63,614.7225,1474.32,0,578,0,0,50.1,1 +63,614.7225,1474.32,1,603,1,0,50.1,1 +63,614.7225,1474.32,0,668,0,0,50.1,1 +63,614.7225,1474.32,0,699,0,0,50.1,1 +63,614.7225,1474.32,0,825,0,0,50.1,1 +63,614.7225,1474.32,0,852,0,0,50.1,1 +63,614.7225,1474.32,1,974,0,0,50.1,1 +63,614.7225,1474.32,0,1046,0,0,50.1,1 +63,614.7225,1474.32,1,1094,0,0,50.1,1 +63,614.7225,1474.32,1,1085,0,0,50.1,1 +63,614.7225,1474.32,1,1102,0,0,50.1,1 +63,614.7225,1474.32,0,1125,0,0,50.1,1 +63,614.7225,1474.32,0,1194,0,0,50.1,1 +63,614.7225,1474.32,0,1186,0,0,50.1,1 +63,614.7225,1474.32,0,1217,0,0,50.1,1 +63,614.7225,1474.32,1,1252,0,0,50.1,1 +63,614.7225,1474.32,1,1247,0,0,50.1,1 +63,614.7225,1474.32,1,1266,1,0,50.1,1 +63,614.7225,1474.32,0,1312,0,0,50.1,1 +63,614.7225,1474.32,1,1339,0,0,50.1,1 +63,614.7225,1474.32,1,1337,0,0,50.1,1 +63,614.7225,1474.32,0,1368,0,0,50.1,1 +63,614.7225,1474.32,1,1420,0,0,50.1,1 +63,614.7225,1474.32,0,1459,0,0,50.1,1 +63,614.7225,1474.32,0,1704,0,0,50.1,1 +63,614.7225,1474.32,0,1733,0,0,50.1,1 +64,620.0431,1497.633,1,514,0,0,58.95,0 +64,620.0431,1497.633,1,577,0,0,58.95,0 +64,620.0431,1497.633,1,586,1,0,58.95,0 +64,620.0431,1497.633,1,672,0,0,58.95,0 +64,620.0431,1497.633,1,714,1,0,58.95,0 +64,620.0431,1497.633,1,912,0,0,58.95,0 +64,620.0431,1497.633,1,905,1,0,58.95,0 +64,620.0431,1497.633,1,1156,0,0,58.95,0 +64,620.0431,1497.633,1,1154,0,0,58.95,0 +64,620.0431,1497.633,1,1181,0,0,58.95,0 +64,620.0431,1497.633,1,1216,0,0,58.95,0 +64,620.0431,1497.633,0,1550,0,0,58.95,0 +64,620.0431,1497.633,1,1550,0,0,58.95,0 +65,622.0861,1474.011,0,494,0,0,50.1,1 +65,622.0861,1474.011,0,548,0,0,50.1,1 +65,622.0861,1474.011,0,562,1,0,50.1,1 +65,622.0861,1474.011,1,548,1,0,50.1,1 +65,622.0861,1474.011,1,578,0,0,50.1,1 +65,622.0861,1474.011,0,610,1,0,50.1,1 +65,622.0861,1474.011,1,642,0,0,50.1,1 +65,622.0861,1474.011,1,625,1,0,50.1,1 +65,622.0861,1474.011,0,668,1,0,50.1,1 +65,622.0861,1474.011,1,679,1,0,50.1,1 +65,622.0861,1474.011,0,694,0,0,50.1,1 +65,622.0861,1474.011,0,790,1,0,50.1,1 +65,622.0861,1474.011,1,790,0,0,50.1,1 +65,622.0861,1474.011,1,913,0,0,50.1,1 +65,622.0861,1474.011,0,1125,0,0,50.1,1 +65,622.0861,1474.011,0,1154,0,0,50.1,1 +65,622.0861,1474.011,0,1156,1,0,50.1,1 +65,622.0861,1474.011,1,1217,0,0,50.1,1 +65,622.0861,1474.011,0,1319,0,0,50.1,1 +65,622.0861,1474.011,1,1308,0,0,50.1,1 +65,622.0861,1474.011,0,1399,0,0,50.1,1 +65,622.0861,1474.011,1,1478,0,0,50.1,1 +65,622.0861,1474.011,1,1520,0,0,50.1,1 +65,622.0861,1474.011,1,1546,1,0,50.1,1 +65,622.0861,1474.011,0,1587,1,0,50.1,1 +65,622.0861,1474.011,0,1642,0,0,50.1,1 +65,622.0861,1474.011,1,1705,1,0,50.1,1 +65,622.0861,1474.011,1,1704,1,0,50.1,1 +65,622.0861,1474.011,1,1733,0,0,50.1,1 +65,622.0861,1474.011,0,1825,0,0,50.1,1 +65,622.0861,1474.011,0,1836,1,0,50.1,1 diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/gambia_pred.csv b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/gambia_pred.csv new file mode 100644 index 0000000..207a478 --- /dev/null +++ b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/gambia_pred.csv @@ -0,0 +1,628 @@ +x,y +490.5442017192299,1529.7564600162377 +495.0469640508747,1529.755206960819 +481.5353803458656,1525.153239973835 +486.0389540206155,1525.1504284119558 +490.54252110748587,1525.1483978447172 +495.0460837316073,1525.1471482670581 +499.54964401810093,1525.1466796758643 +504.0532040920833,1525.1469920699676 +508.5567660786697,1525.1480854501465 +513.0603321029803,1525.149959819127 +454.50562160390075,1520.5783580238 +459.0100774469805,1520.5708811617858 +463.51451393284725,1520.5641831902265 +468.01893318877126,1520.5582640924206 +472.5233373419864,1520.5531238536078 +477.0277285196953,1520.5487624609707 +481.532108849072,1520.5451799036337 +486.036480457269,1520.5423761726638 +490.5408454714199,1520.5403512610696 +495.0452060186445,1520.539105163802 +499.5495642260531,1520.5386378777541 +504.05392222075176,1520.5389494017602 +508.55828212984454,1520.5400397365975 +513.0626460804409,1520.5419088849844 +517.5670161996585,1520.5445568515822 +522.0713946146278,1520.5479836429931 +449.9923132111482,1515.9784534459247 +454.4975862010191,1515.9702207506796 +459.0028376863241,1515.9627647874177 +463.5080697963589,1515.9560855375378 +468.0132846603783,1515.950182984377 +472.51848440760074,1515.945057113211 +477.0236711672131,1515.9407079112525 +481.52884706837386,1515.937135367651 +486.0340142402198,1515.9343394734956 +490.5391748118687,1515.9323202218102 +495.0443309124245,1515.9310776075588 +499.54948467098194,1515.9306116276405 +504.0546382166308,1515.9309222808934 +508.55979367845964,1515.9320095680926 +513.064953185562,1515.93387349195 +517.5701188670396,1515.9365140571158 +522.0752928520071,1515.9399312701769 +449.9835084559546,1511.3703085006448 +454.4895747376461,1511.3620988986079 +458.9956194947809,1511.3546638498008 +463.5016448586342,1511.3480033356668 +468.0076529604404,1511.3421173395832 +472.51364593139726,1511.3370058468593 +477.01962590267124,1511.3326688447387 +481.52559500539996,1511.3291063223967 +486.0315553706994,1511.3263182709434 +490.5375091296665,1511.3243046834195 +495.0434584133844,1511.3230655548005 +499.549405352927,1511.3226008819938 +504.055352079363,1511.3229106638391 +508.56130072376027,1511.3239949011104 +513.0672534171913,1511.3258535965128 +517.5732122907369,1511.3284867546856 +522.0791794754912,1511.3318943822005 +544.6092146571597,1511.3605499252096 +449.9747300151145,1506.762178915796 +454.4815872177836,1506.753992424258 +458.9884228759562,1506.7465783055648 +463.4952391228821,1506.7399365412048 +468.00203809177015,1506.7340671145937 +472.5088219157925,1506.728970011077 +477.01559272808987,1506.7246452179281 +481.5223526617743,1506.7210927243486 +486.02910384993555,1506.7183125214685 +490.5358484256451,1506.716304602347 +495.04258852195994,1506.7150689619705 +499.54932627192784,1506.7146055972535 +504.05606380859194,1506.7149145070389 +508.5628032649938,1506.7159956920987 +513.0695467741801,1506.717849155132 +517.5762964692059,1506.7204749007667 +522.0830544831392,1506.7238729355583 +526.5898229490655,1506.728043267991 +531.0966040000928,1506.7329859084778 +535.6033997693551,1506.7387008693593 +540.110212390018,1506.7451881649047 +544.6170439952826,1506.7524478113123 +549.1238967183903,1506.7604798267075 +553.6307726926269,1506.7692842311467 +332.75262262982113,1502.6367553103617 +337.2615787606082,1502.6085541955647 +341.77045778202756,1502.5811244276954 +346.2792618319582,1502.5544659381885 +350.78799304811923,1502.5285786604104 +355.2966535680775,1502.5034625296576 +359.80524552924743,1502.479117483156 +364.3137710689,1502.4555434600607 +368.8222323241646,1502.4327404014562 +373.3306314320349,1502.4107082503563 +377.8389705293716,1502.389446951702 +382.3472517529103,1502.3689564523636 +386.85547723926175,1502.349236701138 +391.3636491249199,1502.33028764875 +395.8717695462648,1502.3121092478523 +400.37984063956736,1502.2947014530234 +404.8878645409939,1502.278064220769 +409.3958433866114,1502.2621975095208 +413.9037793123899,1502.2471012796368 +418.4116744542096,1502.2327754934006 +422.9195309478643,1502.219220115022 +427.42735092906537,1502.2064351106362 +431.9351365334473,1502.1944204483025 +436.4428898965716,1502.1831760980072 +440.9506131539309,1502.1727020316594 +445.4583084409543,1502.1629982230943 +449.965977893013,1502.1540646480707 +454.47362364542124,1502.1459012842734 +458.98124783344434,1502.1385081113087 +463.48885259230167,1502.1318851107105 +467.9964400571716,1502.1260322659334 +472.50401236319544,1502.1209495623584 +477.0115716454831,1502.1166369872892 +481.5191200391158,1502.1130945299533 +486.0266596791526,1502.1103221815024 +490.5341927006337,1502.1083199350112 +495.0417212385853,1502.1070877854788 +499.54924742802405,1502.1066257298276 +504.05677340396215,1502.1069337669026 +508.56430130141007,1502.1080118974744 +513.0718332553836,1502.109860124235 +517.5793714009064,1502.1124784518017 +522.0869178730159,1502.1158668867142 +526.5944748067666,1502.1200254374367 +531.1020443372357,1502.1249541143563 +535.6096285995261,1502.1306529297847 +540.117229728773,1502.1371218979568 +544.6248498601469,1502.1443610350325 +549.1324911288583,1502.1523703590935 +553.6401556701632,1502.1611498901484 +612.2428841639128,1502.3453852362961 +332.7234427975451,1498.0272878369826 +337.23318631234474,1497.9991666723822 +341.7428526467887,1497.9718146682926 +346.2524439407278,1497.9452317563148 +350.7619623338516,1497.9194178699752 +355.27140996569756,1497.8943729447253 +359.78078897565035,1497.8700969179424 +364.2901015029504,1497.8465897289282 +368.79934968669653,1497.8238513189092 +373.3085356658514,1497.8018816310357 +377.81766157924443,1497.7806806103818 +382.3267295655794,1497.7602482039447 +386.8357417634352,1497.7405843606455 +391.34470031127336,1497.7216890313277 +395.8536073474414,1497.7035621687573 +400.3624650101774,1497.6862037276223 +404.87127543761466,1497.6696136645332 +409.38004076778634,1497.6537919380214 +413.8887631386292,1497.6387385085407 +418.39744468798955,1497.6244533384659 +422.90608755362695,1497.6109363920918 +427.4146938732186,1497.5981876356357 +431.9232657843643,1497.5862070372345 +436.431805424591,1497.5749945669454 +440.9403149313564,1497.5645501967458 +445.4487964420547,1497.554873900534 +449.9572520940217,1497.5459656541268 +454.4656840245365,1497.5378254352627 +458.9740943708288,1497.530453223598 +463.4824852700826,1497.523849000709 +467.9908588594403,1497.5180127500926 +472.49921727600776,1497.5129444571635 +477.00756265685885,1497.508644109256 +481.5158971390389,1497.505111695624 +490.53254195545907,1497.5003506377966 +495.0408565636936,1497.4991219817036 +499.549168821255,1497.4986612360906 +504.0574808651194,1497.4989683998072 +508.565794832261,1497.50004347362 +513.0741128596596,1497.5018864602157 +517.582437084303,1497.5044973642005 +522.0907696431923,1497.5078761920977 +526.5991126733461,1497.512022952352 +531.1074683118056,1497.5169376553247 +535.6158386956379,1497.5226203132986 +540.1242259619422,1497.5290709404737 +544.6326322478535,1497.536289552971 +549.1410596905471,1497.5442761688294 +553.6495104272426,1497.553030808008 +558.1579865952101,1497.5625534923859 +589.7182113897072,1497.6507197895944 +594.2269679569808,1497.6663878535978 +598.7357691939254,1497.6828242461154 +603.2446172385543,1497.7000290082317 +607.7535142289803,1497.7180021829515 +612.2624623034203,1497.7367438152028 +616.7714636001996,1497.7562539518344 +621.2805202577558,1497.776532641619 +319.1622805015059,1493.5065605912018 +332.6943510001077,1493.4178345798305 +337.20487952377147,1493.389793424705 +341.7153307962761,1493.3625192420507 +346.2257069594378,1493.336011963632 +350.7360101549125,1493.3102715231369 +355.2462425242028,1493.2852978561737 +359.75640620865823,1493.2610909002703 +364.26650334948397,1493.2376505948755 +368.776536087743,1493.2149768813574 +373.28650656436196,1493.1930697030048 +377.79641692013365,1493.1719290050232 +382.3062692957253,1493.1515547345396 +386.81606583167866,1493.1319468405973 +391.3258086684177,1493.113105274159 +395.8354999462526,1493.0950299881051 +400.3451418053831,1493.0777209372334 +404.85473638590435,1493.0611780782588 +409.3642858278112,1493.0454013698136 +413.8737922710016,1493.0303907724467 +418.38325785528286,1493.0161462486242 +422.8926847203753,1493.0026677627268 +427.4020750059168,1492.9899552810543 +431.91143085146757,1492.9780087718195 +436.42075439651484,1492.9668282051532 +440.9300477804762,1492.9564135531 +445.43931314270577,1492.946764789621 +449.94855262249916,1492.937881890593 +454.45776835909487,1492.9297648338058 +458.96696249168224,1492.9224135989673 +463.4761371594046,1492.915828167697 +467.98529450136346,1492.9100085235325 +472.4944366566239,1492.9049546519232 +477.00356576421893,1492.9006665402342 +495.0399944977165,1492.8911715069926 +499.54909045165994,1492.8907120723886 +504.0581861917103,1492.891018362099 +508.567283856801,1492.8920903768894 +513.0763855858703,1492.893928119439 +517.5854935178651,1492.896531594343 +522.094609791745,1492.8999008081096 +526.6037365464879,1492.9040357691622 +531.1128759210939,1492.908936487838 +535.6220300545889,1492.9146029763892 +540.1312010860316,1492.921035248982 +544.640391154516,1492.9282333216981 +549.1496023991765,1492.936197212533 +553.6588369591925,1492.9449269413976 +558.1680969737937,1492.9544225301179 +562.6773845822623,1492.964684002434 +585.2243114118977,1493.027480582966 +589.7338095121244,1493.0423379626825 +594.243350183099,1493.0579614458175 +598.752935564701,1493.074351071438 +603.2625677969053,1493.0915068805293 +607.7722490197867,1493.1094289159917 +612.2819813735238,1493.1281172226443 +616.7917669984042,1493.147571847224 +621.3016080348283,1493.167792838385 +625.8115066233149,1493.188780246698 +314.6192865249657,1488.927889101128 +319.1309284102017,1488.8968681643146 +323.64248439685576,1488.86661230176 +328.15395662939295,1488.8371214377246 +332.66534725209715,1488.8083954983883 +337.17665840908023,1488.7804344118479 +341.68789224428434,1488.7532381081178 +346.19905090148706,1488.7268065191292 +350.7101365243046,1488.7011395787315 +355.22115125619973,1488.6762372226876 +359.73209724048223,1488.652099388679 +364.2429766203165,1488.6287260163006 +368.7537915387249,1488.606117047063 +373.26454413859267,1488.5842724243928 +377.77523656267107,1488.5631920936296 +382.2858709535856,1488.5428760020277 +386.79644945383546,1488.523324098755 +391.3069742058027,1488.5045363348927 +395.81744735175414,1488.4865126634363 +400.3278710338468,1488.4692530392927 +404.83824739413245,1488.4527574192825 +409.3485785745623,1488.4370257621385 +413.85886671699035,1488.4220580285057 +418.3691139631801,1488.4078541809404 +422.8793224548073,1488.3944141839113 +427.3894943334657,1488.3817380037992 +431.89963174067054,1488.369825608894 +436.4097368178642,1488.3586769693993 +440.91981170641924,1488.3482920574281 +445.4298585476446,1488.3386708470043 +449.93987948279045,1488.3298133140627 +454.44987665304984,1488.3217194364493 +458.9598521995665,1488.3143891939185 +463.4698082634378,1488.3078225681365 +467.9797469857197,1488.3020195426793 +472.4896705074311,1488.296980103033 +476.99958096955896,1488.2927042365934 +504.05888938338285,1488.283083610091 +508.5687683742865,1488.2841525636006 +513.0786514328807,1488.285985058234 +517.5885407000662,1488.288581098575 +522.0984383167565,1488.2919406911153 +526.6083464238832,1488.2960638442587 +531.1182671624002,1488.3009505683162 +535.6282026732875,1488.3066008755113 +540.1381550975578,1488.3130147799754 +544.648126576259,1488.3201922977503 +549.1581192504799,1488.3281334467893 +553.6681352613543,1488.336838246954 +558.1781767500662,1488.3463067200173 +562.6882458578526,1488.3565388896618 +567.1983447260105,1488.3675347814822 +571.7084754959001,1488.3792944229822 +576.2186403089488,1488.3918178435777 +580.7288413066574,1488.405105074595 +585.2390806306034,1488.4191561492717 +589.7493604224456,1488.4339711027567 +594.2596828239296,1488.4495499721113 +598.7700499768913,1488.465892796308 +603.2804640232615,1488.4829996162316 +607.7909271050722,1488.5008704746797 +612.3014413644585,1488.5195054163612 +616.8120089436652,1488.5389044878996 +621.3226319850503,1488.559067737831 +625.8333126310902,1488.579995216603 +630.344053024384,1488.6016869765801 +310.0747385005506,1484.3498167306766 +314.587249067924,1484.3181217285062 +319.0996715118482,1484.2871896860756 +323.6120079789269,1484.257020525917 +328.1242606155828,1484.2276141724758 +337.14852298241925,1484.1710895930973 +341.66053700456655,1484.1439712256179 +346.172475780233,1484.117615381771 +350.68434145499043,1484.0920219955663 +355.1961361742568,1484.0671910029253 +359.7078620832964,1484.0431223416797 +364.2195213272283,1484.0198159515735 +368.7311160510286,1483.9972717742598 +373.2426483995363,1483.9754897533026 +377.7541205174561,1483.9544698341756 +382.26553454936635,1483.9342119642615 +386.7768926397192,1483.9147160928521 +391.2881969328489,1483.8959821711492 +395.7994495729744,1483.8780101522616 +400.31065270420464,1483.8607999912072 +404.82180847054275,1483.8443516449117 +409.33291901589155,1483.8286650722089 +413.84398648405585,1483.8137402338393 +418.3550130187501,1483.799577092451 +422.8660007636007,1483.7861756126003 +427.3769518621515,1483.7735357607485 +431.88786845786825,1483.7616575052643 +436.39875269414324,1483.750540816423 +440.90960671429883,1483.7401856664064 +445.4204326615937,1483.7305920293018 +449.9312326792275,1483.7217598811023 +454.4420089103427,1483.713689199708 +458.9527634980323,1483.7063799649236 +463.4634985853428,1483.6998321584592 +467.97421631527914,1483.694045763931 +472.48491883080914,1483.689020766861 +476.99560827486874,1483.684757154675 +517.5915786293854,1483.6806458332123 +522.1022552163155,1483.6839957974516 +526.6129423032302,1483.6881071340017 +531.1236420330326,1483.6929798531505 +535.6343565486512,1483.6986139670894 +540.1450879930478,1483.7050094899166 +544.6558385092193,1483.712166437635 +549.1666102402035,1483.720084828153 +553.6774053290835,1483.7287646812842 +558.1882259189927,1483.7382060187483 +562.6990741531175,1483.7484088641706 +567.2099521747047,1483.7593732430823 +571.7208621270638,1483.7710991829208 +576.231806153573,1483.7835867130298 +580.7427863976827,1483.796835864659 +585.2538050029209,1483.8108466709648 +589.7648641128969,1483.825619167011 +594.2759658713071,1483.8411533897674 +598.7871124219384,1483.857449378112 +603.2983059086733,1483.87450717283 +607.8095484754945,1483.8923268166134 +612.3208422664894,1483.910908354063 +616.8321894258548,1483.930251831688 +621.343592097901,1483.950357297906 +625.855052427057,1483.971224803042 +630.3665725578749,1483.9928543993326 +305.5286411865415,1479.7723367419753 +310.0420203676958,1479.7399720480553 +314.5553091966432,1479.708368199275 +319.0685098221302,1479.6775251164452 +323.5816243927133,1479.6474427222886 +328.09465505676826,1479.6181209414362 +337.1204732578933,1479.561758927711 +341.6332650908333,1479.5347185536434 +346.14598160899266,1479.508438510489 +350.6586249598934,1479.4829187324194 +355.1711972909037,1479.4581591555125 +359.6837007492376,1479.4341597177543 +364.1961374819629,1479.4109203590347 +368.70850963600515,1479.388441021151 +373.2208193581517,1479.3667216478052 +377.7330687950555,1479.345762184605 +382.24526009324285,1479.3255625790616 +386.75739539911325,1479.3061227805922 +391.26947685894834,1479.2874427405175 +395.7815066189142,1479.2695224120619 +400.29348682506634,1479.2523617503532 +404.80541962335445,1479.235960712423 +409.3173071596273,1479.2203192572058 +413.8291515796359,1479.205437345539 +418.34095502904023,1479.1913149401623 +422.8527196534123,1479.1779520057178 +427.36444759824127,1479.1653485087502 +431.87614100893774,1479.1535044177058 +436.3878020308392,1479.1424197029326 +440.8994328092126,1479.1320943366807 +445.41103548926117,1479.1225282931005 +449.92261221612904,1479.1137215482447 +454.4341651349028,1479.1056740800675 +458.94569639061973,1479.0983858684224 +463.4572081282703,1479.0918568950658 +467.96870249280335,1479.086087143653 +472.48018162913064,1479.0810765997414 +526.6175241822342,1479.080165594722 +531.129000530307,1479.0850242986994 +535.6404916776072,1479.0906422075172 +540.1519997690395,1479.0970193352384 +544.6635269495454,1479.104155697827 +549.1750753641064,1479.1120513131473 +553.6866471577498,1479.1207062009644 +558.1982444755531,1479.1301203829444 +562.7098694626475,1479.1402938826552 +567.2215242642236,1479.1512267255648 +571.7332110255365,1479.1629189390435 +576.24493189190855,1479.1753705523631 +580.7566890087354,1479.1885815966968 +585.2684845214904,1479.2025521051191 +589.7803205757283,1479.217282112608 +594.2921993170909,1479.232771656043 +598.8041228913113,1479.2490207742062 +603.3160934442179,1479.2660295077828 +607.8281131217401,1479.28379789936 +612.3401840699116,1479.30232599343 +616.8523084348765,1479.3216138363869 +621.364488362892,1479.3416614765297 +625.8767260003347,1479.3624689640606 +630.3890234937046,1479.3840363510867 +305.49524706761713,1475.1624123806057 +310.00940221436366,1475.1301411023069 +314.5234669271546,1475.0986284735545 +319.03744335668443,1475.0678744153568 +323.5513336534578,1475.0378788506246 +328.06513996779756,1475.0086417041762 +337.09250924956405,1474.9524423749156 +341.60607651675326,1474.9254800512567 +346.1195684010418,1474.8992758641864 +350.632987051897,1474.8738297480377 +355.14633461863184,1474.8491416390475 +359.65961325040485,1474.8252114753534 +368.68597230497113,1474.7796247459091 +373.19905702536437,1474.7579680659412 +377.7120814060038,1474.7370691028304 +382.22504759535855,1474.7169278042186 +386.73795774177086,1474.6975441196473 +391.2508139934642,1474.6789180005565 +395.7636184985465,1474.6610494002862 +400.2763734050151,1474.6439382740753 +404.78908086076075,1474.6275845790612 +409.30174301357357,1474.6119882742796 +413.81436201114514,1474.597149320664 +418.32694000107614,1474.583067681046 +422.83947913087894,1474.5697433201558 +427.35198154798275,1474.5571762046197 +431.8644493997383,1474.5453663029618 +436.3768848334227,1474.534313585604 +440.8892899962426,1474.5240180248634 +458.93865088085784,1474.4904068608241 +463.4509368953614,1474.4838967343248 +531.1343426515482,1474.4770838612906 +535.6466080570917,1474.4826855531553 +540.1588904220816,1474.4890442723408 +544.6711918933978,1474.49616003477 +549.183514617961,1474.5040328582636 +553.6958607427374,1474.5126627625382 +558.2082324147435,1474.5220497692071 +562.7206317810497,1474.5321939017786 +567.2330609887866,1474.5430951856597 +571.7455221851479,1474.5547536481517 +576.2580175173966,1474.5671693184545 +580.7705491328677,1474.5803422276651 +585.283119178975,1474.5942724087765 +589.7957298032134,1474.60895989668 +594.3083831531652,1474.6244047281639 +598.8210813765044,1474.640606941915 +603.3338266210004,1474.6575665785183 +607.8466210345237,1474.6752836804562 +612.3594667650499,1474.6937582921112 +616.8723659606644,1474.7129904597623 +621.3853207695668,1474.73298023159 +625.8983333400762,1474.7537276576732 +305.46195532293183,1470.5525016483425 +309.9768840569302,1470.520323853714 +314.4917222754401,1470.488902511436 +319.00647213109954,1470.4582375427121 +323.52113577635566,1470.4283288706442 +328.0357153634736,1470.399176420237 +332.55021304453567,1470.3707801183912 +337.0646309714498,1470.3431398939097 +341.5789712959528,1470.316255677492 +355.1215481698939,1470.2401384120974 +359.6355995988606,1470.2162775728982 +364.1495841816962,1470.1931724237306 +368.66350406920805,1470.170822906678 +373.1773614120657,1470.1492289657212 +377.6911583608028,1470.1283905467358 +382.2048970658262,1470.1083075974927 +386.7185796774152,1470.0889800676584 +391.2322083457305,1470.0704079087939 +395.7457852208168,1470.052591074354 +400.2593124526076,1470.0355295196887 +404.7727921909302,1470.0192232020413 +409.28622658551035,1470.0036720805492 +413.79961778597556,1469.9888761162429 +549.1919279975526,1469.8960294199628 +553.7050460794445,1469.9046343225198 +558.2181897315749,1469.9139941341066 +562.7313611029484,1469.9241088781744 +567.2445623426298,1469.9349785800655 +571.7577955997474,1469.9466032670152 +576.2710630234985,1469.9589829681504 +580.7843667631533,1469.9721177144909 +585.2977089680604,1469.9860075389477 +589.8110917876497,1470.0006524763269 +594.3245173714395,1470.0160525633248 +598.8379878690388,1470.0322078385323 +603.3515054301531,1470.0491183424342 +607.8650722045892,1470.0667841174077 +612.3786903422587,1470.0852052077246 +305.42876596920354,1465.942604505639 +309.9444659117204,1465.910520262533 +314.4600752574325,1465.879190272983 +318.9755961609159,1465.8486144583867 +323.49103077655553,1465.81879274204 +328.00638125855346,1465.789725049132 +332.5216497609287,1465.7614113067468 +337.0368384375255,1465.7338514438632 +341.55194944201634,1465.707045391354 +346.06698492790724,1465.6809930819854 +350.5819470485408,1465.6556944504173 +355.09683795710424,1465.6311494332008 +359.61165980662963,1465.6073579687813 +364.1264147500021,1465.5843199974952 +368.64110493996276,1465.5620354615705 +373.15573252911383,1465.540504305127 +377.6702996699221,1465.5197264741741 +382.1848085147268,1465.4997019166146 +386.69926121573945,1465.4804305822383 +391.2136599250527,1465.4619124227281 +395.7280067946427,1465.4441473916538 +400.2423039763743,1465.4271354444772 +404.75655362200575,1465.4108765385479 +409.27075788319365,1465.395370633105 +413.7849189114961,1465.3806176892754 +562.7420574229837,1465.3160387684434 +567.2560283200075,1465.326876865451 +571.7700312632027,1465.338467752374 +576.284068403696,1465.3508114582662 +580.7981418926875,1465.36390801407 +585.312253881455,1465.3777574526152 +589.8264065213592,1465.3923598086203 +594.3406019638481,1465.4077151186916 +305.3956790230984,1461.332720912919 +309.91214779500865,1461.3007302889905 +314.42852588901485,1461.2694917182284 +318.9448154616258,1461.2390051222271 +323.461018669159,1461.209270424474 +327.97713766774837,1461.180287550345 +332.4931746133446,1461.1520564271066 +337.00913166172273,1461.1245769839156 +341.5250109684861,1461.0978491518174 +346.04081468907094,1461.0718728637462 +350.55654497874946,1461.0466480545253 +355.0722039926387,1461.022174660865 +359.58779388569945,1460.9984526213643 +364.1033168127456,1460.9754818765082 +368.6187749284467,1460.9532623686698 +373.1341703873329,1460.9317940421079 +377.6495053437988,1460.9110768429687 +382.1647819521104,1460.8911107192828 +386.68000236640694,1460.8718956209677 +391.1951687407073,1460.8534314998258 +395.71028322891414,1460.8357183095438 +400.2253479848188,1460.8187560056945 +404.74036516210515,1460.802544545734 +409.2553369143553,1460.7870838890035 +413.770265395053,1460.772373996728 +580.8118745145861,1460.7557130832665 +585.3267539118896,1460.7695221067277 +589.8416739966867,1460.7840818505995 +594.3566369223505,1460.7993923513975 +305.362694501231,1456.7228508305807 +309.879929723019,1456.690953893287 +314.39707418602086,1456.6598068071798 +318.91413004867326,1456.6294094940522 +323.4310994692207,1456.5997618775812 +327.94798460572395,1456.5708638833319 +332.4647876160599,1456.542715438753 +336.9815106579297,1456.5153164731796 +341.4981558888621,1456.4886669178297 +346.0147254662184,1456.462766705807 +350.53122154719557,1456.4376157720974 +355.0476462888345,1456.413214053571 +359.5640018480204,1456.3895614889807 +364.0802903814903,1456.3666580189613 +368.596514045837,1456.3445035860304 +373.1126749975136,1456.3230981345876 +377.628775392837,1456.302441610913 +382.1448173879958,1456.2825339631695 +386.66080313905036,1456.2633751413991 +391.17673480194185,1456.2449650975261 +395.69261453249385,1456.2273037853536 +400.20844448641856,1456.2103911605655 +404.7242268193208,1456.194227180725 +409.2399636867033,1456.1788118052755 +413.75565724396967,1456.164144995539 +305.3298124201634,1452.1129942189918 +309.84781171192463,1452.0811910355926 +314.3657201642352,1452.0501354998155 +305.29703279640665,1447.5031510384936 +309.8157937778482,1447.471441676051 diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/semis_xy.csv b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/semis_xy.csv new file mode 100644 index 0000000..a2b9033 --- /dev/null +++ b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/data/semis_xy.csv @@ -0,0 +1,282 @@ +x,y,sp +14.73,0.05,P +14.72,1.71,P +14.31,2.06,P +14.16,2.64,P +14.12,4.15,B +9.88,4.08,B +13.99,4.63,B +10.64,2.37,P +12.48,2.45,P +13.77,4.55,P +12.42,1.84,P +13.48,2.01,P +13.26,4.17,P +13.12,4.93,B +13.7,2.05,P +13.49,2.23,P +13.92,1.56,B +14.1,1.66,P +13.29,0.62,P +13.98,1.29,P +13.16,0.65,P +13.09,0.51,P +13.42,0.9,P +13.29,1.41,P +13.57,1.92,B +13.08,3.43,P +12.06,1.72,P +12.43,0.41,P +12.16,1.66,P +13.52,0.66,P +12.55,0.18,P +12.83,4.62,B +12.8,3.78,B +11.66,1.85,B +11.33,0.74,P +11.58,1.09,P +12.11,2.67,P +11.97,2.93,P +12,2.85,P +12.71,3.02,P +12.56,2.86,P +12.88,2.95,P +12.03,3.87,P +12.09,4.87,P +10.74,0.72,P +10.86,0.57,P +11.09,0,P +10.55,0.07,P +10.78,0.19,P +10.82,0.16,P +10.76,0.03,P +10.46,1,P +10.75,1.06,P +10.09,0.6,P +10.13,0.38,B +11.27,1.92,P +9.98,2.33,P +10.86,1.41,P +12.18,2.3,P +11.22,2.22,P +11.76,2.36,P +11.36,2.47,P +10.17,2.78,P +11.19,2.09,B +11.69,2.01,P +11.13,3.4,B +12.71,1.9,P +9.1,2.3,P +9.33,1.62,P +8.4,1.76,B +9.17,0.16,P +8.03,1.71,B +8.32,1.06,B +8.18,1.65,B +9.62,1.9,P +9.4,3.41,B +9.59,2.77,B +6.73,2.15,B +9.49,4.75,B +9.36,4.57,B +7.56,4.06,B +9.78,3.36,B +8.95,4.07,B +6.87,1.67,B +5.48,4.03,B +6.48,0.91,B +6.53,1.93,B +6.04,0.96,P +5.97,1.26,B +5.63,3.7,B +5.86,3.59,P +5.15,2.36,B +5.99,2.56,B +5.46,2.75,B +5.6,2.53,P +6.13,2.78,B +5.62,3.2,B +6.48,1.62,B +6.74,0.13,B +3.42,0.84,P +3.29,0.06,P +3.98,1.07,B +3.39,0.69,B +3.02,1.07,P +3.46,1.09,P +4.41,0.6,P +0.34,3.03,B +1.04,3.3,B +0.13,2.62,B +1.96,4.93,P +0.93,4.99,P +0.25,3.32,P +1.07,1.59,B +4.73,1.6,P +4.48,4.17,B +3.64,1.86,B +4.89,1.73,P +4.67,2.57,B +2.49,0.96,B +2.64,2.88,P +2.64,4.13,P +2.1,3.13,B +2.24,4.38,B +1.98,4.58,P +0.23,4.16,P +1.84,1.76,B +0.94,3.08,B +0.89,3.01,P +3.44,2.15,B +12.83,6.01,B +10.11,5.82,P +14,5.1,P +13.71,5.93,P +11.77,5.42,P +14,5.19,B +14.17,5.58,B +10.68,5.47,P +13.84,6.4,B +14.83,7.5,B +14.06,6.46,B +13.4,6.07,P +14.69,5.58,B +10.79,5.97,P +14.69,6.22,B +14.56,9.67,B +14.22,9.09,P +11.4,6.22,B +11.9,6.28,P +14.07,8.47,P +14.46,8.65,B +12.97,6.8,B +13.58,7.13,B +11.88,9.82,P +10.07,9,P +10.95,9.43,B +12.98,6.14,P +11.54,8.05,B +10.32,8.43,B +12.6,9.29,B +12.47,6.58,B +10.09,7.39,B +12.83,4.99,P +11.25,8.68,P +11.92,6.09,B +14,8.59,P +13.57,9.81,B +14.52,8.31,P +12.75,6.13,B +13.59,6.16,B +9.42,7.15,B +8.58,7.71,B +8.18,8.49,B +8.33,5.73,P +8.11,5.93,B +9.82,9.77,P +8.47,9.01,B +7.96,7.46,B +5.18,5.72,B +7.69,7.58,B +8.43,5.07,B +5.9,8.46,B +6.95,5.72,B +5.46,7.78,B +6.21,9.86,B +6.65,9.74,B +5.7,9.63,B +7.12,6.96,B +6.12,8.95,B +5.47,10.04,B +6.66,8.89,B +7.07,9.71,B +4.41,9.84,B +3.25,6.82,B +3.2,5.79,B +3.9,7.25,P +1.82,5.59,B +3.69,9.07,P +4.6,9.66,P +4.7,5.64,B +2.73,5.39,B +2.32,5.6,B +2.15,5.96,B +2.48,6.73,B +1.71,9.96,B +0.33,6.21,P +4.83,7.41,P +1.76,10,P +2.33,8.28,P +1.87,8.2,B +2.63,8.73,B +3.17,9.9,B +2.2,7.5,B +1.09,9.94,B +2.79,5.28,B +13.22,11.66,P +12.86,14.59,P +11.95,13.17,B +10.65,13.46,B +13.58,12.12,P +12.06,10.15,B +11.37,10.85,B +12.1,10.62,B +12.67,14.8,P +13.62,12.49,B +13.77,13.99,B +14.54,11.18,P +11.11,14.61,B +10.76,12.67,B +10.2,13.13,B +11.27,11.67,B +12.13,12.01,B +12.09,13.28,B +9.84,11.19,B +10.61,11.6,P +11.1,11.74,B +10.62,12.61,P +14.89,13.27,B +13.95,12.39,P +11.49,10.72,B +11.96,13.31,B +9.82,13.01,B +8.91,11.71,P +5.6,10.74,B +9.55,13.29,P +8.93,13.61,B +9.43,14.52,B +9.53,11.2,B +5.42,12.14,B +4.97,13.54,P +8.41,12.28,B +4.92,13.27,P +9.65,14.87,P +3.87,13.44,P +4.47,11.18,P +1.11,11.4,B +2.95,11.51,B +3.39,13.58,B +2.31,12.52,B +4.47,13.46,P +4.56,13.32,P +3.48,11.42,P +2.81,10.37,B +3.17,10.56,B +3.87,10.38,B +4.2,11.81,B +4.69,11.1,P +1.37,14.25,B +0.1,13.6,B +0.14,14.74,B +0.29,12.94,P +2.5,11.55,P +3.41,11.4,P +0.35,11.56,P +0.46,13.32,P +0.28,12.82,B +4.58,12.47,B +0.82,13.16,P +3.45,11.42,P +0,12.15,B +0.24,12.82,P +3.92,14.52,P diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/image.jpg b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/image.jpg new file mode 100644 index 0000000..3e2d4e2 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/image.jpg differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/images/cartes_unites.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/images/cartes_unites.png new file mode 100644 index 0000000..eaff8fe Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/images/cartes_unites.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/images/ripley_edge.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/images/ripley_edge.png new file mode 100644 index 0000000..f162581 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/images/ripley_edge.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html new file mode 100644 index 0000000..361e6e1 --- /dev/null +++ b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html @@ -0,0 +1,4071 @@ + + + + + + + + + + + + +BIOS2 Education resources - 4-Day Training in Spatial Statistics with Philippe Marchand + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

4-Day Training in Spatial Statistics with Philippe Marchand

+
+
+

Training session about statistical analysis of spatial data in ecology, hosted by Philippe Marchand (UQAT). | Session de formation sur l’analyse statistique des données spatiales en écologie, animée par Pr. Philippe Marchand (UQAT).

+
+
+
+
FR
+
EN
+
Technical
+
+
+
+ + +
+ +
+
Author
+
+

Philippe Marchand

+
+
+ +
+
Published
+
+

January 12, 2021

+
+
+ + +
+ + +
+ + + + +
+ + + + +

Version en français à la suite.

+
+

1 Spatial statistics in ecology

+

BIOS² hosted an online training session about statistical analysis of spatial data in ecology, led by Pr. Philippe Marchand (UQAT). This 12-hour training was conducted in 4 sessions: January 12, 14, 19 & 21 (2021) from 1:00 to 4:00 pm EST.

+

The content included three types of spatial statistical analyses and their applications to ecology: (1) point pattern analysis to study the distribution of individuals or events in space; (2) geostatistical models to represent the spatial correlation of variables sampled at geolocated points; and (3) areal data models, which apply to measurements taken on areas in space and model spatial relationships as networks of neighbouring regions. The training also included practical exercises using the R statistical programming environment.

+

Philippe Marchand is a professor in ecology and biostatistics at Institut de recherche sur les forêts, Université du Québec en Abitibi-Témiscamingue (UQAT) and BIOS² academic member. His research focuses on modeling processes that influence the spatial distribution of populations, including: seed dispersal and seedling establishment, animal movement, and the spread of forest diseases.

+

If you wish to consult the lesson materials and follow the exercises at your own pace, you can access them through this link. Basic knowledge of linear regression models and experience fitting them in R is recommended. Original repository can be found here.

+
+

Course outline

+ + + + + + + + + + + + + + + + + + + + + + + + + +
DayTopics (EN)
1Introduction to spatial statistics
Point pattern analysis
2Spatial correlation
Geostatistical models
3Areal data
Moran’s I
Spatial autoregression models
Analysis of areal data in R
4GLMM with spatial Gaussian process
GLMM with spatial autoregression
+
+
+
+

2 Introduction to spatial statistics

+
+

Types of spatial analyses

+

In this training, we will discuss three types of spatial analyses: point pattern analysis, geostatistical models and models for areal data.

+

In point pattern analysis, we have point data representing the position of individuals or events in a study area and we assume that all individuals or events have been identified in that area. That analysis focuses on the distribution of the positions of the points themselves. Here are some typical questions for the analysis of point patterns:

+
    +
  • Are the points randomly arranged or clustered?

  • +
  • Are two types of points arranged independently?

  • +
+

Geostatistical models represent the spatial distribution of continuous variables that are measured at certain sampling points. They assume that measurements of those variables at different points are correlated as a function of the distance between the points. Applications of geostatistical models include the smoothing of spatial data (e.g., producing a map of a variable over an entire region based on point measurements) and the prediction of those variables for non-sampled points.

+

Areal data are measurements taken not at points, but for regions of space represented by polygons (e.g. administrative divisions, grid cells). Models representing these types of data define a network linking each region to its neighbours and include correlations in the variable of interest between neighbouring regions.

+
+
+

Stationarity and isotropy

+

Several spatial analyses assume that the variables are stationary in space. As with stationarity in the time domain, this property means that summary statistics (mean, variance and correlations between measures of a variable) do not vary with translation in space. For example, the spatial correlation between two points may depend on the distance between them, but not on their absolute position.

+

In particular, there cannot be a large-scale trend (often called gradient in a spatial context), or this trend must be taken into account before modelling the spatial correlation of residuals.

+

In the case of point pattern analysis, stationarity (also called homogeneity) means that point density does not follow a large-scale trend.

+

In a isotropic statistical model, the spatial correlations between measurements at two points depend only on the distance between the points, not on the direction. In this case, the summary statistics do not change under a spatial rotation of the data.

+
+
+

Georeferenced data

+

Environmental studies increasingly use data from geospatial data sources, i.e. variables measured over a large part of the globe (e.g. climate, remote sensing). The processing of these data requires concepts related to Geographic Information Systems (GIS), which are not covered in this workshop, where we focus on the statistical aspects of spatially varying data.

+

The use of geospatial data does not necessarily mean that spatial statistics are required. For example, we will often extract values of geographic variables at study points to explain a biological response observed in the field. In this case, the use of spatial statistics is only necessary when there is a spatial correlation in the residuals, after controlling for the effect of the predictors.

+
+
+
+

3 Point pattern analysis

+
+

Point pattern and point process

+

A point pattern describes the spatial position (most often in 2D) of individuals or events, represented by points, in a given study area, often called the observation “window”.

+

It is assumed that each point has a negligible spatial extent relative to the distances between the points. More complex methods exist to deal with spatial patterns of objects that have a non-negligible width, but this topic is beyond the scope of this workshop.

+

A point process is a statistical model that can be used to simulate point patterns or explain an observed point pattern.

+
+
+

Complete spatial randomness

+

Complete spatial randomness (CSR) is one of the simplest point patterns, which serves as a null model for evaluating the characteristics of real point patterns. In this pattern, the presence of a point at a given position is independent of the presence of points in a neighbourhood.

+

The process creating this pattern is a homogeneous Poisson process. According to this model, the number of points in any area \(A\) follows a Poisson distribution: \(N(A) \sim \text{Pois}(\lambda A)\), where \(\lambda\) is the intensity of the process (i.e. the density of points per unit area). \(N\) is independent between two disjoint regions, no matter how those regions are defined.

+

In the graph below, only the pattern on the right is completely random. The pattern on the left shows point aggregation (higher probability of observing a point close to another point), while the pattern in the center shows repulsion (low probability of observing a point very close to another).

+
+
+

+
+
+
+
+

Exploratory or inferential analysis for a point pattern

+

Several summary statistics are used to describe the characteristics of a point pattern. The simplest is the intensity \(\lambda\), which as mentioned above represents the density of points per unit area. If the point pattern is heterogeneous, the intensity is not constant, but depends on the position: \(\lambda(x, y)\).

+

Compared to intensity, which is a first-order statistic, second-order statistics describe how the probability of the presence of a point in a region depends on the presence of other points. The Ripley’s \(K\) function presented in the next section is an example of a second-order summary statistic.

+

Statistical inferences on point patterns usually consist of testing the hypothesis that the point pattern corresponds to a given null model, such as CSR or a more complex null model. Even for the simplest null models, we rarely know the theoretical distribution for a summary statistic of the point pattern under the null model. Hypothesis tests on point patterns are therefore performed by simulation: a large number of point patterns are simulated from the null model and the distribution of the summary statistics of interest for these simulations is compared to their values for the observed point pattern.

+
+
+

Ripley’s K function

+

Ripley’s K function \(K(r)\) is defined as the mean number of points within a circle of radius \(r\) around a point in the pattern, standardized by the intensity \(\lambda\).

+

Under the CSR null model, the mean number of points in any circle of radius \(r\) is \(\lambda \pi r^2\), thus in theory \(K(r) = \pi r^2\) for that model. A higher value of \(K(r)\) means that there is an aggregation of points at the scale \(r\), whereas a lower value means that there is repulsion.

+

In practice, \(K(r)\) is estimated for a specific point pattern by the equation:

+

\[ K(r) = \frac{A}{n(n-1)} \sum_i \sum_{j > i} I \left( d_{ij} \le r \right) w_{ij}\]

+

where \(A\) is the area of the observation window and \(n\) is the number of points in the pattern, so \(n(n-1)\) is the number of distinct pairs of points. We take the sum for all pairs of points of the indicator function \(I\), which takes a value of 1 if the distance between points \(i\) and \(j\) is less than or equal to \(r\). Finally, the term \(w_{ij}\) is used to give extra weight to certain pairs of points to account for edge effects, as discussed in the next section.

+

For example, the graphs below show the estimated \(K(r)\) function for the patterns shown above, for values of \(r\) up to 1/4 of the window width. The red dashed curve shows the theoretical value for CSR and the gray area is an “envelope” produced by 99 simulations of that null pattern. The aggregated pattern shows an excess of neighbours up to \(r = 0.25\) and the pattern with repulsion shows a significant deficit of neighbours for small values of \(r\).

+
+
+

+
+
+

In addition to \(K\), there are other statistics to describe the second-order properties of point patterns, such as the mean distance between a point and its nearest \(N\) neighbours. You can refer to the Wiegand and Moloney (2013) textbook in the references to learn more about different summary statistics for point patterns.

+
+
+

Edge effects

+

In the context of point pattern analysis, edge effects are due to the fact that we have incomplete knowledge of the neighbourhood of points near the edge of the observation window, which can induce a bias in the calculation of statistics such as Ripley’s \(K\).

+

Different methods have been developed to correct the bias due to edge effects. In Ripley’s edge correction method, the contribution of a neighbour \(j\) located at a distance \(r\) from a point \(i\) receives a weight \(w_{ij} = 1/\phi_i(r)\), where \(\phi_i(r)\) is the fraction of the circle of radius \(r\) around \(i\) contained in the observation window. For example, if 2/3 of the circle is in the window, this neighbour counts as 3/2 neighbours in the calculation of a statistic like \(K\).

+

+

Ripley’s method is one of the simplest to correct for edge effects, but is not necessarily the most efficient; in particular, larger weights given to certain pairs of points tend to increase the variance of the calculated statistic. Other correction methods are presented in specialized textbooks, such as Wiegand and Moloney (2013).

+
+
+

Example

+

For this example, we use the dataset semis_xy.csv, which represents the \((x, y)\) coordinates for seedlings of two species (sp, B = birch and P = poplar) in a 15 x 15 m plot.

+
+
semis <- read.csv("data/semis_xy.csv")
+head(semis)
+
+
      x    y sp
+1 14.73 0.05  P
+2 14.72 1.71  P
+3 14.31 2.06  P
+4 14.16 2.64  P
+5 14.12 4.15  B
+6  9.88 4.08  B
+
+
+

The spatstat package provides tools for point pattern analysis in R. The first step consists in transforming our data frame into a ppp object (point pattern) with the function of the same name. In this function, we specify which columns contain the coordinates x and y as well as the marks, which here will be the species codes. We also need to specify an observation window (window) using the owin function, where we provide the plot limits in x and y.

+
+
library(spatstat)
+
+semis <- ppp(x = semis$x, y = semis$y, marks = as.factor(semis$sp),
+             window = owin(xrange = c(0, 15), yrange = c(0, 15)))
+semis
+
+
Marked planar point pattern: 281 points
+Multitype, with levels = B, P 
+window: rectangle = [0, 15] x [0, 15] units
+
+
+

Marks can be numeric or categorical. Note that for categorical marks as is the case here, the variable must be explicitly converted to a factor.

+

The plot function applied to a point pattern shows a diagram of the pattern.

+
+
plot(semis)
+
+

+
+
+

The intensity function calculates the density of points of each species by unit area (here, by \(m^2\)).

+
+
intensity(semis)
+
+
        B         P 
+0.6666667 0.5822222 
+
+
+

To first analyze the distribution of each species separately, we split the pattern with split. Since the pattern contains categorical marks, it is automatically split according to the values of those marks. The result is a list of two point patterns.

+
+
semis_split <- split(semis)
+plot(semis_split)
+
+

+
+
+

The Kest function calculates Ripley’s \(K\) for a series of distances up to (by default) 1/4 of the width of the window. Here we apply it to the first pattern (birch) by choosing semis_split[[1]]. Note that double square brackets are necessary to choose an item from a list in R.

+

The argument correction = "iso" tells the function to apply Ripley’s correction for edge effects.

+
+
k <- Kest(semis_split[[1]], correction = "iso")
+plot(k)
+
+

+
+
+

According to this graph, there seems to be an excess of neighbours for distances of 1 m and above. To check if this is a significant difference, we produce a simulation envelope with the envelope function. The first argument of envelope is a point pattern to which the simulations will be compared, the second one is a function to be computed (here, Kest) for each simulated pattern, then we add the arguments of the Kest function (here, only correction).

+
+
plot(envelope(semis_split[[1]], Kest, correction = "iso"))
+
+
Generating 99 simulations of CSR  ...
+1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,  99.
+
+Done.
+
+
+

+
+
+

As indicated by the message, by default the function performs 99 simulations of the null model corresponding to complete spatial randomness (CSR).

+

The observed curve falls outside the envelope of the 99 simulations near \(r = 2\). We must be careful not to interpret too quickly a result that is outside the envelope. Although there is about a 1% probability of obtaining a more extreme result under the null hypothesis at a given distance, the envelope is calculated for a large number of values of \(r\) and is not corrected for multiple comparisons. Thus, a significant difference for a very small range of values of \(r\) may be simply due to chance.

+
+

Exercise 1

+

Looking at the graph of the second point pattern (poplar seedlings), can you predict where Ripley’s \(K\) will be in relation to the null hypothesis of complete spatial randomness? Verify your prediction by calculating Ripley’s \(K\) for this point pattern in R.

+
+
+
+

Effect of heterogeneity

+

The graph below illustrates a heterogeneous point pattern, i.e. it shows an density gradient (more points on the left than on the right).

+
+
+

+
+
+

A density gradient can be confused with an aggregation of points, as can be seen on the graph of the corresponding Ripley’s \(K\). In theory, these are two different processes:

+
    +
  • Heterogeneity: The density of points varies in the study area, for example due to the fact that certain local conditions are more favorable to the presence of the species of interest.

  • +
  • Aggregation: The mean density of points is homogeneous, but the presence of one point increases the presence of other points in its vicinity, for example due to positive interactions between individuals.

  • +
+

However, it may be difficult to differentiate between the two in practice, especially since some patterns may be both heterogeneous and aggregated.

+

Let’s take the example of the poplar seedlings from the previous exercise. The density function applied to a point pattern performs a kernel density estimation of the density of the seedlings across the plot. By default, this function uses a Gaussian kernel with a standard deviation sigma specified in the function, which determines the scale at which density fluctuations are “smoothed”. Here, we use a value of 2 m for sigma and we first represent the estimated density with plot, before overlaying the points (add = TRUE means that the points are added to the existing plot rather than creating a new plot).

+
+
dens_p <- density(semis_split[[2]], sigma = 2)
+plot(dens_p)
+plot(semis_split[[2]], add = TRUE)
+
+

+
+
+

To measure the aggregation or repulsion of points in a heterogeneous pattern, we must use the inhomogeneous version of the \(K\) statistic (Kinhom in spatstat). This statistic is still equal to the mean number of neighbours within a radius \(r\) of a point in the pattern, but rather than standardizing this number by the overall intensity of the pattern, it is standardized by the local estimated density. As above, we specify sigma = 2 to control the level of smoothing for the varying density estimate.

+
+
plot(Kinhom(semis_split[[2]], sigma = 2, correction = "iso"))
+
+

+
+
+

Taking into account the heterogeneity of the pattern at a scale sigma of 2 m, there seems to be a deficit of neighbours starting at a radius of about 1.5 m. We can now check whether this deviation is significant.

+

As before, we use envelope to simulate the Kinhom statistic under the null model. However, the null model here is not a homogeneous Poisson process (CSR). It is instead a heterogeneous Poisson process simulated by the function rpoispp(dens_p), i.e. the points are independent of each other, but their density is heterogeneous and given by dens_p. The simulate argument of the envelope function specifies the function used for simulations under the null model; this function must have one argument, here x, even if it is not used.

+

Finally, in addition to the arguments needed for Kinhom, i.e. sigma and correction, we also specify nsim = 199 to perform 199 simulations and nrank = 5 to eliminate the 5 most extreme results on each side of the envelope, i.e. the 10 most extreme results out of 199, to achieve an interval containing about 95% of the probability under the null hypothesis.

+
+
khet_p <- envelope(semis_split[[2]], Kinhom, sigma = 2,  correction = "iso",
+                   nsim = 199, nrank = 5, simulate = function(x) rpoispp(dens_p))
+
+
Generating 199 simulations by evaluating function  ...
+1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40
+.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80
+.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120
+.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160
+.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.
+
+Done.
+
+
plot(khet_p)
+
+

+
+
+

Note: For a hypothesis test based on simulations of a null hypothesis, the \(p\)-value is estimated by \((m + 1)/(n + 1)\), where \(n\) is the number of simulations and \(m\) is the number of simulations where the value of the statistic is more extreme than that of the observed data. This is why the number of simulations is often chosen to be 99, 199, etc.

+
+

Exercise 2

+

Repeat the heterogeneous density estimation and Kinhom calculation with a standard deviation sigma of 5 rather than 2. How does the smoothing level for the density estimation influence the conclusions?

+

To differentiate between a variation in the density of points from an interaction (aggregation or repulsion) between these points with this type of analysis, it is generally assumed that the two processes operate at different scales. Typically, we can test whether the points are aggregated at a small scale after accounting for a variation in density at a larger scale.

+
+
+
+

Relationship between two point patterns

+

Let’s consider a case where we have two point patterns, for example the position of trees of two species in a plot (orange and green points in the graph below). Each of the two patterns may or may not present an aggregation of points.

+
+
+

+
+
+

Regardless of whether points are aggregated at the species level, we want to determine whether the two species are arranged independently. In other words, does the probability of observing a tree of one species depend on the presence of a tree of the other species at a given distance?

+

The bivariate version of Ripley’s \(K\) allows us to answer this question. For two patterns noted 1 and 2, the function \(K_{12}(r)\) calculates the mean number of points in pattern 2 within a radius \(r\) from a point in pattern 1, standardized by the density of pattern 2.

+

In theory, this function is symmetrical, so \(K_{12}(r) = K_{21}(r)\) and the result would be the same whether the points of pattern 1 or 2 are chosen as “focal” points for the analysis. However, the estimation of the two quantities for an observed pattern may differ, in particular because of edge effects. The variance of \(K_{12}\) and \(K_{21}\) between simulations of a null model may also differ, so the null hypothesis test may have more or less power depending on the choice of the focal species.

+

The choice of an appropriate null model is important here. In order to determine whether there is a significant attraction or repulsion between the two patterns, the position of one of the patterns must be randomly moved relative to that of the other pattern, while keeping the spatial structure of each pattern taken in isolation.

+

One way to do this randomization is to shift one of the two patterns horizontally and/or vertically by a random distance. The part of the pattern that “comes out” on one side of the window is attached to the other side. This method is called a toroidal shift, because by connecting the top and bottom as well as the left and right of a rectangular surface, we obtain the shape of a torus (a three-dimensional “donut”).

+
+
+

+
+
+

The graph above shows a translation of the green pattern to the right, while the orange pattern remains in the same place. The green points in the shaded area are brought back on the other side. Note that while this method generally preserves the structure of each pattern while randomizing their relative position, it can have some drawbacks, such as dividing point clusters that are near the cutoff point.

+

Let’s now check whether the position of the two species (birch and poplar) is independent in our plot. The function Kcross calculates the bivariate \(K_{ij}\), we must specify which type of point (mark) is considered as the focal species \(i\) and the neighbouring species \(j\).

+
+
plot(Kcross(semis, i = "P", j = "B", correction = "iso"))
+
+

+
+
+

Here, the observed \(K\) is lower than the theoretical value, indicating a possible repulsion between the two patterns.

+

To determine the envelope of the \(K\) under the null hypothesis of independence of the two patterns, we must specify that the simulations are based on a translation of the patterns. We indicate that the simulations use the function rshift (random translation) with the argument simulate = function(x) rshift(x, which = "B"); here, the x argument in simulate corresponds to the original point pattern and the which argument indicates which of the patterns is translated. As in the previous case, the arguments needed for Kcross, i.e. i, j and correction, must be repeated in the envelope function.

+
+
plot(envelope(semis, Kcross, i = "P", j = "B", correction = "iso", 
+              nsim = 199, nrank = 5, simulate = function(x) rshift(x, which = "B")))
+
+
Generating 199 simulations by evaluating function  ...
+1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40
+.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80
+.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120
+.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160
+.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.
+
+Done.
+
+
+

+
+
+

Here, the observed curve is totally within the envelope, so we do not reject the null hypothesis of independence of the two patterns.

+
+

Questions

+
    +
  1. What would be one reason for our choice to translate the points of the birch rather than poplar?

  2. +
  3. Would the simulations generated by random translation be a good null model if the two patterns were heterogeneous?

  4. +
+
+
+
+

Marked point patterns

+

The fir.csv dataset contains the \((x, y)\) coordinates of 822 fir trees in a 1 hectare plot and their status (A = alive, D = dead) following a spruce budworm outbreak.

+
+
fir <- read.csv("data/fir.csv")
+head(fir)
+
+
      x     y status
+1 31.50  1.00      A
+2 85.25 30.75      D
+3 83.50 38.50      A
+4 84.00 37.75      A
+5 83.00 33.25      A
+6 33.25  0.25      A
+
+
+
+
fir <- ppp(x = fir$x, y = fir$y, marks = as.factor(fir$status),
+           window = owin(xrange = c(0, 100), yrange = c(0, 100)))
+plot(fir)
+
+

+
+
+

Suppose that we want to check whether fir mortality is independent or correlated between neighbouring trees. How does this question differ from the previous example, where we wanted to know if the position of the points of two species was independent?

+

In the previous example, the independence or interaction between the species referred to the formation of the pattern itself (whether or not seedlings of one species establish near those of the other species). Here, the characteristic of interest (survival) occurs after the establishment of the pattern, assuming that all those trees were alive at first and that some died as a result of the outbreak. So we take the position of the trees as fixed and we want to know whether the distribution of status (dead, alive) among those trees is random or shows a spatial pattern.

+

In Wiegand and Moloney’s textbook, the first situation (establishment of seedlings of two species) is called a bivariate pattern, so it is really two interacting patterns, while the second is a single pattern with a qualitative mark. The spatstat package in R does not differentiate between the two in terms of pattern definition (types of points are always represented by the marks argument), but the analysis methods applied to the two questions differ.

+

In the case of a pattern with a qualitative mark, we can define a mark connection function \(p_{ij}(r)\). For two points separated by a distance \(r\), this function gives the probability that the first point has the mark \(i\) and the second the mark \(j\). Under the null hypothesis where the marks are independent, this probability is equal to the product of the proportions of each mark in the entire pattern, \(p_{ij}(r) = p_i p_j\) independently of \(r\).

+

In spatstat, the mark connection function is computed with the markconnect function, where the marks \(i\) and \(j\) and the type of edge correction must be specified. In our example, we see that two closely spaced points are less likely to have a different status (A and D) than expected under the assumption of random and independent distribution of marks (red dotted line).

+
+
plot(markconnect(fir, i = "A", j = "D", correction = "iso"))
+
+

+
+
+

In this graph, the fluctuations in the function are due to the estimation error of a continuous \(r\) function from a limited number of discrete point pairs.

+

To simulate the null model in this case, we use the rlabel function, which randomly reassigns the marks among the points of the pattern, keeping the points’ positions fixed.

+
+
plot(envelope(fir, markconnect, i = "A", j = "D", correction = "iso", 
+              nsim = 199, nrank = 5, simulate = rlabel))
+
+
Generating 199 simulations by evaluating function  ...
+1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40
+.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80
+.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120
+.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160
+.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.
+
+Done.
+
+
+

+
+
+

Note that since the rlabel function has only one required argument corresponding to the original point pattern, it was not necessary to specify: simulate = function(x) rlabel(x).

+

Here are the results for tree pairs of the same status A or D:

+
+
par(mfrow = c(1, 2))
+plot(envelope(fir, markconnect, i = "A", j = "A", correction = "iso", 
+              nsim = 199, nrank = 5, simulate = rlabel))
+
+
Generating 199 simulations by evaluating function  ...
+1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40
+.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80
+.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120
+.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160
+.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.
+
+Done.
+
+
plot(envelope(fir, markconnect, i = "D", j = "D", correction = "iso", 
+              nsim = 199, nrank = 5, simulate = rlabel))
+
+
Generating 199 simulations by evaluating function  ...
+1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40
+.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80
+.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120
+.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160
+.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.
+
+Done.
+
+
+

+
+
+

It therefore appears that fir mortality due to this outbreak is spatially aggregated, since trees located in close proximity to each other have a greater probability of sharing the same status than predicted by the null hypothesis.

+
+
+

References

+

Fortin, M.-J. and Dale, M.R.T. (2005) Spatial Analysis: A Guide for Ecologists. Cambridge University Press: Cambridge, UK.

+

Wiegand, T. and Moloney, K.A. (2013) Handbook of Spatial Point-Pattern Analysis in Ecology, CRC Press.

+

The dataset in the last example is a subet of the Lake Duparquet Research and Teaching Forest (LDRTF) data, available on Dryad here.

+
+
+
+

4 Solutions

+
+

Exercise 1

+
+
plot(envelope(semis_split[[2]], Kest, correction = "iso"))
+
+
Generating 99 simulations of CSR  ...
+1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,  99.
+
+Done.
+
+
+

+
+
+

Poplar seedlings seem to be significantly aggregated according to the \(K\) function.

+
+
+

Exercise 2

+
+
dens_p <- density(semis_split[[2]], sigma = 5)
+plot(dens_p)
+plot(semis_split[[2]], add = TRUE)
+
+

+
+
khet_p <- envelope(semis_split[[2]], Kinhom, sigma = 5, correction = "iso",
+                   nsim = 199, nrank = 5, simulate = function(x) rpoispp(dens_p))
+
+
Generating 199 simulations by evaluating function  ...
+1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40
+.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80
+.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120
+.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160
+.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.
+
+Done.
+
+
plot(khet_p)
+
+

+
+
+

Here, as we estimate density variations at a larger scale, even after accounting for this variation, the poplar seedlings seem to be aggregated at a small scale.

+
+
+
+

5 Spatial correlation of a variable

+

Correlation between measurements of a variable taken at nearby points often occurs in environmental data. This principle is sometimes referred to as the “first law of geography” and is expressed in the following quote from Waldo Tobler: “Everything is related to everything else, but near things are more related than distant things”.

+

In statistics, we often refer to autocorrelation as the correlation between measurements of the same variable taken at different times (temporal autocorrelation) or places (spatial autocorrelation).

+
+

Intrinsic or induced dependence

+

There are two basic types of spatial dependence on a measured variable \(y\): an intrinsic dependence on \(y\), or a dependence induced by external variables influencing \(y\), which are themselves spatially correlated.

+

For example, suppose that the abundance of a species is correlated between two sites located near each other:

+
    +
  • this spatial dependence can be induced if it is due to a spatial correlation of habitat factors that are favorable or unfavorable to the species;

  • +
  • or it can be intrinsic if it is due to the dispersion of individuals to nearby sites.

  • +
+

In many cases, both types of dependence affect a given variable.

+

If the dependence is simply induced and the external variables that cause it are included in the model explaining \(y\), then the model residuals will be independent and we can use all the methods already seen that ignore spatial correlation.

+

However, if the dependence is intrinsic or due to unmeasured external factors, then the spatial correlation of the residuals in the model will have to be taken into account.

+
+
+

Different ways to model spatial effects

+

In this training, we will directly model the spatial correlations of our data. It is useful to compare this approach to other ways of including spatial aspects in a statistical model.

+

First, we could include predictors in the model that represent position (e.g., longitude, latitude). Such predictors may be useful for detecting a systematic large-scale trend or gradient, whether or not the trend is linear (e.g., with a generalized additive model).

+

In contrast to this approach, the models we will see now serve to model a spatial correlation in the random fluctuations of a variable (i.e., in the residuals after removing any systematic effect).

+

Mixed models use random effects to represent the non-independence of data on the basis of their grouping, i.e., after accounting for systematic fixed effects, data from the same group are more similar (their residual variation is correlated) than data from different groups. These groups were sometimes defined according to spatial criteria (observations grouped into sites).

+

However, in the context of a random group effect, all groups are as different from each other, e.g., two sites within 100 km of each other are no more or less similar than two sites 2 km apart.

+

The methods we will see here and in the next parts of the training therefore allow us to model non-independence on a continuous scale (closer = more correlated) rather than just discrete (hierarchy of groups).

+
+
+
+

6 Geostatistical models

+

Geostatistics refers to a group of techniques that originated in the earth sciences. Geostatistics is concerned with variables that are continuously distributed in space and where a number of points are sampled to estimate this distribution. A classic example of these techniques comes from the mining field, where the aim was to create a map of the concentration of ore at a site from samples taken at different points on the site.

+

For these models, we will assume that \(z(x, y)\) is a stationary spatial variable measured at points with coordinates \(x\) and \(y\).

+
+

Variogram

+

A central aspect of geostatistics is the estimation of the variogram \(\gamma_z\) . The variogram is equal to half the mean square difference between the values of \(z\) for two points \((x_i, y_i)\) and \((x_j, y_j)\) separated by a distance \(h\).

+

\[\gamma_z(h) = \frac{1}{2} \text{E} \left[ \left( z(x_i, y_i) - z(x_j, y_j) \right)^2 \right]_{d_{ij} = h}\]

+

In this equation, the \(\text{E}\) function with the index \(d_{ij}=h\) designates the statistical expectation (i.e., the mean) of the squared deviation between the values of \(z\) for points separated by a distance \(h\).

+

If we want instead to express the autocorrelation \(\rho_z(h)\) between measures of \(z\) separated by a distance \(h\), it is related to the variogram by the equation:

+

\[\gamma_z = \sigma_z^2(1 - \rho_z)\] ,

+

where \(\sigma_z^2\) is the global variance of \(z\).

+

Note that \(\gamma_z = \sigma_z^2\) when we reach a distance where the measurements of \(z\) are independent, so \(\rho_z = 0\). In this case, we can see that \(\gamma_z\) is similar to a variance, although it is sometimes called “semivariogram” or “semivariance” because of the 1/2 factor in the above equation.

+
+
+

Theoretical models for the variogram

+

Several parametric models have been proposed to represent the spatial correlation as a function of the distance between sampling points. Let us first consider a correlation that decreases exponentially:

+

\[\rho_z(h) = e^{-h/r}\]

+

Here, \(\rho_z = 1\) for \(h = 0\) and the correlation is multiplied by \(1/e \approx 0.37\) each time the distance increases by \(r\). In this context, \(r\) is called the range of the correlation.

+

From the above equation, we can calculate the corresponding variogram.

+

\[\gamma_z(h) = \sigma_z^2 (1 - e^{-h/r})\]

+

Here is a graphical representation of this variogram.

+
+
+

+
+
+

Because of the exponential function, the value of \(\gamma\) at large distances approaches the global variance \(\sigma_z^2\) without exactly reaching it. This asymptote is called a sill in the geostatistical context and is represented by the symbol \(s\).

+

Finally, it is sometimes unrealistic to assume a perfect correlation when the distance tends towards 0, because of a possible variation of \(z\) at a very small scale. A nugget effect, denoted \(n\), can be added to the model so that \(\gamma\) approaches \(n\) (rather than 0) if \(h\) tends towards 0. The term nugget comes from the mining origin of these techniques, where a nugget could be the source of a sudden small-scale variation in the concentration of a mineral.

+

By adding the nugget effect, the remainder of the variogram is “compressed” to keep the same sill, resulting in the following equation.

+

\[\gamma_z(h) = n + (s - n) (1 - e^{-h/r})\]

+

In the gstat package that we use below, the term \((s-n)\) is called a partial sill or psill for the exponential portion of the variogram.

+
+
+

+
+
+

In addition to the exponential model, two other common theoretical models for the variogram are the Gaussian model (where the correlation follows a half-normal curve), and the spherical model (where the variogram increases linearly at the start and then curves and reaches the plateau at a distance equal to its range \(r\)). The spherical model thus allows the correlation to be exactly 0 at large distances, rather than gradually approaching zero in the case of the other models.

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
Model\(\rho(h)\)\(\gamma(h)\)
Exponential\(\exp\left(-\frac{h}{r}\right)\)\(s \left(1 - \exp\left(-\frac{h}{r}\right)\right)\)
Gaussian\(\exp\left(-\frac{h^2}{r^2}\right)\)\(s \left(1 - \exp\left(-\frac{h^2}{r^2}\right)\right)\)
Spherical \((h < r)\) *\(1 - \frac{3}{2}\frac{h}{r} + \frac{1}{2}\frac{h^3}{r^3}\)\(s \left(\frac{3}{2}\frac{h}{r} - \frac{1}{2}\frac{h^3}{r^3} \right)\)
+

* For the spherical model, \(\rho = 0\) and \(\gamma = s\) if \(h \ge r\).

+
+
+

+
+
+
+
+

Empirical variogram

+

To estimate \(\gamma_z(h)\) from empirical data, we need to define distance classes, thus grouping different distances within a margin of \(\pm \delta\) around a distance \(h\), then calculating the mean square deviation for the pairs of points in that distance class.

+

\[\hat{\gamma_z}(h) = \frac{1}{2 N_{\text{paires}}} \sum \left[ \left( z(x_i, y_i) - z(x_j, y_j) \right)^2 \right]_{d_{ij} = h \pm \delta}\]

+

We will see in the next section how to estimate a variogram in R.

+
+
+

Regression model with spatial correlation

+

The following equation represents a multiple linear regression including residual spatial correlation:

+

\[v = \beta_0 + \sum_i \beta_i u_i + z + \epsilon\]

+

Here, \(v\) designates the response variable and \(u\) the predictors, to avoid confusion with the spatial coordinates \(x\) and \(y\).

+

In addition to the residual \(\epsilon\) that is independent between observations, the model includes a term \(z\) that represents the spatially correlated portion of the residual variance.

+

Here are suggested steps to apply this type of model:

+
    +
  1. Fit the regression model without spatial correlation.

  2. +
  3. Verify the presence of spatial correlation from the empirical variogram of the residuals.

  4. +
  5. Fit one or more regression models with spatial correlation and select the one that shows the best fit to the data.

  6. +
+
+
+
+

7 Geostatistical models in R

+

The gstat package contains functions related to geostatistics. For this example, we will use the oxford dataset from this package, which contains measurements of physical and chemical properties for 126 soil samples from a site, along with their coordinates XCOORD and YCOORD.

+
+
library(gstat)
+
+data(oxford)
+str(oxford)
+
+
'data.frame':   126 obs. of  22 variables:
+ $ PROFILE  : num  1 2 3 4 5 6 7 8 9 10 ...
+ $ XCOORD   : num  100 100 100 100 100 100 100 100 100 100 ...
+ $ YCOORD   : num  2100 2000 1900 1800 1700 1600 1500 1400 1300 1200 ...
+ $ ELEV     : num  598 597 610 615 610 595 580 590 598 588 ...
+ $ PROFCLASS: Factor w/ 3 levels "Cr","Ct","Ia": 2 2 2 3 3 2 3 2 3 3 ...
+ $ MAPCLASS : Factor w/ 3 levels "Cr","Ct","Ia": 2 3 3 3 3 2 2 3 3 3 ...
+ $ VAL1     : num  3 3 4 4 3 3 4 4 4 3 ...
+ $ CHR1     : num  3 3 3 3 3 2 2 3 3 3 ...
+ $ LIME1    : num  4 4 4 4 4 0 2 1 0 4 ...
+ $ VAL2     : num  4 4 5 8 8 4 8 4 8 8 ...
+ $ CHR2     : num  4 4 4 2 2 4 2 4 2 2 ...
+ $ LIME2    : num  4 4 4 5 5 4 5 4 5 5 ...
+ $ DEPTHCM  : num  61 91 46 20 20 91 30 61 38 25 ...
+ $ DEP2LIME : num  20 20 20 20 20 20 20 20 40 20 ...
+ $ PCLAY1   : num  15 25 20 20 18 25 25 35 35 12 ...
+ $ PCLAY2   : num  10 10 20 10 10 20 10 20 10 10 ...
+ $ MG1      : num  63 58 55 60 88 168 99 59 233 87 ...
+ $ OM1      : num  5.7 5.6 5.8 6.2 8.4 6.4 7.1 3.8 5 9.2 ...
+ $ CEC1     : num  20 22 17 23 27 27 21 14 27 20 ...
+ $ PH1      : num  7.7 7.7 7.5 7.6 7.6 7 7.5 7.6 6.6 7.5 ...
+ $ PHOS1    : num  13 9.2 10.5 8.8 13 9.3 10 9 15 12.6 ...
+ $ POT1     : num  196 157 115 172 238 164 312 184 123 282 ...
+
+
+

Suppose that we want to model the magnesium concentration (MG1), represented as a function of the spatial position in the following graph.

+
+
library(ggplot2)
+ggplot(oxford, aes(x = YCOORD, y = XCOORD, size = MG1)) +
+    geom_point() +
+    coord_fixed()
+
+

+
+
+

Note that the \(x\) and \(y\) axes have been inverted to save space. The coord_fixed() function of ggplot2 ensures that the scale is the same on both axes, which is useful for representing spatial data.

+

We can immediately see that these measurements were taken on a 100 m grid. It seems that the magnesium concentration is spatially correlated, although it may be a correlation induced by another variable. In particular, we know that the concentration of magnesium is negatively related to the soil pH (PH1).

+
+
ggplot(oxford, aes(x = PH1, y = MG1)) +
+    geom_point()
+
+

+
+
+

The variogram function of gstat is used to estimate a variogram from empirical data. Here is the result obtained for the variable MG1.

+
+
var_mg <- variogram(MG1 ~ 1, locations = ~ XCOORD + YCOORD, data = oxford)
+var_mg
+
+
    np     dist    gamma dir.hor dir.ver   id
+1  225 100.0000 1601.404       0       0 var1
+2  200 141.4214 1950.805       0       0 var1
+3  548 215.0773 2171.231       0       0 var1
+4  623 303.6283 2422.245       0       0 var1
+5  258 360.5551 2704.366       0       0 var1
+6  144 400.0000 2948.774       0       0 var1
+7  570 427.5569 2994.621       0       0 var1
+8  291 500.0000 3402.058       0       0 var1
+9  366 522.8801 3844.165       0       0 var1
+10 200 577.1759 3603.060       0       0 var1
+11 458 619.8400 3816.595       0       0 var1
+12  90 670.8204 3345.739       0       0 var1
+
+
+

The formula MG1 ~ 1 indicates that no linear predictor is included in this model, while the argument locations indicates which variables in the data frame correspond to the spatial coordinates.

+

In the resulting table, gamma is the value of the variogram for the distance class centered on dist, while np is the number of pairs of points in that class. Here, since the points are located on a grid, we obtain regular distance classes (e.g.: 100 m for neighboring points on the grid, 141 m for diagonal neighbors, etc.).

+

Here, we limit ourselves to the estimation of isotropic variograms, i.e. the variogram depends only on the distance between the two points and not on the direction. Although we do not have time to see it today, it is possible with gstat to estimate the variogram separately in different directions.

+

We can illustrate the variogram with plot.

+
+
plot(var_mg, col = "black")
+
+

+
+
+

If we want to estimate the residual spatial correlation of MG1 after including the effect of PH1, we can add that predictor to the formula.

+
+
var_mg <- variogram(MG1 ~ PH1, locations = ~ XCOORD + YCOORD, data = oxford)
+plot(var_mg, col = "black")
+
+

+
+
+

Including the effect of pH, the range of the spatial correlation seems to decrease, while the plateau is reached around 300 m. It even seems that the variogram decreases beyond 400 m. In general, we assume that the variance between two points does not decrease with distance, unless there is a periodic spatial pattern.

+

The function fit.variogram accepts as arguments a variogram estimated from the data, as well as a theoretical model described in a vgm function, and then estimates the parameters of that model according to the data. The fitting is done by the method of least squares.

+

For example, vgm("Exp") means we want to fit an exponential model.

+
+
vfit <- fit.variogram(var_mg, vgm("Exp"))
+vfit
+
+
  model    psill    range
+1   Nug    0.000  0.00000
+2   Exp 1951.496 95.11235
+
+
+

There is no nugget effect, because psill = 0 for the Nug (nugget) part of the model. The exponential part has a sill at 1951 and a range of 95 m.

+

To compare different models, a vector of model names can be given to vgm. In the following example, we include the exponential, gaussian (“Gau”) and spherical (“Sph”) models.

+
+
vfit <- fit.variogram(var_mg, vgm(c("Exp", "Gau", "Sph")))
+vfit
+
+
  model    psill    range
+1   Nug    0.000  0.00000
+2   Exp 1951.496 95.11235
+
+
+

The function gives us the result of the model with the best fit (lowest sum of squared deviations), which here is the same exponential model.

+

Finally, we can superimpose the theoretical model and the empirical variogram on the same graph.

+
+
plot(var_mg, vfit, col = "black")
+
+

+
+
+
+

Regression with spatial correlation

+

We have seen above that the gstat package allows us to estimate the variogram of the residuals of a linear model. In our example, the magnesium concentration was modeled as a function of pH, with spatially correlated residuals.

+

Another tool to fit this same type of model is the gls function of the nlme package, which is included with the installation of R.

+

This function applies the generalized least squares method to fit linear regression models when the residuals are not independent or when the residual variance is not the same for all observations. Since the estimates of the coefficients depend on the estimated correlations between the residuals and the residuals themselves depend on the coefficients, the model is fitted by an iterative algorithm:

+
    +
  1. A classical linear regression model (without correlation) is fitted to obtain residuals.

  2. +
  3. The spatial correlation model (variogram) is fitted with those residuals.

  4. +
  5. The regression coefficients are re-estimated, now taking into account the correlations.

  6. +
+

Steps 2 and 3 are repeated until the estimates are stable at a desired precision.

+

Here is the application of this method to the same model for the magnesium concentration in the oxford dataset. In the correlation argument of gls, we specify an exponential correlation model as a function of our spatial coordinates and we include a possible nugget effect.

+

In addition to the exponential correlation corExp, the gls function can also estimate a Gaussian (corGaus) or spherical (corSpher) model.

+
+
library(nlme)
+gls_mg <- gls(MG1 ~ PH1, oxford, 
+              correlation = corExp(form = ~ XCOORD + YCOORD, nugget = TRUE))
+summary(gls_mg)
+
+
Generalized least squares fit by REML
+  Model: MG1 ~ PH1 
+  Data: oxford 
+      AIC      BIC   logLik
+  1278.65 1292.751 -634.325
+
+Correlation Structure: Exponential spatial correlation
+ Formula: ~XCOORD + YCOORD 
+ Parameter estimate(s):
+      range      nugget 
+478.0322964   0.2944753 
+
+Coefficients:
+               Value Std.Error   t-value p-value
+(Intercept) 391.1387  50.42343  7.757084       0
+PH1         -41.0836   6.15662 -6.673079       0
+
+ Correlation: 
+    (Intr)
+PH1 -0.891
+
+Standardized residuals:
+       Min         Q1        Med         Q3        Max 
+-2.1846957 -0.6684520 -0.3687813  0.4627580  3.1918604 
+
+Residual standard error: 53.8233 
+Degrees of freedom: 126 total; 124 residual
+
+
+

To compare this result with the adjusted variogram above, the parameters given by gls must be transformed. The range has the same meaning in both cases and corresponds to 478 m for the result of gls. The global variance of the residuals is the square of Residual standard error. The nugget effect here (0.294) is expressed as a fraction of that variance. Finally, to obtain the partial sill of the exponential part, the nugget effect must be subtracted from the total variance.

+

After performing these calculations, we can give these parameters to the vgm function of gstat to superimpose this variogram estimated by gls on our variogram of the residuals of the classical linear model.

+
+
gls_range <- 478
+gls_var <- 53.823^2
+gls_nugget <- 0.294 * gls_var
+gls_psill <- gls_var - gls_nugget
+
+gls_vgm <- vgm("Exp", psill = gls_psill, range = gls_range, nugget = gls_nugget)
+
+plot(var_mg, gls_vgm, col = "black", ylim = c(0, 4000))
+
+

+
+
+

Does the model fit the data less well here? In fact, this empirical variogram represented by the points was obtained from the residuals of the linear model ignoring the spatial correlation, so it is a biased estimate of the actual spatial correlations. The method is still adequate to quickly check if spatial correlations are present. However, to simultaneously fit the regression coefficients and the spatial correlation parameters, the generalized least squares (GLS) approach is preferable and will produce more accurate estimates.

+

Finally, note that the result of the gls model also gives the AIC, which we can use to compare the fit of different models (with different predictors or different forms of spatial correlation).

+
+
+

Exercise

+

The bryo_belg.csv dataset is adapted from the data of this study:

+
+

Neyens, T., Diggle, P.J., Faes, C., Beenaerts, N., Artois, T. et Giorgi, E. (2019) Mapping species richness using opportunistic samples: a case study on ground-floor bryophyte species richness in the Belgian province of Limburg. Scientific Reports 9, 19122. https://doi.org/10.1038/s41598-019-55593-x

+
+

This data frame shows the specific richness of ground bryophytes (richness) for different sampling points in the Belgian province of Limburg, with their position (x, y) in km, in addition to information on the proportion of forest (forest) and wetlands (wetland) in a 1 km^2$ cell containing the sampling point.

+
+
bryo_belg <- read.csv("data/bryo_belg.csv")
+head(bryo_belg)
+
+
  richness    forest   wetland        x        y
+1        9 0.2556721 0.5036614 228.9516 220.8869
+2        6 0.6449114 0.1172068 227.6714 219.8613
+3        5 0.5039905 0.6327003 228.8252 220.1073
+4        3 0.5987329 0.2432942 229.2775 218.9035
+5        2 0.7600775 0.1163538 209.2435 215.2414
+6       10 0.6865434 0.0000000 210.4142 216.5579
+
+
+

For this exercise, we will use the square root of the specific richness as the response variable. The square root transformation often allows to homogenize the variance of the count data in order to apply a linear regression.

+
    +
  1. Fit a linear model of the transformed species richness to the proportion of forest and wetlands, without taking into account spatial correlations. What is the effect of the two predictors in this model?

  2. +
  3. Calculate the empirical variogram of the model residuals in (a). Does there appear to be a spatial correlation between the points?

  4. +
+

Note: The cutoff argument to the variogram function specifies the maximum distance at which the variogram is calculated. You can manually adjust this value to get a good view of the sill.

+
    +
  1. Re-fit the linear model in (a) with the gls function in the nlme package, trying different types of spatial correlations (exponential, Gaussian, spherical). Compare the models (including the one without spatial correlation) with the AIC.

  2. +
  3. What is the effect of the proportion of forests and wetlands according to the model in (c)? Explain the differences between the conclusions of this model and the model in (a).

  4. +
+
+
+
+

8 Kriging

+

As mentioned before, a common application of geostatistical models is to predict the value of the response variable at unsampled locations, a form of spatial interpolation called kriging (pronounced with a hard “g”).

+

There are three basic types of kriging based on the assumptions made about the response variable:

+
    +
  • Ordinary kriging: Stationary variable with an unknown mean.

  • +
  • Simple kriging: Stationary variable with a known mean.

  • +
  • Universal kriging: Variable with a trend given by a linear or non-linear model.

  • +
+

For all kriging methods, the predictions at a new point are a weighted mean of the values at known points. These weights are chosen so that kriging provides the best linear unbiased prediction of the response variable, if the model assumptions (in particular the variogram) are correct. That is, among all possible unbiased predictions, the weights are chosen to give the minimum mean square error. Kriging also provides an estimate of the uncertainty of each prediction.

+

While we will not present the detailed kriging equations here, the weights depend on both the correlations (estimated by the variogram) between the sampled points and the new point, as well of the correlations between the sampled points themselves. In other words, sampled points near the new point are given more weight, but isolated sampled points are also given more weight, because sample points close to each other provide redundant information.

+

Kriging is an interpolation method, so the prediction at a sampled point will always be equal to the measured value (the measurement is supposed to have no error, just spatial variation). However, in the presence of a nugget effect, any small displacement from the sampled location will show variability according to the nugget.

+

In the example below, we generate a new dataset composed of randomly-generated (x, y) coordinates within the study area as well as randomly-generated pH values based on the oxford data. We then apply the function krige to predict the magnesium values at these new points. Note that we specify the variogram derived from the GLS results in the model argument to krige.

+
+
set.seed(14)
+new_points <- data.frame(
+    XCOORD = runif(100, min(oxford$XCOORD), max(oxford$XCOORD)),
+    YCOORD = runif(100, min(oxford$YCOORD), max(oxford$YCOORD)),
+    PH1 = rnorm(100, mean(oxford$PH1), sd(oxford$PH1))
+)
+
+pred <- krige(MG1 ~ PH1, locations = ~ XCOORD + YCOORD, data = oxford,
+              newdata = new_points, model = gls_vgm)
+
+
[using universal kriging]
+
+
head(pred)
+
+
    XCOORD    YCOORD var1.pred var1.var
+1 227.0169  162.1185  47.13065 1269.002
+2 418.9136  465.9013  79.68437 1427.269
+3 578.5943 2032.7477  60.30539 1264.471
+4 376.2734 1530.7193 127.22366 1412.875
+5 591.5336  421.6290 105.88124 1375.485
+6 355.7369  404.3378 127.73055 1250.114
+
+
+

The result of krige includes the new point coordinates, the prediction of the variable var1.pred along with its estimated variance var1.var. In the graph below, we show the mean MG1 predictions from kriging (triangles) along with the measurements (circles).

+
+
pred$MG1 <- pred$var1.pred
+
+ggplot(oxford, aes(x = YCOORD, y = XCOORD, color = MG1)) +
+    geom_point() +
+    geom_point(data = pred, shape = 17, size = 2) +
+    coord_fixed()
+
+

+
+
+

The estimated mean and variance from kriging can be used to simulate possible values of the variable at each new point, conditional on the sampled values. In the example below, we performed 4 conditional simulations by adding the argument nsim = 4 to the same krige instruction.

+
+
sim_mg <- krige(MG1 ~ PH1, locations = ~ XCOORD + YCOORD, data = oxford,
+                newdata = new_points, model = gls_vgm, nsim = 4)
+
+
drawing 4 GLS realisations of beta...
+[using conditional Gaussian simulation]
+
+
head(sim_mg)
+
+
    XCOORD    YCOORD       sim1      sim2      sim3      sim4
+1 227.0169  162.1185   9.638739  34.53159  46.08685  77.86376
+2 418.9136  465.9013  60.029144  20.17179  76.46333  59.57924
+3 578.5943 2032.7477 100.791412  77.47887  73.50058  59.40279
+4 376.2734 1530.7193 112.615730 150.96664  78.76125 146.83928
+5 591.5336  421.6290  70.925240  72.85522 153.90610 126.63758
+6 355.7369  404.3378 161.608032 118.93640 134.45695 142.20074
+
+
+
+
library(tidyr)
+sim_mg <- pivot_longer(sim_mg, cols = c(sim1, sim2, sim3, sim4), 
+                       names_to = "sim", values_to = "MG1")
+ggplot(sim_mg, aes(x = YCOORD, y = XCOORD, color = MG1)) +
+    geom_point() +
+    coord_fixed() +
+    facet_wrap(~ sim)
+
+

+
+
+
+
+

9 Solutions

+
+
bryo_lm <- lm(sqrt(richness) ~ forest + wetland, data = bryo_belg)
+summary(bryo_lm)
+
+

+Call:
+lm(formula = sqrt(richness) ~ forest + wetland, data = bryo_belg)
+
+Residuals:
+    Min      1Q  Median      3Q     Max 
+-1.8847 -0.4622  0.0545  0.4974  2.3116 
+
+Coefficients:
+            Estimate Std. Error t value Pr(>|t|)    
+(Intercept)  2.34159    0.08369  27.981  < 2e-16 ***
+forest       1.11883    0.13925   8.034 9.74e-15 ***
+wetland     -0.59264    0.17216  -3.442 0.000635 ***
+---
+Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+
+Residual standard error: 0.7095 on 417 degrees of freedom
+Multiple R-squared:  0.2231,    Adjusted R-squared:  0.2193 
+F-statistic: 59.86 on 2 and 417 DF,  p-value: < 2.2e-16
+
+
+

The proportion of forest has a significant positive effect and the proportion of wetlands has a significant negative effect on bryophyte richness.

+
+
plot(variogram(sqrt(richness) ~ forest + wetland, locations = ~ x + y,
+               data = bryo_belg, cutoff = 50), col = "black")
+
+

+
+
+

The variogram is increasing from 0 to at least 40 km, so there appears to be spatial correlations in the model residuals.

+
+
bryo_exp <- gls(sqrt(richness) ~ forest + wetland, data = bryo_belg,
+                correlation = corExp(form = ~ x + y, nugget = TRUE))
+bryo_gaus <- gls(sqrt(richness) ~ forest + wetland, data = bryo_belg,
+                correlation = corGaus(form = ~ x + y, nugget = TRUE))
+bryo_spher <- gls(sqrt(richness) ~ forest + wetland, data = bryo_belg,
+                  correlation = corSpher(form = ~ x + y, nugget = TRUE))
+
+
+
AIC(bryo_lm)
+
+
[1] 908.6358
+
+
AIC(bryo_exp)
+
+
[1] 867.822
+
+
AIC(bryo_gaus)
+
+
[1] 870.9592
+
+
AIC(bryo_spher)
+
+
[1] 866.9117
+
+
+

The spherical model has the smallest AIC.

+
+
summary(bryo_spher)
+
+
Generalized least squares fit by REML
+  Model: sqrt(richness) ~ forest + wetland 
+  Data: bryo_belg 
+       AIC      BIC    logLik
+  866.9117 891.1102 -427.4558
+
+Correlation Structure: Spherical spatial correlation
+ Formula: ~x + y 
+ Parameter estimate(s):
+     range     nugget 
+43.1727664  0.6063187 
+
+Coefficients:
+                 Value Std.Error   t-value p-value
+(Intercept)  2.0368769 0.2481636  8.207800   0.000
+forest       0.6989844 0.1481690  4.717481   0.000
+wetland     -0.2441130 0.1809118 -1.349348   0.178
+
+ Correlation: 
+        (Intr) forest
+forest  -0.251       
+wetland -0.235  0.241
+
+Standardized residuals:
+        Min          Q1         Med          Q3         Max 
+-1.75204183 -0.06568688  0.61415597  1.15240370  3.23322743 
+
+Residual standard error: 0.7998264 
+Degrees of freedom: 420 total; 417 residual
+
+
+

Both effects are less important in magnitude and the effect of wetlands is not significant anymore. As is the case for other types of non-independent residuals, the “effective sample size” here is less than the number of points, since points close to each other provide redundant information. Therefore, the relationship between predictors and response is less clear than given by the model assuming all these points were independent.

+

Note that the results for all three gls models are quite similar, so the choice to include spatial correlations was more important than the exact shape assumed for the variogram.

+
+
+

10 Areal data

+

Areal data are variables measured for regions of space, defined by polygons. This type of data is more common in the social sciences, human geography and epidemiology, where data is often available at the scale of administrative divisions.

+

This type of data also appears frequently in natural resource management. For example, the following map shows the forest management units of the Ministère de la Forêt, de la Faune et des Parcs du Québec.

+

+

Suppose that a variable is available at the level of these management units. How can we model the spatial correlation between units that are spatially close together?

+

One option would be to apply the geostatistical methods seen before, for example by calculating the distance between the centers of the polygons.

+

Another option, which is more adapted for areal data, is to define a network where each region is connected to neighbouring regions by a link. It is then assumed that the variables are directly correlated between neighbouring regions only. (Note, however, that direct correlations between immediate neighbours also generate indirect correlations for a chain of neighbours).

+

In this type of model, the correlation is not necessarily the same from one link to another. In this case, each link in the network can be associated with a weight representing its importance for the spatial correlation. We represent these weights by a matrix \(W\) where \(w_{ij}\) is the weight of the link between regions \(i\) and \(j\). A region has no link with itself, so \(w_{ii} = 0\).

+

A simple choice for \(W\) is to assign a weight equal to 1 if the regions are neighbours, otherwise 0 (binary weight).

+

In addition to land divisions represented by polygons, another example of areal data consists of a grid where the variable is calculated for each cell of the grid. In this case, a cell generally has 4 or 8 neighbouring cells, depending on whether diagonals are included or not.

+
+
+

11 Moran’s I

+

Before discussing spatial autocorrelation models, we present Moran’s \(I\) statistic, which allows us to test whether a significant correlation is present between neighbouring regions.

+

Moran’s \(I\) is a spatial autocorrelation coefficient of \(z\), weighted by the \(w_{ij}\). It therefore takes values between -1 and 1.

+

\[I = \frac{N}{\sum_i \sum_j w_{ij}} \frac{\sum_i \sum_j w_{ij} (z_i - \bar{z}) (z_j - \bar{z})}{\sum_i (z_i - \bar{z})^2}\]

+

In this equation, we recognize the expression of a correlation, which is the product of the deviations from the mean for two variables \(z_i\) and \(z_j\), divided by the product of their standard deviations (it is the same variable here, so we get the variance). The contribution of each pair \((i, j)\) is multiplied by its weight \(w_{ij}\) and the term on the left (the number of regions \(N\) divided by the sum of the weights) ensures that the result is bounded between -1 and 1.

+

Since the distribution of \(I\) is known in the absence of spatial autocorrelation, this statistic serves to test the null hypothesis that there is no spatial correlation between neighbouring regions.

+

Although we will not see an example in this course, Moran’s \(I\) can also be applied to point data. In this case, we divide the pairs of points into distance classes and calculate \(I\) for each distance class; the weight \(w_{ij} = 1\) if the distance between \(i\) and \(j\) is in the desired distance class, otherwise 0.

+
+
+

12 Spatial autoregression models

+

Let us recall the formula for a linear regression with spatial dependence:

+

\[v = \beta_0 + \sum_i \beta_i u_i + z + \epsilon\]

+

where \(z\) is the portion of the residual variance that is spatially correlated.

+

There are two main types of autoregressive models to represent the spatial dependence of \(z\): conditional autoregression (CAR) and simultaneous autoregressive (SAR).

+
+

Conditional autoregressive (CAR) model

+

In the conditional autoregressive model, the value of \(z_i\) for the region \(i\) follows a normal distribution: its mean depends on the value \(z_j\) of neighbouring regions, multiplied by the weight \(w_{ij}\) and a correlation coefficient \(\rho\); its standard deviation \(\sigma_{z_i}\) may vary from one region to another.

+

\[z_i \sim \text{N}\left(\sum_j \rho w_{ij} z_j,\sigma_{z_i} \right)\]

+

In this model, if \(w_{ij}\) is a binary matrix (0 for non-neighbours, 1 for neighbours), then \(\rho\) is the coefficient of partial correlation between neighbouring regions. This is similar to a first-order autoregressive model in the context of time series, where the autoregression coefficient indicates the partial correlation.

+
+
+

Simultaneous autoregressive (SAR) model

+

In the simultaneous autoregressive model, the value of \(z_i\) is given directly by the sum of contributions from neighbouring values \(z_j\), multiplied by \(\rho w_{ij}\), with an independent residual \(\nu_i\) of standard deviation \(\sigma_z\).

+

\[z_i = \sum_j \rho w_{ij} z_j + \nu_i\]

+

At first glance, this looks like a temporal autoregressive model. However, there is an important conceptual difference. For temporal models, the causal influence is directed in only one direction: \(v(t-2)\) affects \(v(t-1)\) which then affects \(v(t)\). For a spatial model, each \(z_j\) that affects \(z_i\) depends in turn on \(z_i\). Thus, to determine the joint distribution of \(z\), a system of equations must be solved simultaneously (hence the name of the model).

+

For this reason, although this model resembles the formula of CAR model, the solutions of the two models differ and in the case of SAR, the coefficient \(\rho\) is not directly equal to the partial correlation due to each neighbouring region.

+

For more details on the mathematical aspects of these models, see the article by Ver Hoef et al. (2018) suggested in reference.

+

For the moment, we will consider SAR and CAR as two types of possible models to represent a spatial correlation on a network. We can always fit several models and compare them with the AIC to choose the best form of correlation or the best weight matrix.

+

The CAR and SAR models share an advantage over geostatistical models in terms of efficiency. In a geostatistical model, spatial correlations are defined between each pair of points, although they become negligible as distance increases. For a CAR or SAR model, only neighbouring regions contribute and most weights are equal to 0, making these models faster to fit than a geostatistical model when the data are massive.

+
+
+
+

13 Analysis of areal data in R

+

To illustrate the analysis of areal data in R, we load the packages sf (to read geospatial data), spdep (to define spatial networks and calculate Moran’s \(I\)) and spatialreg (for SAR and CAR models).

+
+
library(sf)
+library(spdep)
+library(spatialreg)
+
+

As an example, we will use a dataset that presents some of the results of the 2018 provincial election in Quebec, with population characteristics of each riding. This data is included in a shapefile (.shp) file type, which we can read with the read_sf function of the sf package.

+
+
elect2018 <- read_sf("data/elect2018.shp")
+head(elect2018)
+
+
Simple feature collection with 6 features and 9 fields
+Geometry type: MULTIPOLYGON
+Dimension:     XY
+Bounding box:  xmin: 97879.03 ymin: 174515.3 xmax: 694261.1 ymax: 599757.1
+Projected CRS: LambertAQ
+# A tibble: 6 × 10
+  circ             age_moy pct_frn pct_prp rev_med propCAQ propPQ propPLQ propQS
+  <chr>              <dbl>   <dbl>   <dbl>   <int>   <dbl>  <dbl>   <dbl>  <dbl>
+1 Abitibi-Est         40.8   0.963   0.644   34518    42.7   19.5    18.8   15.7
+2 Abitibi-Ouest       42.2   0.987   0.735   33234    34.1   33.3    11.3   16.6
+3 Acadie              40.3   0.573   0.403   25391    16.5    9      53.8   13.8
+4 Anjou-Louis-Riel    43.5   0.821   0.416   31275    28.9   14.7    39.1   14.5
+5 Argenteuil          43.3   0.858   0.766   31097    38.9   21.1    17.4   12.2
+6 Arthabaska          43.4   0.989   0.679   30082    61.8    9.4    11.4   12.6
+# … with 1 more variable: geometry <MULTIPOLYGON [m]>
+
+
+

Note: The dataset is actually composed of 4 files with the extensions .dbf, .prj, .shp and .shx, but it is sufficient to write the name of the .shp file in read_sf.

+

The columns of the dataset are, in order:

+
    +
  • the name of the electoral riding (circ);
  • +
  • four characteristics of the population (age_moy = mean age, pct_frn = fraction of the population that speaks mainly French at home, pct_prp = fraction of households that own their home, rev_med = median income);
  • +
  • four columns showing the fraction of votes obtained by the main parties (CAQ, PQ, PLQ, QS);
  • +
  • a geometry column that contains the geometric object (multipolygon) corresponding to the riding.
  • +
+

To illustrate one of the variables on a map, we call the plot function with the name of the column in square brackets and quotation marks.

+
+
plot(elect2018["rev_med"])
+
+

+
+
+

In this example, we want to model the fraction of votes obtained by the CAQ based on the characteristics of the population in each riding and taking into account the spatial correlations between neighbouring ridings.

+
+

Definition of the neighbourhood network

+

The poly2nb function of the spdep package defines a neighbourhood network from polygons. The result vois is a list of 125 elements where each element contains the indices of the neighbouring (bordering) polygons of a given polygon.

+
+
vois <- poly2nb(elect2018)
+vois[[1]]
+
+
[1]   2  37  63  88 101 117
+
+
+

Thus, the first riding (Abitibi-Est) has 6 neighbouring ridings, for which the names can be found as follows:

+
+
elect2018$circ[vois[[1]]]
+
+
[1] "Abitibi-Ouest"               "Gatineau"                   
+[3] "Laviolette-Saint-Maurice"    "Pontiac"                    
+[5] "Rouyn-Noranda-Témiscamingue" "Ungava"                     
+
+
+

We can illustrate this network by extracting the coordinates of the center of each district, creating a blank map with plot(elect2018["geometry"]), then adding the network as an additional layer with plot(vois, add = TRUE, coords = coords).

+
+
coords <- st_centroid(elect2018) %>%
+    st_coordinates()
+plot(elect2018["geometry"])
+plot(vois, add = TRUE, col = "red", coords = coords)
+
+

+
+
+

We can “zoom” on southern Québec by choosing the limits xlim and ylim.

+
+
plot(elect2018["geometry"], 
+     xlim = c(400000, 800000), ylim = c(100000, 500000))
+plot(vois, add = TRUE, col = "red", coords = coords)
+
+

+
+
+

We still have to add weights to each network link with the nb2listw function. The style of weights “B” corresponds to binary weights, i.e. 1 for the presence of link and 0 for the absence of link between two ridings.

+

Once these weights are defined, we can verify with Moran’s test whether there is a significant autocorrelation of votes obtained by the CAQ between neighbouring ridings.

+
+
poids <- nb2listw(vois, style = "B")
+
+moran.test(elect2018$propCAQ, poids)
+
+

+    Moran I test under randomisation
+
+data:  elect2018$propCAQ  
+weights: poids    
+
+Moran I statistic standard deviate = 13.148, p-value < 2.2e-16
+alternative hypothesis: greater
+sample estimates:
+Moran I statistic       Expectation          Variance 
+      0.680607768      -0.008064516       0.002743472 
+
+
+

The value \(I = 0.68\) is very significant judging by the \(p\)-value of the test.

+

Let’s verify if the spatial correlation persists after taking into account the four characteristics of the population, therefore by inspecting the residuals of a linear model including these four predictors.

+
+
elect_lm <- lm(propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, data = elect2018)
+summary(elect_lm)
+
+

+Call:
+lm(formula = propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, 
+    data = elect2018)
+
+Residuals:
+     Min       1Q   Median       3Q      Max 
+-30.9890  -4.4878   0.0562   6.2653  25.8146 
+
+Coefficients:
+              Estimate Std. Error t value Pr(>|t|)    
+(Intercept)  1.354e+01  1.836e+01   0.737    0.463    
+age_moy     -9.170e-01  3.855e-01  -2.378    0.019 *  
+pct_frn      4.588e+01  5.202e+00   8.820 1.09e-14 ***
+pct_prp      3.582e+01  6.527e+00   5.488 2.31e-07 ***
+rev_med     -2.624e-05  2.465e-04  -0.106    0.915    
+---
+Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+
+Residual standard error: 9.409 on 120 degrees of freedom
+Multiple R-squared:  0.6096,    Adjusted R-squared:  0.5965 
+F-statistic: 46.84 on 4 and 120 DF,  p-value: < 2.2e-16
+
+
moran.test(residuals(elect_lm), poids)
+
+

+    Moran I test under randomisation
+
+data:  residuals(elect_lm)  
+weights: poids    
+
+Moran I statistic standard deviate = 6.7047, p-value = 1.009e-11
+alternative hypothesis: greater
+sample estimates:
+Moran I statistic       Expectation          Variance 
+      0.340083290      -0.008064516       0.002696300 
+
+
+

Moran’s \(I\) has decreased but remains significant, so some of the previous correlation was induced by these predictors, but there remains a spatial correlation due to other factors.

+
+
+

Spatial autoregression models

+

Finally, we fit SAR and CAR models to these data with the spautolm (spatial autoregressive linear model) function of spatialreg. Here is the code for a SAR model including the effect of the same four predictors.

+
+
elect_sar <- spautolm(propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, 
+                      data = elect2018, listw = poids)
+summary(elect_sar)
+
+

+Call: spautolm(formula = propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, 
+    data = elect2018, listw = poids)
+
+Residuals:
+      Min        1Q    Median        3Q       Max 
+-23.08342  -4.10573   0.24274   4.29941  23.08245 
+
+Coefficients: 
+               Estimate  Std. Error z value  Pr(>|z|)
+(Intercept) 15.09421119 16.52357745  0.9135   0.36098
+age_moy     -0.70481703  0.32204139 -2.1886   0.02863
+pct_frn     39.09375061  5.43653962  7.1909 6.435e-13
+pct_prp     14.32329345  6.96492611  2.0565   0.03974
+rev_med      0.00016730  0.00023209  0.7208   0.47101
+
+Lambda: 0.12887 LR test value: 42.274 p-value: 7.9339e-11 
+Numerical Hessian standard error of lambda: 0.012069 
+
+Log likelihood: -433.8862 
+ML residual variance (sigma squared): 53.028, (sigma: 7.282)
+Number of observations: 125 
+Number of parameters estimated: 7 
+AIC: 881.77
+
+
+

The value given by Lambda in the summary corresponds to the coefficient \(\rho\) in our description of the model. The likelihood-ratio test (LR test) confirms that this residual spatial correlation (after controlling for the effect of predictors) is significant.

+

The estimated effects for the predictors are similar to those of the linear model without spatial correlation. The effects of mean age, fraction of francophones and fraction of homeowners remain significant, although their magnitude has decreased somewhat.

+

To fit a CAR rather than SAR model, we must specify family = "CAR".

+
+
elect_car <- spautolm(propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, 
+                      data = elect2018, listw = poids, family = "CAR")
+summary(elect_car)
+
+

+Call: spautolm(formula = propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, 
+    data = elect2018, listw = poids, family = "CAR")
+
+Residuals:
+      Min        1Q    Median        3Q       Max 
+-21.73315  -4.24623  -0.24369   3.44228  23.43749 
+
+Coefficients: 
+               Estimate  Std. Error z value  Pr(>|z|)
+(Intercept) 16.57164696 16.84155327  0.9840  0.325128
+age_moy     -0.79072151  0.32972225 -2.3981  0.016478
+pct_frn     38.99116707  5.43667482  7.1719 7.399e-13
+pct_prp     17.98557474  6.80333470  2.6436  0.008202
+rev_med      0.00012639  0.00023106  0.5470  0.584364
+
+Lambda: 0.15517 LR test value: 40.532 p-value: 1.9344e-10 
+Numerical Hessian standard error of lambda: 0.0026868 
+
+Log likelihood: -434.7573 
+ML residual variance (sigma squared): 53.9, (sigma: 7.3416)
+Number of observations: 125 
+Number of parameters estimated: 7 
+AIC: 883.51
+
+
+

For a CAR model with binary weights, the value of Lambda (which we called \(\rho\)) directly gives the partial correlation coefficient between neighbouring districts. Note that the AIC here is slightly higher than the SAR model, so the latter gave a better fit.

+
+
+

Exercise

+

The rls_covid dataset, in shapefile format, contains data on detected COVID-19 cases (cas), number of cases per 1000 people (taux_1k) and the population density (dens_pop) in each of Quebec’s local health service networks (RLS) (Source: Data downloaded from the Institut national de santé publique du Québec as of January 17, 2021).

+
+
rls_covid <- read_sf("data/rls_covid.shp")
+head(rls_covid)
+
+
Simple feature collection with 6 features and 5 fields
+Geometry type: MULTIPOLYGON
+Dimension:     XY
+Bounding box:  xmin: 785111.2 ymin: 341057.8 xmax: 979941.5 ymax: 541112.7
+Projected CRS: Conique_conforme_de_Lambert_du_MTQ_utilis_e_pour_Adresse_Qu_be
+# A tibble: 6 × 6
+  RLS_code RLS_nom                 cas taux_1k dens_…¹                  geometry
+  <chr>    <chr>                 <dbl>   <dbl>   <dbl>        <MULTIPOLYGON [m]>
+1 0111     RLS de Kamouraska       152    7.34    6.76 (((827028.3 412772.4, 82…
+2 0112     RLS de Rivière-du-Lo…   256    7.34   19.6  (((855905 452116.9, 8557…
+3 0113     RLS de Témiscouata       81    4.26    4.69 (((911829.4 441311.2, 91…
+4 0114     RLS des Basques          28    3.3     5.35 (((879249.6 471975.6, 87…
+5 0115     RLS de Rimouski         576    9.96   15.5  (((917748.1 503148.7, 91…
+6 0116     RLS de La Mitis          76    4.24    5.53 (((951316 523499.3, 9525…
+# … with abbreviated variable name ¹​dens_pop
+
+
+

Fit a linear model of the number of cases per 1000 as a function of population density (it is suggested to apply a logarithmic transform to the latter). Check whether the model residuals are correlated between bordering RLS with a Moran’s test and then model the same data with a conditional autoregressive model.

+
+
+

Reference

+

Ver Hoef, J.M., Peterson, E.E., Hooten, M.B., Hanks, E.M. and Fortin, M.-J. (2018) Spatial autoregressive models for statistical inference from ecological data. Ecological Monographs 88: 36-59.

+
+
+
+

14 GLMM with spatial Gaussian process

+
+

Data

+

The gambia dataset found in the geoR package presents the results of a study of malaria prevalence among children of 65 villages in The Gambia. We will use a slightly transformed version of the data found in the file gambia.csv.

+
+
library(geoR)
+
+gambia <- read.csv("data/gambia.csv")
+head(gambia)
+
+
  id_village        x        y pos  age netuse treated green phc
+1          1 349.6313 1458.055   1 1783      0       0 40.85   1
+2          1 349.6313 1458.055   0  404      1       0 40.85   1
+3          1 349.6313 1458.055   0  452      1       0 40.85   1
+4          1 349.6313 1458.055   1  566      1       0 40.85   1
+5          1 349.6313 1458.055   0  598      1       0 40.85   1
+6          1 349.6313 1458.055   1  590      1       0 40.85   1
+
+
+

Here are the fields in that dataset:

+
    +
  • id_village: Identifier of the village.
  • +
  • x and y: Spatial coordinates of the village (in kilometers, based on UTM coordinates).
  • +
  • pos: Binary response, whether the child tested positive for malaria.
  • +
  • age: Age of the child in days.
  • +
  • netuse: Whether or not the child sleeps under a bed net.
  • +
  • treated: Whether or not the bed net is treated.
  • +
  • green: Remote sensing based measure of greenness of vegetation (measured at the village level).
  • +
  • phc: Presence or absence of a public health centre for the village.
  • +
+

We can count the number of positive cases and total children tested by village to map the fraction of positive cases (or prevalence, prev).

+
+
# Create village-level dataset
+gambia_agg <- group_by(gambia, id_village, x, y, green, phc) %>%
+    summarize(pos = sum(pos), total = n()) %>%
+    mutate(prev = pos / total) %>%
+    ungroup()
+
+
`summarise()` has grouped output by 'id_village', 'x', 'y', 'green'. You can
+override using the `.groups` argument.
+
+
head(gambia_agg)
+
+
# A tibble: 6 × 8
+  id_village     x     y green   phc   pos total  prev
+       <int> <dbl> <dbl> <dbl> <int> <int> <int> <dbl>
+1          1  350. 1458.  40.8     1    17    33 0.515
+2          2  359. 1460.  40.8     1    19    63 0.302
+3          3  360. 1460.  40.1     0     7    17 0.412
+4          4  364. 1497.  40.8     0     8    24 0.333
+5          5  366. 1460.  40.8     0    10    26 0.385
+6          6  367. 1463.  40.8     0     7    18 0.389
+
+
+
+
ggplot(gambia_agg, aes(x = x, y = y)) +
+    geom_point(aes(color = prev)) +
+    geom_path(data = gambia.borders, aes(x = x / 1000, y = y / 1000)) +
+    coord_fixed() +
+    theme_minimal() +
+    scale_color_viridis_c()
+
+

+
+
+

We use the gambia.borders dataset from the geoR package to trace the country boundaries with geom_path. Since those boundaries are in meters, we divide by 1000 to get the same scale as our points. We also use coord_fixed to ensure a 1:1 aspect ratio between the axes and use the viridis color scale, which makes it easier to visualize a continuous variable compared with the default gradient scale in ggplot2.

+

Based on this map, there seems to be spatial correlation in malaria prevalence, with the eastern cluster of villages showing more high prevalence values (yellow-green) and the middle cluster showing more low prevalence values (purple).

+
+
+

Non-spatial GLMM

+

For this first example, we will ignore the spatial aspect of the data and model the presence of malaria (pos) as a function of the use of a bed net (netuse) and the presence of a public health centre (phc). Since we have a binary response, we need to use a logistic regression model (a GLM). Since we have predictors at both the individual and village level, and we expect that children of the same village have more similar probabilities of having malaria even after accounting for those predictors, we need to add a random effect of the village. The result is a GLMM that we fit using the glmer function in the lme4 package.

+
+
library(lme4)
+
+mod_glmm <- glmer(pos ~ netuse + phc + (1 | id_village), 
+                  data = gambia, family = binomial)
+summary(mod_glmm)
+
+
Generalized linear mixed model fit by maximum likelihood (Laplace
+  Approximation) [glmerMod]
+ Family: binomial  ( logit )
+Formula: pos ~ netuse + phc + (1 | id_village)
+   Data: gambia
+
+     AIC      BIC   logLik deviance df.resid 
+  2428.0   2450.5  -1210.0   2420.0     2031 
+
+Scaled residuals: 
+    Min      1Q  Median      3Q     Max 
+-2.1286 -0.7120 -0.4142  0.8474  3.3434 
+
+Random effects:
+ Groups     Name        Variance Std.Dev.
+ id_village (Intercept) 0.8149   0.9027  
+Number of obs: 2035, groups:  id_village, 65
+
+Fixed effects:
+            Estimate Std. Error z value Pr(>|z|)    
+(Intercept)   0.1491     0.2297   0.649   0.5164    
+netuse       -0.6044     0.1442  -4.190 2.79e-05 ***
+phc          -0.4985     0.2604  -1.914   0.0556 .  
+---
+Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+
+Correlation of Fixed Effects:
+       (Intr) netuse
+netuse -0.422       
+phc    -0.715 -0.025
+
+
+

According to these results, both netuse and phc result in a decrease of malaria prevalence, although the effect of phc is not significant at a threshold \(\alpha = 0.05\). The intercept (0.149) is the logit of the probability of malaria presence for a child with no bednet and no public health centre, but it is the mean intercept across all villages, and there is a lot of variation between villages, based on the random effect standard deviation of 0.90. We can get the estimated intercept for each village with the function coef:

+
+
head(coef(mod_glmm)$id_village)
+
+
  (Intercept)     netuse        phc
+1  0.93727515 -0.6043602 -0.4984835
+2  0.09204843 -0.6043602 -0.4984835
+3  0.22500620 -0.6043602 -0.4984835
+4 -0.46271089 -0.6043602 -0.4984835
+5  0.13680037 -0.6043602 -0.4984835
+6 -0.03723346 -0.6043602 -0.4984835
+
+
+

So for example, the intercept for village 1 is around 0.94, equivalent to a probability of 72%:

+
+
plogis(0.937)
+
+
[1] 0.7184933
+
+
+

while the intercept in village 2 is equivalent to a probability of 52%:

+
+
plogis(0.092)
+
+
[1] 0.5229838
+
+
+

The DHARMa package provides a general method for checking whether the residuals of a GLMM are distributed according to the specified model and whether there is any residual trend. The package works by simulating replicates of each observation according to the fitted model and then determining a “standardized residual”, which is the relative position of the observed value with respect to the simulated values, e.g. 0 if the observation is smaller than all the simulations, 0.5 if it is in the middle, etc. If the model represents the data well, each value of the standardized residual between 0 and 1 should be equally likely, so the standardized residuals should produce a uniform distribution between 0 and 1.

+

The simulateResiduals function performs the calculation of the standardized residuals, then the plot function plots the diagnostic graphs with the results of certain tests.

+
+
library(DHARMa)
+res_glmm <- simulateResiduals(mod_glmm)
+plot(res_glmm)
+
+

+
+
+

The graph on the left is a quantile-quantile plot of standardized residuals. The results of three statistical tests also also shown: a Kolmogorov-Smirnov (KS) test which checks whether there is a deviation from the theoretical distribution, a dispersion test that checks whether there is underdispersion or overdispersion, and an outlier test based on the number of residuals that are more extreme than all the simulations. Here, we get a significant result for the outliers, though the message indicates that this result might have an inflated type I error rate in this case.

+

On the right, we generally get a graph of standardized residuals (in y) as a function of the rank of the predicted values, in order to check for any leftover trend in the residual. Here, the predictions are binned by quartile, so it might be better to instead aggregate the predictions and residuals by village, which we can do with the recalculateResiduals function.

+
+
plot(recalculateResiduals(res_glmm, group = gambia$id_village))
+
+
DHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details
+
+
+

+
+
+

The plot to the right now shows individual points, along with a quantile regression for the 1st quartile, the median and the 3rd quartile. In theory, these three curves should be horizontal straight lines (no leftover trend in the residuals vs. predictions). The curve for the 3rd quartile (in red) is significantly different from a horizontal line, which could indicate some systematic effect that is missing from the model.

+
+
+

Spatial GLMM with spaMM

+

The spaMM (spatial mixed models) package is a relatively new R package that can perform approximate maximum likelihood estimation of parameters for GLMM with spatial dependence, modelled either as a Gaussian process or with a CAR (we will see the latter in the last section). The package implements different algorithms, but there is a single fitme function that chooses the appropriate algorithm for each model type. For example, here is the same (non-spatial) model as above fit with spaMM.

+
+
library(spaMM)
+
+mod_spamm_glmm <- fitme(pos ~ netuse + phc + (1 | id_village),
+                        data = gambia, family = binomial)
+summary(mod_spamm_glmm)
+
+
formula: pos ~ netuse + phc + (1 | id_village)
+Estimation of lambda by ML (p_v approximation of logL).
+Estimation of fixed effects by ML (p_v approximation of logL).
+family: binomial( link = logit ) 
+ ------------ Fixed effects (beta) ------------
+            Estimate Cond. SE t-value
+(Intercept)   0.1491   0.2287  0.6519
+netuse       -0.6045   0.1420 -4.2567
+phc          -0.4986   0.2593 -1.9231
+ --------------- Random effects ---------------
+Family: gaussian( link = identity ) 
+           --- Variance parameters ('lambda'):
+lambda = var(u) for u ~ Gaussian; 
+   id_village  :  0.8151  
+             --- Coefficients for log(lambda):
+      Group        Term Estimate Cond.SE
+ id_village (Intercept)  -0.2045  0.2008
+# of obs: 2035; # of groups: id_village, 65 
+ ------------- Likelihood values  -------------
+                        logLik
+logL       (p_v(h)): -1210.016
+
+
+

Note that the estimates of the fixed effects as well as the variance of random effects are nearly identical to those obtained by glmer above.

+

We can now use spaMM to fit the same model with the addition of spatial correlations between villages. In the formula of the model, this is represented as a random effect Matern(1 | x + y), which means that the intercepts are spatially correlated between villages following a Matérn correlation function of coordinates (x, y). The Matérn function is a flexible function for spatial correlation that includes a shape parameter \(\nu\) (nu), so that when \(\nu = 0.5\) it is equivalent to the exponential correlation but as \(\nu\) grows to large values, it approaches a Gaussian correlation. We could let the function estimate \(\nu\), but here we will fix it to 0.5 with the fixed argument of fitme.

+
+
mod_spamm <- fitme(pos ~ netuse + phc + Matern(1 | x + y) + (1 | id_village),
+                   data = gambia, family = binomial, fixed = list(nu = 0.5))
+
+
Increase spaMM.options(separation_max=<.>) to at least 21 if you want to check separation (see 'help(separation)').
+
+
summary(mod_spamm)
+
+
formula: pos ~ netuse + phc + Matern(1 | x + y) + (1 | id_village)
+Estimation of corrPars and lambda by ML (p_v approximation of logL).
+Estimation of fixed effects by ML (p_v approximation of logL).
+Estimation of lambda by 'outer' ML, maximizing logL.
+family: binomial( link = logit ) 
+ ------------ Fixed effects (beta) ------------
+            Estimate Cond. SE t-value
+(Intercept)  0.06861   0.3352  0.2047
+netuse      -0.51719   0.1407 -3.6757
+phc         -0.44416   0.2052 -2.1648
+ --------------- Random effects ---------------
+Family: gaussian( link = identity ) 
+                   --- Correlation parameters:
+      1.nu      1.rho 
+0.50000000 0.05128692 
+           --- Variance parameters ('lambda'):
+lambda = var(u) for u ~ Gaussian; 
+   x + y  :  0.6421 
+   id_village  :  0.1978  
+# of obs: 2035; # of groups: x + y, 65; id_village, 65 
+ ------------- Likelihood values  -------------
+                        logLik
+logL       (p_v(h)): -1197.968
+
+
+

Let’s first check the random effects of the model. The spatial correlation function has a parameter rho equal to 0.0513. This parameter in spaMM is the inverse of the range, so here the range of exponential correlation is 1/0.0513 or around 19.5 km. There are now two variance prameters, the one identified as x + y is the long-range variance (i.e. sill) for the exponential correlation model whereas the one identified as id_village shows the non-spatially correlated portion of the variation between villages.

+

In fact, while we left the random effects (1 | id_village) in the formula to represent the non-spatial portion of variation between villages, we could also represent this with a nugget effect in the geostatistical model. In both cases, it would represent the idea that even two villages very close to each other would have different baseline prevalences in the model.

+

By default, the Matern function has no nugget effect, but we can add one by specifying a non-zero Nugget in the initial parameter list init.

+
+
mod_spamm2 <- fitme(pos ~ netuse + phc + Matern(1 | x + y),
+                    data = gambia, family = binomial, fixed = list(nu = 0.5),
+                    init = list(Nugget = 0.1))
+
+
Increase spaMM.options(separation_max=<.>) to at least 21 if you want to check separation (see 'help(separation)').
+
+
summary(mod_spamm2)
+
+
formula: pos ~ netuse + phc + Matern(1 | x + y)
+Estimation of corrPars and lambda by ML (p_v approximation of logL).
+Estimation of fixed effects by ML (p_v approximation of logL).
+Estimation of lambda by 'outer' ML, maximizing logL.
+family: binomial( link = logit ) 
+ ------------ Fixed effects (beta) ------------
+            Estimate Cond. SE t-value
+(Intercept)  0.06861   0.3352  0.2047
+netuse      -0.51719   0.1407 -3.6757
+phc         -0.44416   0.2052 -2.1648
+ --------------- Random effects ---------------
+Family: gaussian( link = identity ) 
+                   --- Correlation parameters:
+      1.nu   1.Nugget      1.rho 
+0.50000000 0.23551027 0.05128692 
+           --- Variance parameters ('lambda'):
+lambda = var(u) for u ~ Gaussian; 
+   x + y  :  0.8399  
+# of obs: 2035; # of groups: x + y, 65 
+ ------------- Likelihood values  -------------
+                        logLik
+logL       (p_v(h)): -1197.968
+
+
+

As you can see, all estimates are the same, except that the variance of the spatial portion (sill) is now 0.84 and the nugget is equal to a fraction 0.235 of that sill, so a variance of 0.197, which is the same as the id_village random effect in the version above. Thus the two formulations are equivalent.

+

Now, recall the coefficients we obtained for the non-spatial GLMM:

+
+
summary(mod_glmm)$coefficients
+
+
              Estimate Std. Error    z value     Pr(>|z|)
+(Intercept)  0.1490596  0.2296971  0.6489399 5.163772e-01
+netuse      -0.6043602  0.1442448 -4.1898243 2.791706e-05
+phc         -0.4984835  0.2604083 -1.9142382 5.558973e-02
+
+
+

In the spatial version, both fixed effects have moved slightly towards zero, but the standard error of the effect of phc has decreased. It is interesting that the inclusion of spatial dependence has allowed us to estimate more precisely the effect of having a public health centre in the village. This would not always be the case: for a predictor that is also strongly correlated in space, spatial correlation in the response makes it harder to estimate the effect of this predictor, since it is confounded with the spatial effect. However, for a predictor that is not correlated in space, including the spatial effect reduces the residual (non-spatial) variance and may thus increase the precision of the predictor’s effect.

+

The spaMM package is also compatible with DHARMa for residual diagnostics. (You can in fact ignore the warning that it is not in the class of supported models, this is due to using the fitme function rather than a specific algorithm function in spaMM.)

+
+
res_spamm <- simulateResiduals(mod_spamm2)
+plot(res_spamm)
+
+
DHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details
+
+
+

+
+
plot(recalculateResiduals(res_spamm, group = gambia$id_village))
+
+
DHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details
+
+
+

+
+
+

Finally, while we will show how to make and visualize spatial predictions below, we can produce a quick map of the estimated spatial effects in a spaMM model with the filled.mapMM function.

+
+
filled.mapMM(mod_spamm2)
+
+

+
+
+
+
+

Gaussian process models vs. smoothing splines

+

If you are familiar with generalized additive models (GAM), you might think that the spatial variation in malaria prevalence (as shown in the map above) could be represented by a 2D smoothing spline (as a function of \(x\) and \(y\)) within a GAM.

+

The code below fits the GAM equivalent of our Gaussian process GLMM above with the gam function in the mgcv package. The spatial effect is represented by the 2D spline s(x, y) whereas the non-spatial random effect of village is represented by s(id_village, bs = "re"), which is the same as (1 | id_village) in the previous models. Note that for the gam function, categorical variables must be explicitly converted to factors.

+
+
library(mgcv)
+gambia$id_village <- as.factor(gambia$id_village)
+mod_gam <- gam(pos ~ netuse + phc + s(id_village, bs = "re") + s(x, y), 
+               data = gambia, family = binomial)
+
+

To visualize the 2D spline, we will use the gratia package.

+
+
library(gratia)
+draw(mod_gam)
+
+

+
+
+

Note that the plot of the spline s(x, y) (top right) does not extend too far from the locations of the data (other areas are blank). In this graph, we can also see that the village random effects follow the expected Gaussian distribution (top left).

+

Next, we will use both the spatial GLMM from the previous section and this GAMM to predict the mean prevalence on a spatial grid of points contained in the file gambia_pred.csv. The graph below adds those prediction points (in black) on the previous map of the data points.

+
+
gambia_pred <- read.csv("data/gambia_pred.csv")
+
+ggplot(gambia_agg, aes(x = x, y = y)) +
+    geom_point(data = gambia_pred) +
+    geom_point(aes(color = prev)) +
+    geom_path(data = gambia.borders, aes(x = x / 1000, y = y / 1000)) +
+    coord_fixed() +
+    theme_minimal() +
+    scale_color_viridis_c()
+
+

+
+
+

To make predictions from the GAMM model at those points, the code below goes through the following steps:

+
    +
  • All predictors in the model must be in the prediction data frame, so we add constant values of netuse and phc (both equal to 1) for all points. Thus, we will make predictions of malaria prevalence in the case where a net is used and a public health centre is present. We also add a constant id_village, although it will not be used in predictions (see below).

  • +
  • We call the predict function on the output of gam to produce predictions at the new data points (argument newdata), including standard errors (se.fit = TRUE) and excluding the village random effects, so the prediction is made for an “average village”. The resulting object gam_pred will have columns fit (mean prediction) and se.fit (standard error). Those predictions and standard errors are on the link (logit) scale.

  • +
  • We add the original prediction data frame to gam_pred with cbind.

  • +
  • We add columns for the mean prediction and 50% confidence interval boundaries (mean \(\pm\) 0.674 standard error), converted from the logit scale to the probability scale with plogis. We choose a 50% interval since a 95% interval may be too wide here to contrast the different predictions on the map at the end of this section.

  • +
+
+
gambia_pred <- mutate(gambia_pred, netuse = 1, phc = 1, id_village = 1)
+
+gam_pred <- predict(mod_gam, newdata = gambia_pred, se.fit = TRUE, 
+                    exclude = "s(id_village)")
+gam_pred <- cbind(gambia_pred, as.data.frame(gam_pred))
+gam_pred <- mutate(gam_pred, pred = plogis(fit), 
+                   lo = plogis(fit - 0.674 * se.fit), # 50% CI
+                   hi = plogis(fit + 0.674 * se.fit))
+
+

Note: The reason we do not make predictions directly on the probability (response) scale is that the normal formula for confidence intervals applies more accurately on the logit scale. Adding a certain number of standard errors around the mean on the probability scale would lead to less accurate intervals and maybe even confidence intervals outside the possible range (0, 1) for a probability.

+

We apply the same strategy to make predictions from the spaMM spatial GLMM model. There are a few differences in the predict method compared with the GAMM case.

+
    +
  • The argument binding = "fit" means that mean predictions (fit column) will be attached to the prediction dataset and returned as spamm_pred.

  • +
  • The variances = list(linPred = TRUE) tells predict to calculate the variance of the linear predictor (so the square of the standard error). However, it appears as an attribute predVar in the output data frame rather than a se.fit column, so we move it to a column on the next line.

  • +
+
+
spamm_pred <- predict(mod_spamm, newdata = gambia_pred, type = "link",
+                      binding = "fit", variances = list(linPred = TRUE))
+spamm_pred$se.fit <- sqrt(attr(spamm_pred, "predVar"))
+spamm_pred <- mutate(spamm_pred, pred = plogis(fit), 
+                     lo = plogis(fit - 0.674 * se.fit),
+                     hi = plogis(fit + 0.674 * se.fit))
+
+

Finally, we combine both sets of predictions as different rows of a pred_all dataset with bind_rows. The name of the dataset each prediction originates from (gam or spamm) will appear in the “model” column (argument .id). To simplify production of the next plot, we then use pivot_longer in the tidyr package to change the three columns “pred”, “lo” and “hi” to two columns, “stat” and “value” (pred_tall has thus three rows for every row in pred_all).

+
+
pred_all <- bind_rows(gam = gam_pred, spamm = spamm_pred, .id = "model")
+
+library(tidyr)
+pred_tall <- pivot_longer(pred_all, c(pred, lo, hi), names_to = "stat",
+                          values_to = "value")
+
+

Having done these steps, we can finally look at the prediction maps (mean, lower and upper bounds of the 50% confidence interval) with ggplot. The original data points are shown in red.

+
+
ggplot(pred_tall, aes(x = x, y = y)) +
+    geom_point(aes(color = value)) +
+    geom_point(data = gambia_agg, color = "red", size = 0) +
+    coord_fixed() +
+    facet_grid(stat~model) +
+    scale_color_viridis_c() +
+    theme_minimal()
+
+

+
+
+

While both models agree that there is a higher prevalence near the eastern cluster of villages, the GAMM also estimates a higher prevalence at a few points (western edge and around the center) where there is no data. This is an artifact of the shape of the spline fit around the data points, since a spline is meant to fit a global, although nonlinear, trend. In contrast, the geostatistical model represents the spatial effect as local correlations and reverts to the overall mean prevalence when far from any data points, which is a safer assumption. This is one reason to choose a geostatistical / Gaussian process model in this case.

+
+
+

Bayesian methods for GLMMs with Gaussian processes

+

Bayesian models provide a flexible framework to express models with complex dependence structure among the data, including spatial dependence. However, fitting a Gaussian process model with a fully Bayesian approach can be slow, due the need to compute a spatial covariance matrix between all point pairs at each iteration.

+

The INLA (integrated nested Laplace approximation) method performs an approximate calculation of the Bayesian posterior distribution, which makes it suitable for spatial regression problems. We do not cover it in this course, but I recommend the textbook by Paula Moraga (in the references section below) that provides worked examples of using INLA for various geostatistical and areal data models, in the context of epidemiology, including models with both space and time dependence. The book presents the same Gambia malaria data as an example of a geostatistical dataset, which inspired its use in this course.

+
+
+
+

15 GLMM with spatial autoregression

+

We return to the last example of the previous part, where we modelled the rate of COVID-19 cases (cases / 1000) for administrative health network divisions (RLS) in Quebec as a function of their population density. The rate is given by the “taux_1k” column in the rls_covid shapefile.

+
+
library(sf)
+rls_covid <- read_sf("data/rls_covid.shp")
+rls_covid <- rls_covid[!is.na(rls_covid$dens_pop), ]
+plot(rls_covid["taux_1k"])
+
+

+
+
+

Previously, we modelled the logarithm of this rate as a linear function of the logarithm of population density, with the residual variance correlated among neighbouring units via a CAR (conditional autoregression) structure, as shown in the code below.

+
+
library(spdep)
+library(spatialreg)
+
+rls_nb <- poly2nb(rls_covid)
+rls_w <- nb2listw(rls_nb, style = "B")
+
+car_lm <- spautolm(log(taux_1k) ~ log(dens_pop), data = rls_covid,
+                   listw = rls_w, family = "CAR")
+summary(car_lm)
+
+

+Call: spautolm(formula = log(taux_1k) ~ log(dens_pop), data = rls_covid, 
+    listw = rls_w, family = "CAR")
+
+Residuals:
+      Min        1Q    Median        3Q       Max 
+-1.201858 -0.254084 -0.053348  0.281482  1.427053 
+
+Coefficients: 
+              Estimate Std. Error z value  Pr(>|z|)
+(Intercept)   1.702068   0.168463 10.1035 < 2.2e-16
+log(dens_pop) 0.206623   0.032848  6.2903 3.169e-10
+
+Lambda: 0.15762 LR test value: 23.991 p-value: 9.6771e-07 
+Numerical Hessian standard error of lambda: 0.0050486 
+
+Log likelihood: -80.68953 
+ML residual variance (sigma squared): 0.2814, (sigma: 0.53048)
+Number of observations: 95 
+Number of parameters estimated: 4 
+AIC: 169.38
+
+
+

As a reminder, the poly2nb function in the spdep package creates a list of neighbours based on bordering polygons in a shapefile, then the nb2listw converts it to a list of weights, here binary weights (style = "B") so that each bordering region receives the same weight of 1 in the autoregressive model.

+

Instead of using the rates, it would be possible to model the cases directly (column “cas” in the dataset) with a Poisson regression, which is appropriate for count data. To account for the fact that if the risk per person were equal, cases would be proportional to population, we can add the unit’s population pop as an offset in the Poisson regression. Therefore, the model would look like: cas ~ log(dens_pop) + offset(log(pop)). Note that since the Poisson regression uses a logarithmic link, that model with log(pop) as an offset assumes that log(cas / pop) (so the log rate) is proportional to log(dens_pop), just like the linear model above, but it has the advantage of modelling the stochasticity of the raw data (the number of cases) directly with a Poisson distribution.

+

We do not have the population in this data, but we can estimate it from the cases and the rate (cases / 1000) as follows:

+
+
rls_covid$pop <- rls_covid$cas / rls_covid$taux_1k * 1000
+
+

To define a CAR model in spaMM, we need a weights matrix rather than a list of weights as in the spatialreg package. Fortunately, the spdep package also includes a function nb2mat to convert the neighbours list to a matrix of weights, here again using binary weights. To avoid a warning, we specify the row and column names of that matrix to be equal to the IDs associated with each unit (RLS_code). Then, we add a term adjacency(1 | RLS_code) to the model to specify that the residual variation between different groups defined by RLS_code is spatially correlated with a CAR structure (here, each group has only one observation since we have one data point by RLS unit).

+
+
library(spaMM)
+
+rls_mat <- nb2mat(rls_nb, style = "B")
+rownames(rls_mat) <- rls_covid$RLS_code
+colnames(rls_mat) <- rls_covid$RLS_code
+
+rls_spamm <- fitme(cas ~ log(dens_pop) + offset(log(pop)) + adjacency(1 | RLS_code),
+                   data = rls_covid, adjMatrix = rls_mat, family = poisson)
+summary(rls_spamm)
+
+
formula: cas ~ log(dens_pop) + offset(log(pop)) + adjacency(1 | RLS_code)
+Estimation of corrPars and lambda by ML (p_v approximation of logL).
+Estimation of fixed effects by ML (p_v approximation of logL).
+Estimation of lambda by 'outer' ML, maximizing logL.
+family: poisson( link = log ) 
+ ------------ Fixed effects (beta) ------------
+              Estimate Cond. SE t-value
+(Intercept)    -5.1618  0.16855 -30.625
+log(dens_pop)   0.1999  0.03267   6.119
+ --------------- Random effects ---------------
+Family: gaussian( link = identity ) 
+                   --- Correlation parameters:
+    1.rho 
+0.1576605 
+           --- Variance parameters ('lambda'):
+lambda = var(u) for u ~ Gaussian; 
+   RLS_code  :  0.266  
+# of obs: 95; # of groups: RLS_code, 95 
+ ------------- Likelihood values  -------------
+                        logLik
+logL       (p_v(h)): -709.3234
+
+
+

Note that the spatial correlation coefficient rho (0.158) is similar to the equivalent quantity in the spautolm model above, where it was called Lambda. The effect of log(dens_pop) is also approximately 0.2 in both models.

+
+

Reference

+

Moraga, Paula (2019) Geospatial Health Data: Modeling and Visualization with R-INLA and Shiny. Chapman & Hall/CRC Biostatistics Series. Available online at https://www.paulamoraga.com/book-geospatial/.

+
+
+
+
+

16 Statistiques spatiales en écologie

+

BIOS² a organisé une session de formation en ligne sur l’analyse statistique des données spatiales en écologie, animée par le Pr. Philippe Marchand (UQAT). Cette formation de 12 heures s’est déroulée en 4 sessions : 12, 14, 19 & 21 janvier (2021) de 13h00 à 16h00 HNE.

+

Le contenu comprenait trois types d’analyses statistiques spatiales et leurs applications en écologie : (1) l’analyse des patrons de points qui permet d’étudier la distribution d’individus ou d’événements dans l’espace; (2) les modèles géostatistiques qui représentent la corrélation spatiale de variables échantillonnées à des points géoréférencés; et (3) les modèles de données aréales, qui s’appliquent aux mesures prises sur des régions de l’espace et qui représentent les liens spatiaux par le biais de réseaux de voisinage. La formation comprenait également des exercices pratiques utilisant l’environnement de programmation statistique R.

+

Philippe Marchand est professeur d’écologie et de biostatistique à l’Institut de recherche sur les forêts, Université du Québec en Abitibi-Témiscamingue (UQAT) et membre académique de BIOS². Ses travaux de recherche portent sur la modélisation de processus qui influencent la distribution spatiale des populations, incluant: la dispersion des graines et l’établissement des semis, le mouvement des animaux, et la propagation des épidémies forestières.

+

Si vous souhaitez consulter le matériel pédagogique et suivre les exercices à votre propre rythme, vous pouvez y accéder par ce lien. Une connaissance de base des modèles de régression linéaire et une expérience de l’ajustement de ces modèles dans R sont recommandées. Le repositoire original se trouve ici.

+
+

Plan du cours

+ + + + + + + + + + + + + + + + + + + + + + + + + +
JourSujets
1Introduction aux statistiques spatiales
Analyse des patrons de points
2Corrélation spatiale d’une variable
Modèles géostatistiques
3Données aréales
Indice de Moran
Modèles d’autorégression spatiale
Analyse des données aréales dans R
4GLMM avec processus spatial gaussien
GLMM avec autorégression spatiale
+
+
+
+

17 Introduction aux statistiques spatiales

+
+

Types d’analyses spatiales

+

Dans le cadre de cette formation, nous discuterons de trois types d’analyses spatiales: l’analyse des patrons de points, les modèles géostatistiques et les modèles de données aréales.

+

Dans l’analyse des patrons de points, nous avons des données ponctuelles représentant la position d’individus ou d’événements dans une région d’étude et nous supposons que tous les individus ou événements ont été recensés dans cette région. Cette analyse s’intéresse à la distribution des positions des points eux-mêmes. Voici quelques questions typiques de l’analyse des patrons de points:

+
    +
  • Les points sont-ils disposés aléatoirement ou agglomérés?

  • +
  • Deux types de points sont-ils disposés indépendamment?

  • +
+

Les modèles géostatistiques visent à représenter la distribution spatiale de variables continues qui sont mesurés à certains points d’échantillonnage. Ils supposent que les mesures de ces variables à différents points sont corrélées en fonction de la distance entre ces points. Parmi les applications des modèles géostatistiques, notons le lissage des données spatiales (ex.: produire une carte d’une variable sur l’ensemble d’une région en fonction des mesures ponctuelles) et la prédiction de ces variables pour des points non-échantillonnés.

+

Les données aréales sont des mesures prises non pas à des points, mais pour des régions de l’espace représentées par des polygones (ex.: divisions du territoire, cellules d’une grille). Les modèles représentant ces types de données définissent un réseau de voisinage reliant les régions et incluent une corrélation spatiale entre régions voisines.

+
+
+

Stationnarité et isotropie

+

Plusieurs analyses spatiales supposent que les variables sont stationnaires dans l’espace. Comme pour la stationnarité dans le domaine temporel, cette propriété signifie que les statistiques sommaires (moyenne, variance et corrélations entre mesures d’une variable) ne varient pas avec une translation dans l’espace. Par exemple, la corrélation spatiale entre deux points peut dépendre de la distance les séparant, mais pas de leur position absolue.

+

En particulier, il ne peut pas y avoir de tendance à grande échelle (souvent appelée gradient dans un contexte spatial), ou bien cette tendance doit être prise en compte afin de modéliser la corrélation spatiale des résidus.

+

Dans le cas de l’analyse des patrons de points, la stationnarité (aussi appelée homogénéité dans ce contexte) signifie que la densité des points ne suit pas de tendance à grande échelle.

+

Dans un modèle statistique isotropique, les corrélations spatiales entre les mesures à deux points dépendent seulement de la distance entre ces points, pas de la direction. Dans ce cas, les statistiques sommaires ne varient pas si on effectue une rotation dans l’espace.

+
+
+

Données géoréférencées

+

Les études environnementales utilisent de plus en plus de données provenant de sources de données géospatiales, c’est-à-dire des variables mesurées sur une grande partie du globe (ex.: climat, télédétection). Le traitement de ces données requiert des concepts liés aux systèmes d’information géographique (SIG), qui ne sont pas couverts dans cet atelier, alors que nous nous concentrons sur les aspects statistiques de données variant dans l’espace.

+

L’utilisation de données géospatiales ne signifie pas nécessairement qu’il faut avoir recours à des statistiques spatiales. Par exemple, il est courant d’extraire les valeurs de ces variables géographiques à des points d’étude pour expliquer une réponse biologique observée sur le terrain. Dans ce cas, l’utilisation de statistiques spatiales est seulement nécessaire en présence d’une corrélation spatiale dans les résidus, après avoir tenu compte de l’effet des prédicteurs.

+
+
+
+

18 Analyse des patrons de points

+
+

Patron de points et processus ponctuel

+

Un patron de points (point pattern) décrit la position spatiale (le plus souvent en 2D) d’individus ou d’événements, représentés par des points, dans une aire d’étude donnée, souvent appelée la fenêtre d’observation.

+

On suppose que chaque point a une étendue spatiale négligeable par rapport aux distances entre les points. Des méthodes plus complexes existent pour traiter des patrons spatiaux d’objets qui ont une largeur non-néligeable, mais ce sujet dépasse la portée de cet atelier.

+

Un processus ponctuel (point process) est un modèle statistique qui peut être utilisé pour simuler des patrons de points ou expliquer un patron de points observé.

+
+
+

Structure spatiale totalement aléatoire

+

Une structure spatiale totalement aléatoire (complete spatial randomness) est un des patrons les plus simples, qui sert de modèle nul pour évaluer les caractéristiques de patrons de points réels. Dans ce patron, la présence d’un point à une position donnée est indépendante de la présence de points dans un voisinage.

+

Le processus créant ce patron est un processus de Poisson homogène. Selon ce modèle, le nombre de points dans toute région de superficie \(A\) suit une distribution de Poisson: \(N(A) \sim \text{Pois}(\lambda A)\), où \(\lambda\) est l’intensité du processus (i.e. la densité de points). \(N\) est indépendant entre deux régions disjointes, peu importe comment ces régions sont définies.

+

Dans le graphique ci-dessous, seul le patron à droite est totalement aléatoire. Le patron à gauche montre une agrégation des points (probabilité plus grande d’observer un point si on est à proximité d’un autre point), tandis que le patron du centre montre une répulsion (faible probabilité d’observer un point très près d’un autre).

+
+
+

+
+
+
+
+

Analyse exploratoire ou inférentielle pour un patron de points

+

Plusieurs statistiques sommaires sont utilisées pour décrire les caractéristiques un patron de points. La plus simple est l’intensité \(\lambda\), qui comme mentionné plus haut représente la densité de points par unité de surface. Si le patron de points est hétérogène, l’intensité n’est pas constante, mais dépend de la position: \(\lambda(x, y)\).

+

Par rapport à l’intensité qui est une statistique dite de premier ordre, les statistiques de second ordre décrivent comment la probabilité de présence d’un point dans une région dépend de la présence d’autres points. L’indice \(K\) de Ripley présenté dans la prochaine section est un exemple de statistique sommaire de second ordre.

+

Les inférences statistiques réalisées sur des patrons de points consistent habituellement à tester l’hypothèse que le patron de points correspond à un modèle nul donné, par exemple une structure spatiale totalement aléatoire, ou un modèle nul plus complexe. Même pour les modèles nuls les plus simples, nous connaissons rarement la distribution théorique pour une statistique sommaire du patron de points sous le modèle nul. Les tests d’hypothèses sur les patrons de points sont donc réalisés par simulation: on simule un grand nombre de patrons de points à partir du modèle nul et on compare la distribution des statistiques sommaires qui nous intéressent pour ces simulations à la valeur des statistiques pour le patron de points observé.

+
+
+

Indice \(K\) de Ripley

+

L’indice de Ripley \(K(r)\) est défini comme le nombre moyen de points se trouvant dans un cercle de rayon \(r\) donné autour d’un point du patron, normalisé par l’intensité \(\lambda\).

+

Pour un patron totalement aléatoire, le nombre moyen de points dans un cercle de rayon \(r\) est \(\lambda \pi r^2\), donc en théorie \(K(r) = \pi r^2\) pour ce modèle nul. Une valeur de \(K(r)\) supérieure signifie qu’il y a agrégation des points à l’échelle \(r\), tandis qu’une valeur inférieure signifie qu’il y a une répulsion.

+

En pratique, \(K(r)\) est estimé pour un patron de points donné par l’équation:

+

\[ K(r) = \frac{A}{n(n-1)} \sum_i \sum_{j > i} I \left( d_{ij} \le r \right) w_{ij}\]

+

\(A\) est l’aire de la fenêtre d’observation et \(n\) est le nombre de points du patron, donc \(n(n-1)\) est le nombre de paires de points distinctes. On fait la somme pour toutes les paires de points de la fonction indicatrice \(I\), qui prend une valeur de 1 si la distance entre les points \(i\) et \(j\) est inférieure ou égale à \(r\). Finalement, le terme \(w_{ij}\) permet de donner un poids supplémentaire à certaines paires de points pour tenir compte des effets de bordure, tel que discuté dans la section suivante.

+

Par exemple, les graphiques ci-dessous présentent la fonction estimée \(K(r)\) pour les patrons illustrés ci-dessus, pour des valeurs de \(r\) allant jusqu’à 1/4 de la largeur de la fenêtre. La courbe pointillée rouge indique la valeur théorique pour une structure spatiale totalement aléatoire et la zone grise est une “enveloppe” produite par 99 simulations de ce modèle nul. Le patron agrégé montre un excès de voisins jusqu’à \(r = 0.25\) et le patron avec répulsion montre un déficit significatif de voisins pour les petites valeurs de \(r\).

+
+
+

+
+
+

Outre le \(K\), il existe d’autres statistiques pour décrire les propriétés de second ordre du patron, par exemple la distance moyenne entre un point et ses \(N\) plus proches voisins. Vous pouvez consulter le manuel de Wiegand et Moloney (2013) suggéré en référence pour en apprendre plus sur différentes statistiques sommaires des patrons de points.

+
+
+

Effets de bordure

+

Dans le contexte de l’analyse de patrons de points, l’effet de bordure (“edge effect”) est dû au fait que nous avons une connaissance incomplète du voisinage des points près du bord de la fenêtre d’observation, ce qui peut induire un biais dans le calcul des statistiques comme le \(K\) de Ripley.

+

Différentes méthodes ont été développées pour corriger le biais dû aux effets de bordure. Selon la méthode de Ripley, la contribution d’un voisin \(j\) situé à une distance \(r\) d’un point \(i\) reçoit un poids \(w_{ij} = 1/\phi_i(r)\), où \(\phi_i(r)\) est la fraction du cercle de rayon \(r\) autour de \(i\) contenu dans la fenêtre d’observation. Par exemple, si 2/3 du cercle se trouve dans la fenêtre, ce voisin compte pour 3/2 voisins dans le calcul d’une statistique comme \(K\).

+

+

La méthode de Ripley est une des plus simples pour corriger les effets de bordure, mais n’est pas nécessairement la plus efficace; notamment, les poids plus grands donnés à certaines paires de points tend à accroître la variance du calcul de la statistique. D’autres méthodes de correction sont présentées dans les manuels spécialisés, comme celui de Wiegand et Moloney (2013) en référence.

+
+
+

Exemple

+

Pour cet exemple, nous utilisons le jeu de données semis_xy.csv, qui représente les coordonnées \((x, y)\) de semis de deux espèces (sp, B = bouleau et P = peuplier) dans une placette de 15 x 15 m.

+
+
semis <- read.csv("data/semis_xy.csv")
+head(semis)
+
+
      x    y sp
+1 14.73 0.05  P
+2 14.72 1.71  P
+3 14.31 2.06  P
+4 14.16 2.64  P
+5 14.12 4.15  B
+6  9.88 4.08  B
+
+
+

Le package spatstat permet d’effectuer des analyses de patrons de point dans R. La première étape consiste à transformer notre tableau de données en objet ppp (patron de points) avec la fonction du même nom. Dans cette fonction, nous spécifions quelles colonnes contiennent les coordonnées x et y ainsi que les marques (marks), qui seront ici les codes d’espèce. Il faut aussi spécifier une fenêtre d’observation (window) à l’aide de la fonction owin, à laquelle nous indiquons les limites de la placette en x et y.

+
+
library(spatstat)
+
+semis <- ppp(x = semis$x, y = semis$y, marks = as.factor(semis$sp),
+             window = owin(xrange = c(0, 15), yrange = c(0, 15)))
+semis
+
+
Marked planar point pattern: 281 points
+Multitype, with levels = B, P 
+window: rectangle = [0, 15] x [0, 15] units
+
+
+

Les marques peuvent être numériques ou catégorielles. Notez que pour des marques catégorielles comme c’est le cas ici, il faut convertir explicitement la variable en facteur.

+

La fonction plot appliquée à un patron de points montre un diagramme du patron.

+
+
plot(semis)
+
+

+
+
+

La fonction intensity calcule la densité des points de chaque espèce par unité de surface, ici en \(m^2\).

+
+
intensity(semis)
+
+
        B         P 
+0.6666667 0.5822222 
+
+
+

Pour analyser d’abord séparément la distribution de chaque espèce, nous séparons le patron avec split. Puisque le patron contient des marques catégorielles, la séparation se fait automatiquement en fonction de la valeur des marques. Le résultat est une liste de deux patrons de points.

+
+
semis_split <- split(semis)
+plot(semis_split)
+
+

+
+
+

La fonction Kest calcule le \(K\) de Ripley pour une série de distances allant (par défaut) jusqu’à 1/4 de la largeur de la fenêtre. Ici, nous l’appliquons au premier patron (bouleau) en choisissant semis_split[[1]]. Notez que les doubles crochets sont nécessaires pour choisir un élément d’une liste dans R.

+

L’argument correction = "iso" indique d’appliquer la méthode de Ripley pour corriger les effets de bordure.

+
+
k <- Kest(semis_split[[1]], correction = "iso")
+plot(k)
+
+

+
+
+

Selon ce graphique, il semble y avoir une excès de voisins à partir d’un rayon de 1 m. Pour vérifier s’il s’agit d’un écart significatif, nous produisons une enveloppe de simulation avec la fonction envelope. Le permier argument d’envelope est un patron de point auquel les simulations seront comparées, le deuxième une fonction à calculer (ici, Kest) pour chaque patron simulé, puis on y ajoute les arguments de la fonction Kest (ici, seulement correction).

+
+
plot(envelope(semis_split[[1]], Kest, correction = "iso"))
+
+
Generating 99 simulations of CSR  ...
+1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,  99.
+
+Done.
+
+
+

+
+
+

Tel qu’indiqué par le message, cette fonction effectue par défaut 99 simulations de l’hypothèse nulle correspondant à une structure spatiale totalement aléatoire (CSR, pour complete spatial randomness).

+

La courbe observée sort de l’enveloppe des 99 simulations près de \(r = 2\). Il faut être prudent de ne pas interpréter trop rapidement un résultat sortant de l’enveloppe. Même s’il y a environ une probabilité de 1% d’obtenir un résultat plus extrême selon l’hypothèse nulle à une distance donnée, l’enveloppe est calculée pour un grand nombre de valeurs de la distance et nous n’effectuons pas de correction pour les comparaisons multiples. Ainsi, un écart significatif pour une très petite plage de valeurs de \(r\) peut être simplement dû au hasard.

+
+

Exercice 1

+

En regardant le graphique du deuxième patron de points (semis de peuplier), pouvez-vous prédire où se situera le \(K\) de Ripley par rapport à l’hypothèse nulle d’une structure spatiale totalement aléatoire? Vérifiez votre prédiction en calculant le \(K\) de Ripley pour ce patron de points dans R.

+
+
+
+

Effet de l’hétérogénéité

+

Le graphique ci-dessous illustre un patron de points hétérogène, c’est-à-dire qu’il présente un gradient d’intensité (plus de points à gauche qu’à droite).

+
+
+

+
+
+

Un gradient de densité peut être confondu avec une agrégation des points, comme on peut voir sur le graphique du \(K\) de Ripley correspondant. En théorie, il s’agit de deux processus différents:

+
    +
  • Hétérogénéité: La densité de points varie dans la région d’étude, par exemple dû au fait que certaines conditions locales sont plus propices à la présence de l’espèce étudiée.

  • +
  • Agrégation: La densité moyenne des points est homogène, mais la présence d’un point augmente la présence d’autre points dans son voisinage, par exemple en raison d’interactions positives entre les individus.

  • +
+

Cependant, il peut être difficile de différencier les deux en pratique, surtout que certains patrons peuvent être à la fois hétérogènes et agrégés.

+

Prenons l’exemple des semis de peuplier de l’exercice précédent. La fonction density appliquée à un patron de points effectue une estimation par noyau (kernel density estimation) de la densité des semis à travers la placette. Par défaut, cette fonction utilise un noyau gaussien avec un écart-type sigma spécifié dans la fonction, qui détermine l’échelle à laquelle les fluctuations de densité sont “lissées”. Ici, nous utilisons une valeur de 2 m pour sigma et nous représentons d’abord la densité estimée avec plot, avant d’y superposer les points (add = TRUE signifie que les points sont ajoutés au graphique existant plutôt que de créer un nouveau graphique).

+
+
dens_p <- density(semis_split[[2]], sigma = 2)
+plot(dens_p)
+plot(semis_split[[2]], add = TRUE)
+
+

+
+
+

Pour mesurer l’agrégation ou la répulsion des points d’un patron hétérogène, nous devons utilisé la version non-homogène de la statistique \(K\) (Kinhom dans spatstat). Cette statistique est toujours égale au nombre moyen de voisins dans un rayon \(r\) d’un point du patron, mais plutôt que de normaliser ce nombre par l’intensité globale du patron, il est normalisé par l’estimation locale de la densité de points. Comme ci-dessus, nous spécifions sigma = 2 pour contrôler le niveau de lissage de l’estimation de la densité variable.

+
+
plot(Kinhom(semis_split[[2]], sigma = 2, correction = "iso"))
+
+

+
+
+

En tenant compte de l’hétérogénéité du patron à une échelle sigma de 2 m, il semble donc y avoir un déficit de voisins à partir d’environ 1.5 m des points du patron. Il reste à voir si cette déviation est significative.

+

Comme précédemment, nous utilisons envelope pour simuler la statistique Kinhom sous le modèle nul. Cependant, ici le modèle nul n’est pas un processus de Poisson homogène (structure spatiale totalement aléatoire). Il s’agit plutôt d’un processus de Poisson hétérogène simulé par la fonction rpoispp(dens_p), c’est-à-dire que les points sont indépendants les uns des autres, mais leur densité est hétérogène et donnée par dens_p. L’argument simulate de la fonction envelope permet de spécifier une fonction utilisée pour les simulations sous le modèle nul; cette fonction doit avoir un argument, ici x, même s’il n’est pas utilisé.

+

Finalement, en plus des arguments nécessaires pour Kinhom, soit sigma et correction, nous spécifions aussi nsim = 199 pour réaliser 199 simulations et nrank = 5 pour éliminer les 5 résultats les plus extrêmes de chaque côté de l’enveloppe, donc les 10 plus extrêmes sur 199, pour réaliser un intervalle contenant environ 95% de la probabilité sous l’hypothèse nulle.

+
+
khet_p <- envelope(semis_split[[2]], Kinhom, sigma = 2, correction = "iso",
+                   nsim = 199, nrank = 5, simulate = function(x) rpoispp(dens_p))
+
+
Generating 199 simulations by evaluating function  ...
+1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40
+.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80
+.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120
+.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160
+.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.
+
+Done.
+
+
plot(khet_p)
+
+

+
+
+

Note: Pour un test d’hypothèse basé sur des simulations d’une hypothèse nulle, la valeur \(p\) est estimée par \((m + 1)/(n + 1)\), où \(n\) est le nombre de simulations et \(m\) est le nombre de simulations où la valeur de la statistique est plus extrême que celle des données observées. C’est pour cette raison qu’on choisit un nombre de simulations comme 99, 199, etc.

+
+

Exercice 2

+

Répétez l’estimation de la densité hétérogène et le calcul de Kinhom avec un écart-type sigma de 5 plutôt que 2. Comment le niveau de lissage pour la densité influence-t-il les conclusions?

+

Pour différencier une variation de densité des points et d’une interaction (agrégation ou répulsion) entre ces points avec ce type d’analyse, il faut généralement supposer que les deux processus opèrent à différentes échelles. Typiquement, nous pouvons tester si les points sont agrégés à petite échelle après avoir tenu compte d’une variation de la densité à une échelle plus grande.

+
+
+
+

Relation entre deux patrons de points

+

Considérons un cas où nous avons deux patrons de points, par exemple la position des arbres de deux espèces dans une parcelle (points oranges et verts dans le graphique ci-dessous). Chacun des deux patrons peut présenter ou non des agrégations de points.

+
+
+

+
+
+

Sans égard à cette agrégation au niveau de l’espèce, nous voulons déterminer si les deux espèces sont disposées indépendamment. Autrement dit, la probabilité d’observer un arbre d’une espèce dépend-elle de la présence d’un arbre de l’autre espèce à une distance donnée?

+

La version bivariée du \(K\) de Ripley permet de répondre à cette question. Pour deux patrons désignés 1 et 2, l’indice \(K_{12}(r)\) calcule le nombre moyen de points du patron 2 dans un rayon \(r\) autour d’un point du patron 1, normalisé par la densité du patron 2.

+

En théorie, cet indice est symétrique, donc \(K_{12}(r) = K_{21}(r)\) et le résultat serait le même si on choisit les points du patron 1 ou 2 comme points “focaux” pour l’analyse. Cependant, l’estimation des deux quantités pour un patron observé peut différer, notamment en raison des effets de bord. La variabilité peut aussi être différente pour \(K_{12}\) et \(K_{21}\) entre les simulations d’un modèle nul, donc le test de l’hypothèse nulle peut avoir une puissance différente selon le choix de l’espèce focale.

+

Le choix d’un modèle nul approprié est important ici. Afin de déterminer s’il existe une attraction ou une répulsion significative entre les deux patrons, il faut déplacer aléatoirement la position d’un des patrons relative à celle de l’autre patron, tout en conservant la structure spatiale de chaque patron pris isolément.

+

Une des façons d’effectuer cette randomisation consiste à décaler l’un des deux patrons horizontalement et/ou verticalement d’une distance aléatoire. La partie du patron qui “sort” d’un côté de la fenêtre est rattachée de l’autre côté. Cette méthode s’appelle une translation toroïdale (toroidal shift), car en connectant le haut et le bas ainsi que la gauche et la droite d’une surface rectangulaire, on obtient la forme d’un tore (un “beigne” en trois dimensions).

+
+
+

+
+
+

Le graphique ci-dessus illustre une translation du patron vert vers la droite, tandis que le patron orange reste au même endroit. Les points verts dans la zone ombragée sont ramenés de l’autre côté. Notez que si cette méthode préserve de façon générale la structure de chaque patron tout en randomisant leur position relative, elle peut comporter certains inconvénients, comme de diviser des amas de points qui se trouvent près du point de coupure.

+

Vérifions maintenant s’il y a une dépendance entre la position des deux espèces (bouleau et peuplier) dans notre placette. La fonction Kcross calcule l’indice bivarié \(K_{ij}\), il faut spécifier quel type de point est considéré comme l’espèce focale \(i\) et l’espèce voisine \(j\).

+
+
plot(Kcross(semis, i = "P", j = "B", correction = "iso"))
+
+

+
+
+

Ici, le \(K\) observé est inférieur à la valeur théorique, indiquant une répulsion possible des deux patrons.

+

Pour déterminer l’enveloppe du \(K\) selon l’hypothèse nulle d’indépendance des deux patrons, nous devons spécifier que les simulations doivent être basées sur une translation des patrons. Nous indiquons que les simulations doivent utiliser la fonction rshift (translation aléatoire) avec l’argument simulate = function(x) rshift(x, which = "B"); ici, l’argument x de simulate correspond au patron de points original et l’argument which indique quel type de points subit la translation. Comme pour le cas précédent, il faut répéter dans la fonction envelope les arguments nécessaires pour Kcross, soit i, j et correction.

+
+
plot(envelope(semis, Kcross, i = "P", j = "B", correction = "iso", 
+              nsim = 199, nrank = 5, simulate = function(x) rshift(x, which = "B")))
+
+
Generating 199 simulations by evaluating function  ...
+1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40
+.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80
+.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120
+.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160
+.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.
+
+Done.
+
+
+

+
+
+

Ici, la courbe observée se situe totalement dans l’enveloppe, donc nous ne rejetons pas l’hypothèse nulle d’indépendance des deux patrons.

+
+

Questions

+
    +
  1. Quelle raison pourrait justifier ici notre choix d’effectuer la translation des points du bouleau plutôt que du peuplier?

  2. +
  3. Est-ce que les simulations générées par translation aléatoire constitueraient un bon modèle nul si les deux patrons étaient hétérogènes?

  4. +
+
+
+
+

Patrons de points marqués

+

Le jeu de données fir.csv contient les coordonnées \((x, y)\) de 822 sapins dans une placette d’un hectare et leur statut (A = vivant, D = mort) suivant une épidémie de tordeuse des bourgeons de l’épinette.

+
+
fir <- read.csv("data/fir.csv")
+head(fir)
+
+
      x     y status
+1 31.50  1.00      A
+2 85.25 30.75      D
+3 83.50 38.50      A
+4 84.00 37.75      A
+5 83.00 33.25      A
+6 33.25  0.25      A
+
+
+
+
fir <- ppp(x = fir$x, y = fir$y, marks = as.factor(fir$status),
+           window = owin(xrange = c(0, 100), yrange = c(0, 100)))
+plot(fir)
+
+

+
+
+

Supposons que nous voulons vérifier si la mortalité des sapins est indépendante ou corrélée entre arbres rapprochés. En quoi cette question diffère-t-elle de l’exemple précédent où nous voulions savoir si la position des points de deux espèces était indépendante?

+

Dans l’exemple précédent, l’indépendance ou l’interaction entre les espèces référait à la formation du patron lui-même (que des semis d’une espèce s’établissent ou non à proximité de ceux de l’autre espèce). Ici, la caractéristique qui nous intéresse (survie des sapins) est postérieure à l’établissement du patron, en supposant que tous ces arbres étaient vivants d’abord et que certains sont morts suite à l’épidémie. Donc nous prenons la position des arbres comme fixe et nous voulons savoir si la distribution des statuts (mort, vivant) entre ces arbres est aléatoire ou présente un patron spatial.

+

Dans le manuel de Wiegand et Moloney, la première situation (établissement de semis de deux espèces) est appelé patron bivarié, donc il s’agit vraiment de deux patrons qui interagissent, tandis que la deuxième est un seul patron avec une marque qualitative. Le package spatstat dans R ne fait pas de différences entre les deux au niveau de la définition du patron (les types de points sont toujours représentés par l’argument marks), mais les méthodes d’analyse appliquées aux deux questions diffèrent.

+

Dans le cas d’un patron avec une marque qualitative, nous pouvons définir une fonction de connexion de marques (mark connection function) \(p_{ij}(r)\). Pour deux points séparés par une distance \(r\), cette fonction donne la probabilité que le premier point porte la marque \(i\) et le deuxième la marque \(j\). Selon l’hypothèse nulle où les marques sont indépendantes, cette probabilité est égale au produit des proportions de chaque marque dans le patron entier, \(p_{ij}(r) = p_i p_j\) indépendamment de \(r\).

+

Dans spatstat, la fonction de connexion de marques est calculée avec la fonction markconnect, où il faut spécifier les marques \(i\) et \(j\) ainsi que le type de correction des effets de bord. Dans notre exemple, nous voyons que deux points rapprochés ont moins de chance d’avoir une statut différent (A et D) que prévu selon l’hypothèse de distribution aléatoire et indépendante des marques (ligne rouge pointillée).

+
+
plot(markconnect(fir, i = "A", j = "D", correction = "iso"))
+
+

+
+
+

Dans ce graphique, les ondulations dans la fonction sont dues à l’erreur d’estimation d’une fonction continue de \(r\) à partir d’un nombre limité de paires de points discrètes.

+

Pour simuler le modèle nul dans ce cas-ci, nous utilisons la fonction rlabel qui réassigne aléatoirement les marques parmi les points du patron, en maintenant la position des points.

+
+
plot(envelope(fir, markconnect, i = "A", j = "D", correction = "iso", 
+              nsim = 199, nrank = 5, simulate = rlabel))
+
+
Generating 199 simulations by evaluating function  ...
+1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40
+.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80
+.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120
+.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160
+.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.
+
+Done.
+
+
+

+
+
+

Notez que puisque la fonction rlabel a un seul argument obligatoire correspondant au patron de points original, il n’était pas nécessaire de spécifier au long: simulate = function(x) rlabel(x).

+

Voici les résultats pour les paires d’arbres du même statut A ou D:

+
+
par(mfrow = c(1, 2))
+plot(envelope(fir, markconnect, i = "A", j = "A", correction = "iso", 
+              nsim = 199, nrank = 5, simulate = rlabel))
+
+
Generating 199 simulations by evaluating function  ...
+1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40
+.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80
+.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120
+.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160
+.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.
+
+Done.
+
+
plot(envelope(fir, markconnect, i = "D", j = "D", correction = "iso", 
+              nsim = 199, nrank = 5, simulate = rlabel))
+
+
Generating 199 simulations by evaluating function  ...
+1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40
+.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80
+.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120
+.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160
+.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.
+
+Done.
+
+
+

+
+
+

Il semble donc que la mortalité des sapins due à cette épidémie est agrégée spatialement, puisque les arbres situés à proximité l’un de l’autre ont une plus grande probabilité de partager le même statut que prévu par l’hypothèse nulle.

+
+
+

Références

+

Fortin, M.-J. et Dale, M.R.T. (2005) Spatial Analysis: A Guide for Ecologists. Cambridge University Press: Cambridge, UK.

+

Wiegand, T. et Moloney, K.A. (2013) Handbook of Spatial Point-Pattern Analysis in Ecology, CRC Press.

+

Le jeu de données du dernier exemple est tiré des données de la Forêt d’enseignement et de recherche du Lac Duparquet (FERLD), disponibles sur Dryad en suivant ce lien.

+
+
+
+

19 Solutions

+
+

Exercice 1

+
+
plot(envelope(semis_split[[2]], Kest, correction = "iso"))
+
+
Generating 99 simulations of CSR  ...
+1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,  99.
+
+Done.
+
+
+

+
+
+

Les semis de peuplier semblent significativement agrégés selon la valeur du \(K\).

+
+
+

Exercice 2

+
+
dens_p <- density(semis_split[[2]], sigma = 5)
+plot(dens_p)
+plot(semis_split[[2]], add = TRUE)
+
+

+
+
khet_p <- envelope(semis_split[[2]], Kinhom, sigma = 5, correction = "iso",
+                   nsim = 199, nrank = 5, simulate = function(x) rpoispp(dens_p))
+
+
Generating 199 simulations by evaluating function  ...
+1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40
+.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80
+.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120
+.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160
+.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.
+
+Done.
+
+
plot(khet_p)
+
+

+
+
+

Ici, puisque nous estimons la variation de densité à une plus grande échelle, même après avoir tenu compte de cette variation, les semis de peuplier semblent agrégés à petite échelle.

+
+
+
+

20 Corrélation spatiale d’une variable

+

La corrélation entre les mesures d’une variable prises à des points rapprochés est une caractéristique dans de nombreux jeux de données. Ce principe est parfois appelé “première loi de la géographie” et exprimé par la citation de Waldo Tobler: “Everything is related to everything else, but near things are more related than distant things.” (Tout est relié, mais les choses rapprochées le sont davantage que celles éloignées).

+

En statistique, nous parlons souvent d’autocorrélation pour désigner la corrélation qui existe entre les mesures d’une même variable prises à différents moments (autocorrélation temporelle) ou différents lieux (autocorrélation spatiale).

+
+

Dépendance intrinsèque ou induite

+

Il existe deux types fondamentaux de dépendance spatiale sur une variable mesurée \(y\): une dépendance intrinsèque à \(y\), ou une dépendance induite par des variables externes influençant \(y\), qui sont elles-mêmes corrélées dans l’espace.

+

Par exemple, supposons que l’abondance d’une espèce soit corrélée entre deux sites rapprochés:

+
    +
  • cette dépendance spatiale peut être induite si elle est due à une corrélation spatiale des facteurs d’habitat qui favorisent ou défavorisent l’espèce;

  • +
  • ou elle peut être intrinsèque si elle est due à la dispersion d’individus entre sites rapprochés.

  • +
+

Dans plusieurs cas, les deux types de dépendance affectent une variable donnée.

+

Si la dépendance est simplement induite et que les variables externes qui en sont la cause sont incluses dans le modèle expliquant \(y\), alors les résidus du modèle seront indépendants et nous pouvons utiliser toutes les méthodes déjà vues qui ignorent la dépendance spatiale.

+

Cependant, si la dépendance est intrinsèque ou due à des influences externes non-mesurées, alors il faudra tenir compte de la dépendance spatiale des résidus dans le modèle.

+
+
+

Différentes façons de modéliser les effets spatiaux

+

Dans cette formation, nous modéliserons directement les corrélations spatiales de nos données. Il est utile de comparer cette approche à d’autres façons d’inclure des aspects spatiaux dans un modèle statistique.

+

D’abord, nous pourrions inclure des prédicteurs dans le modèle qui représentent la position (ex.: longitude, latitude). De tels prédicteurs peuvent être utiles pour détecter une tendance ou un gradient systématique à grande échelle, que cette tendance soit linéaire ou non (par exemple, avec un modèle additif généralisé).

+

En contraste à cette approche, les modèles que nous verrons maintenant servent à modéliser une corrélation spatiale dans les fluctuations aléatoires d’une variable (i.e., dans les résidus après avoir enlevé tout effet systématique).

+

Les modèles mixtes utilisent des effets aléatoires pour représenter la non-indépendance de données sur la base de leur groupement, c’est-à-dire qu’après avoir tenu compte des effets fixes systématiques, les données d’un même groupe sont plus semblables (leur variation résiduelle est corrélée) par rapport aux données de groupes différents. Ces groupes étaient parfois définis selon des critères spatiaux (observations regroupées en sites).

+

Cependant, dans un contexte d’effet aléatoire de groupe, tous les groupes sont aussi différents les uns des autres, ex.: deux sites à 100 km l’un de l’autre ne sont pas plus ou moins semblables que deux sites distants de 2 km.

+

Les méthodes que nous verrons ici et dans les prochains parties de la formation nous permettent donc ce modéliser la non-indépendance sur une échelle continue (plus proche = plus corrélé) plutôt que seulement discrète (hiérarchie de groupements).

+
+
+
+

21 Modèles géostatistiques

+

La géostatistique désigne un groupe de techniques tirant leur origine en sciences de la Terre. Elle s’intéresse à des variables distribuées de façon continue dans l’espace, dont on cherche à estimer la distribution en échantillonnant un nombre de points. Un exemple classique de ces techniques provient du domaine minier, où l’on cherchait à créer une carte de la concentration du minerai sur un site à partir d’échantillons pris à différents points du site.

+

Pour ces modèles, nous supposerons que \(z(x, y)\) est une variable spatiale stationnaire mesurée selon les coordonnées \(x\) et \(y\).

+
+

Variogramme

+

Un aspect central de la géostatistique est l’estimation du variogramme \(\gamma_z\) de la variable \(z\). Le variogramme est égal à la moitié de l’écart carré moyen entre les valeurs de \(z\) pour deux points \((x_i, y_i)\) et \((x_j, y_j)\) séparés par une distance \(h\).

+

\[\gamma_z(h) = \frac{1}{2} \text{E} \left[ \left( z(x_i, y_i) - z(x_j, y_j) \right)^2 \right]_{d_{ij} = h}\]

+

Dans cette équation, la fonction \(\text{E}\) avec l’indice \(d_{ij}=h\) désigne l’espérance statistique (autrement dit, la moyenne) de l’écart au carré entre les valeurs de \(z\) pour les points séparés par une distance \(h\).

+

Si on préfère exprimer l’autocorrélation \(\rho_z(h)\) entre mesures de \(z\) séparées par une distance \(h\), celle-ci est reliée au variogramme par l’équation:

+

\[\gamma_z = \sigma_z^2(1 - \rho_z)\] ,

+

\(\sigma_z^2\) est la variance globale de \(z\).

+

Notez que \(\gamma_z = \sigma_z^2\) si nous sommes à une distance où les mesures de \(z\) sont indépendantes, donc \(\rho_z = 0\). Dans ce cas, on voit bien que \(\gamma_z\) s’apparente à une variance, même s’il est parfois appelé “semivariogramme” ou “semivariance” en raison du facteur 1/2 dans l’équation ci-dessus.

+
+
+

Modèles théoriques du variogramme

+

Plusieurs modèles paramétriques ont été proposés pour représenter la corrélation spatiale en fonction de la distance entre points d’échantillonnage. Considérons d’abord une corrélation qui diminue de façon exponentielle:

+

\[\rho_z(h) = e^{-h/r}\]

+

Ici, \(\rho_z = 1\) pour \(h = 0\) et la corréaltion est multipliée par \(1/e \approx 0.37\) pour chaque augmentation de \(r\) de la distance. Dans ce contexte, \(r\) se nomme la portée (range) de la corrélation.

+

À partir de l’équation ci-dessus, nous pouvons calculer le variogramme correspondant.

+

\[\gamma_z(h) = \sigma_z^2 (1 - e^{-h/r})\]

+

Voici une représentation graphique de ce variogramme.

+
+
+

+
+
+

En raison de la fonction exponentielle, la valeur de \(\gamma\) à des grandes distances s’approche de la variance globale \(\sigma_z^2\) sans exactement l’atteindre. Cette asymptote est appelée palier (sill) dans le contexte géostatistique et représentée par le symbole \(s\).

+

Finalement, il n’est parfois pas réaliste de supposer une corrélation parfaite lorsque la distance tend vers 0, en raison d’une variation possible de \(z\) à très petite échelle. On peut ajouter au modèle un effet de pépite (nugget), noté \(n\), pour que \(\gamma\) s’approche de \(n\) (plutôt que 0) si \(h\) tend vers 0. Le terme pépite provient de l’origine minière de ces techniques, où une pépite d’un minerai pourrait être la source d’une variation abrupte de la concentration à petite échelle.

+

En ajoutant l’effet de pépite, le reste du variogramme est “compressé” pour conserver le même palier, ce qui résulte en l’équation suivante.

+

\[\gamma_z(h) = n + (s - n) (1 - e^{-h/r})\]

+

Dans le package gstat que nous utiliserons ci-dessous, le terme \((s - n)\) est le palier partiel (partial sill, ou psill) pour la partie exponentielle.

+
+
+

+
+
+

En plus du modèle exponentiel, deux autres modèles théoriques courants pour le variogramme sont le modèle gaussien (où la corrélation suit une courbe demi-normale), ainsi que le modèle sphérique (où le variogramme augmente de façon linéaire au départ pour ensuite courber et atteindre le palier à une distance égale à sa portée \(r\)). Le modèle sphérique permet donc à la corrélation d’être exactement 0 à grande distance, plutôt que de s’approcher graduellement de zéro dans le cas des autres modèles.

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
Modèle\(\rho(h)\)\(\gamma(h)\)
Exponentiel\(\exp\left(-\frac{h}{r}\right)\)\(s \left(1 - \exp\left(-\frac{h}{r}\right)\right)\)
Gaussien\(\exp\left(-\frac{h^2}{r^2}\right)\)\(s \left(1 - \exp\left(-\frac{h^2}{r^2}\right)\right)\)
Sphérique \((h < r)\) *\(1 - \frac{3}{2}\frac{h}{r} + \frac{1}{2}\frac{h^3}{r^3}\)\(s \left(\frac{3}{2}\frac{h}{r} - \frac{1}{2}\frac{h^3}{r^3} \right)\)
+

* Pour le modèle sphérique, \(\rho = 0\) et \(\gamma = s\) si \(h \ge r\).

+
+
+

+
+
+
+
+

Variogramme empirique

+

Pour estimer \(\gamma_z(h)\) à partir de données empiriques, nous devons définir des classes de distance, donc grouper différentes distances dans une marge \(\pm \delta\) autour d’une distance \(h\), puis calculer l’écart-carré moyen pour les paires de points dans cette classe de distance.

+

\[\hat{\gamma_z}(h) = \frac{1}{2 N_{\text{paires}}} \sum \left[ \left( z(x_i, y_i) - z(x_j, y_j) \right)^2 \right]_{d_{ij} = h \pm \delta}\]

+

Nous verrons dans la partie suivante comment estimer un variogramme dans R.

+
+
+

Modèle de régression avec corrélation spatiale

+

L’équation suivante représente une régression linéaire multiple incluant une corrélation spatiale résiduelle:

+

\[v = \beta_0 + \sum_i \beta_i u_i + z + \epsilon\]

+

Ici, \(v\) désigne la variable réponse et \(u\) les prédicteurs, pour ne pas confondre avec les coordonnées spatiales \(x\) et \(y\).

+

En plus du résidu \(\epsilon\) qui est indépendant entre les observations, le modèle inclut un terme \(z\) qui représente la portion spatialement corrélée de la variance résiduelle.

+

Voici une suggestions d’étapes à suivre pour appliquer ce type de modèle:

+
    +
  1. Ajuster le modèle de régression sans corrélation spatiale.

  2. +
  3. Vérifier la présence de corrélation spatiale à partir du variogramme empirique des résidus.

  4. +
  5. Ajuster un ou plusieurs modèles de régression avec corrélation spatiale et choisir celui qui montre le meilleur ajustement aux données.

  6. +
+
+
+
+

22 Modèles géostatistiques dans R

+

Le package gstat contient des fonctions liées à la géostatistique. Pour cet exemple, nous utiliserons le jeu de données oxford de ce package, qui contient des mesures de propriétés physiques et chimiques pour 126 échantillons du sol d’un site, ainsi que leurs coordonnées XCOORD et YCOORD.

+
+
library(gstat)
+
+data(oxford)
+str(oxford)
+
+
'data.frame':   126 obs. of  22 variables:
+ $ PROFILE  : num  1 2 3 4 5 6 7 8 9 10 ...
+ $ XCOORD   : num  100 100 100 100 100 100 100 100 100 100 ...
+ $ YCOORD   : num  2100 2000 1900 1800 1700 1600 1500 1400 1300 1200 ...
+ $ ELEV     : num  598 597 610 615 610 595 580 590 598 588 ...
+ $ PROFCLASS: Factor w/ 3 levels "Cr","Ct","Ia": 2 2 2 3 3 2 3 2 3 3 ...
+ $ MAPCLASS : Factor w/ 3 levels "Cr","Ct","Ia": 2 3 3 3 3 2 2 3 3 3 ...
+ $ VAL1     : num  3 3 4 4 3 3 4 4 4 3 ...
+ $ CHR1     : num  3 3 3 3 3 2 2 3 3 3 ...
+ $ LIME1    : num  4 4 4 4 4 0 2 1 0 4 ...
+ $ VAL2     : num  4 4 5 8 8 4 8 4 8 8 ...
+ $ CHR2     : num  4 4 4 2 2 4 2 4 2 2 ...
+ $ LIME2    : num  4 4 4 5 5 4 5 4 5 5 ...
+ $ DEPTHCM  : num  61 91 46 20 20 91 30 61 38 25 ...
+ $ DEP2LIME : num  20 20 20 20 20 20 20 20 40 20 ...
+ $ PCLAY1   : num  15 25 20 20 18 25 25 35 35 12 ...
+ $ PCLAY2   : num  10 10 20 10 10 20 10 20 10 10 ...
+ $ MG1      : num  63 58 55 60 88 168 99 59 233 87 ...
+ $ OM1      : num  5.7 5.6 5.8 6.2 8.4 6.4 7.1 3.8 5 9.2 ...
+ $ CEC1     : num  20 22 17 23 27 27 21 14 27 20 ...
+ $ PH1      : num  7.7 7.7 7.5 7.6 7.6 7 7.5 7.6 6.6 7.5 ...
+ $ PHOS1    : num  13 9.2 10.5 8.8 13 9.3 10 9 15 12.6 ...
+ $ POT1     : num  196 157 115 172 238 164 312 184 123 282 ...
+
+
+

Supposons que nous souhaitons modéliser la concentration de magnésium (MG1), représentée en fonction de la position spatiale dans le graphique suivant.

+
+
library(ggplot2)
+ggplot(oxford, aes(x = YCOORD, y = XCOORD, size = MG1)) +
+    geom_point() +
+    coord_fixed()
+
+

+
+
+

Notez que les axes \(x\) et \(y\) ont été inversés par souci d’espace. La fonction coord_fixed() de ggplot2 assure que l’échelle soit la même sur les deux axes, ce qui est utile pour représenter des données spatiales.

+

Nous voyons tout de suite que ces mesures ont été prises sur une grille de 100 m de côté. Il semble que la concentration de magnésium soit spatialement corrélée, bien qu’il puisse s’agir d’une corrélation induite par une autre variable. Nous savons notamment que la concentration de magnésium est reliée négativement au pH du sol (PH1).

+
+
ggplot(oxford, aes(x = PH1, y = MG1)) +
+    geom_point()
+
+

+
+
+

La fonction variogram de gstat sert à estimer un variogramme à partir de données empiriques. Voici le résultat obtenu pour la variable MG1.

+
+
var_mg <- variogram(MG1 ~ 1, locations = ~ XCOORD + YCOORD, data = oxford)
+var_mg
+
+
    np     dist    gamma dir.hor dir.ver   id
+1  225 100.0000 1601.404       0       0 var1
+2  200 141.4214 1950.805       0       0 var1
+3  548 215.0773 2171.231       0       0 var1
+4  623 303.6283 2422.245       0       0 var1
+5  258 360.5551 2704.366       0       0 var1
+6  144 400.0000 2948.774       0       0 var1
+7  570 427.5569 2994.621       0       0 var1
+8  291 500.0000 3402.058       0       0 var1
+9  366 522.8801 3844.165       0       0 var1
+10 200 577.1759 3603.060       0       0 var1
+11 458 619.8400 3816.595       0       0 var1
+12  90 670.8204 3345.739       0       0 var1
+
+
+

La formule MG1 ~ 1 indique qu’aucun prédicteur linéaire n’est inclus dans ce modèle, tandis que l’argument locations indique quelles variables du tableau correspondent aux coordonnées spatiales.

+

Dans le tableau obtenu, gamma est la valeur du variogramme pour la classe de distance centrée sur dist, tandis que np est le nombre de paires de points dans cette classe. Ici, puisque les points sont situés sur une grille, nous obtenons des classes de distance régulières (ex.: 100 m pour les points voisins sur la grille, 141 m pour les voisins en diagonale, etc.).

+

Nous nous limitons ici à l’estimation de variogrammes isotropiques, c’est-à-dire que le variogramme dépend seulement de la distance entre les deux points et non de la direction. Bien que nous n’ayons pas le temps de le voir aujourd’hui, il est possible avec gstat d’estimer séparément le variogramme dans différentes directions.

+

Nous pouvons illustrer le variogramme avec plot.

+
+
plot(var_mg, col = "black")
+
+

+
+
+

Si nous voulons estimer la corrélation spatiale résiduelle de MG1 après avoir inclus l’effet de PH1, nous pouvons ajouter ce prédicteur à la formule.

+
+
var_mg <- variogram(MG1 ~ PH1, locations = ~ XCOORD + YCOORD, data = oxford)
+plot(var_mg, col = "black")
+
+

+
+
+

En incluant l’effet du pH, la portée de la corrélation spatiale semble diminuer, alors que le plateau est atteint autour de 300 m. Il semble même que le variogramme diminue au-delà de 400 m. En général, nous supposons que la variance entre deux points ne diminue pas avec la distance, à moins d’avoir un patron spatial périodique.

+

La fonction fit.variogram accepte comme arguments un variogramme estimé à partir des données, ainsi qu’un modèle théorique décrit dans une fonction vgm, puis estime les paramètres de ce modèle en fonction des données. L’ajustement se fait par la méthode des moindres carrés.

+

Par exemple, vgm("Exp") indique d’ajuster un modèle exponentiel.

+
+
vfit <- fit.variogram(var_mg, vgm("Exp"))
+vfit
+
+
  model    psill    range
+1   Nug    0.000  0.00000
+2   Exp 1951.496 95.11235
+
+
+

Il n’y a aucun effet de pépite, car psill = 0 pour la partie Nug (nugget) du modèle. La partie exponentielle a un palier à 1951 et une portée de 95 m.

+

Pour comparer différents modèles, on peut donner un vecteur de noms de modèles à vgm. Dans l’exemple suivant, nous incluons les modèles exponentiel, gaussien (“Gau”) et sphérique (“Sph”).

+
+
vfit <- fit.variogram(var_mg, vgm(c("Exp", "Gau", "Sph")))
+vfit
+
+
  model    psill    range
+1   Nug    0.000  0.00000
+2   Exp 1951.496 95.11235
+
+
+

La fonction nous donne le résultat du modèle le mieux ajusté (plus faible somme des écarts au carré), qui est ici le même modèle exponentiel.

+

Finalement, nous pouvons superposer le modèle théorique et le variogramme empirique sur un même graphique.

+
+
plot(var_mg, vfit, col = "black")
+
+

+
+
+
+

Régression avec corrélation spatiale

+

Nous avons vu ci-dessus que le package gstat permet d’estimer le variogramme des résidus d’un modèle linéaire. Dans notre exemple, la concentration de magnésium était modélisée en fonction du pH, avec des résidus spatialement corrélés.

+

Un autre outil pour ajuster ce même type de modèle est la fonction gls du package nlme, qui est inclus avec l’installation de R.

+

Cette fonction applique la méthode des moindres carrés généralisés (generalized least squares) pour ajuster des modèles de régression linéaire lorsque les résidus ne sont pas indépendants ou lorsque la variance résiduelle n’est pas la même pour toutes les observations. Comme les estimés des coefficients dépendent de l’estimé des corrélations entre les résidus et que ces derniers dépendent eux-mêmes des coefficients, le modèle est ajusté par un algorithme itératif:

+
    +
  1. On ajuste un modèle de régression linéaire classique (sans corrélation) pour obtenir des résidus.

  2. +
  3. On ajuste le modèle de corrélation spatiale (variogramme) avec ses résidus.

  4. +
  5. On ré-estime les coefficients de la régression en tenant compte maintenant des corrélations.

  6. +
+

Les étapes 2 et 3 sont répétées jusqu’à ce que les estimés soient stables à une précision voulue.

+

Voici l’application de cette méthode au même modèle pour la concentration de magnésium dans le jeu de données oxford. Dans l’argument correlation de gls, nous spécifions un modèle de corrélation exponentielle en fonction de nos coordonnées spatiales et indiquons que nous voulons aussi estimer un effet de pépite.

+

En plus de la corrélation exponentielle corExp, la fonction gls peut aussi estimer un modèle gaussien (corGaus) ou sphérique (corSpher).

+
+
library(nlme)
+gls_mg <- gls(MG1 ~ PH1, oxford, 
+              correlation = corExp(form = ~ XCOORD + YCOORD, nugget = TRUE))
+summary(gls_mg)
+
+
Generalized least squares fit by REML
+  Model: MG1 ~ PH1 
+  Data: oxford 
+      AIC      BIC   logLik
+  1278.65 1292.751 -634.325
+
+Correlation Structure: Exponential spatial correlation
+ Formula: ~XCOORD + YCOORD 
+ Parameter estimate(s):
+      range      nugget 
+478.0322964   0.2944753 
+
+Coefficients:
+               Value Std.Error   t-value p-value
+(Intercept) 391.1387  50.42343  7.757084       0
+PH1         -41.0836   6.15662 -6.673079       0
+
+ Correlation: 
+    (Intr)
+PH1 -0.891
+
+Standardized residuals:
+       Min         Q1        Med         Q3        Max 
+-2.1846957 -0.6684520 -0.3687813  0.4627580  3.1918604 
+
+Residual standard error: 53.8233 
+Degrees of freedom: 126 total; 124 residual
+
+
+

Pour comparer ce résultat au variogramme ajusté ci-dessus, il faut transformer les paramètres donnés par gls. La portée (range) a le même sens dans les deux cas et correspond à 478 m pour le résultat de gls. La variance globale des résidus est le carré de Residual standard error. L’effet de pépite ici (0.294) est exprimé comme fraction de cette variance. Finalement, pour obtenir le palier partiel de la partie exponentielle, il faut soustraire l’effet de pépite de la variance totale.

+

Après avoir réalisé ces calculs, nous pouvons donner ces paramètres à la fonction vgm de gstat pour superposer ce variogramme estimé par gls à notre variogramme des résidus du modèle linéaire classique.

+
+
gls_range <- 478
+gls_var <- 53.823^2
+gls_nugget <- 0.294 * gls_var
+gls_psill <- gls_var - gls_nugget
+
+gls_vgm <- vgm("Exp", psill = gls_psill, range = gls_range, nugget = gls_nugget)
+
+plot(var_mg, gls_vgm, col = "black", ylim = c(0, 4000))
+
+

+
+
+

Est-ce que le modèle est moins bien ajusté aux données ici? En fait, ce variogramme empirique représenté par les points avait été obtenu à partir des résidus du modèle linéaire ignorant la corrélation spatiale, donc c’est un estimé biaisé des corrélations spatiales réelles. La méthode est quand même adéquate pour vérifier rapidement s’il y a présence de corrélations spatiales. Toutefois, pour ajuster simultanément les coefficients de la régression et les paramètres de corrélation spatiale, l’approche des moindres carrés généralisés (GLS) est préférable et produira des estimés plus justes.

+

Finalement, notez que le résultat du modèle gls donne aussi l’AIC, que nous pouvons utiliser pour comparer l’ajustement de différents modèles (avec différents prédicteurs ou différentes formes de corrélation spatiale).

+
+
+

Exercice

+

Le fichier bryo_belg.csv est adapté des données de l’étude:

+
+

Neyens, T., Diggle, P.J., Faes, C., Beenaerts, N., Artois, T. et Giorgi, E. (2019) Mapping species richness using opportunistic samples: a case study on ground-floor bryophyte species richness in the Belgian province of Limburg. Scientific Reports 9, 19122. https://doi.org/10.1038/s41598-019-55593-x

+
+

Ce tableau de données indique la richesse spécifique des bryophytes au sol (richness) pour différents points d’échantillonnage de la province belge de Limbourg, avec leur position (x, y) en km, en plus de l’information sur la proportion de forêts (forest) et de milieux humides (wetland) dans une cellule de 1 km\(^2\) contenant le point d’échantillonnage.

+
+
bryo_belg <- read.csv("data/bryo_belg.csv")
+head(bryo_belg)
+
+
  richness    forest   wetland        x        y
+1        9 0.2556721 0.5036614 228.9516 220.8869
+2        6 0.6449114 0.1172068 227.6714 219.8613
+3        5 0.5039905 0.6327003 228.8252 220.1073
+4        3 0.5987329 0.2432942 229.2775 218.9035
+5        2 0.7600775 0.1163538 209.2435 215.2414
+6       10 0.6865434 0.0000000 210.4142 216.5579
+
+
+

Pour cet exercice, nous utiliserons la racine carrée de la richesse spécifique comme variable réponse. La transformation racine carrée permet souvent d’homogénéiser la variance des données de comptage afin d’y appliquer une régression linéaire.

+
    +
  1. Ajustez un modèle linéaire de la richesse spécifique transformée en fonction de la fraction de forêt et de milieux humides, sans tenir compte des corrélations spatiales. Quel est l’effet des deux prédicteurs selon ce modèle?

  2. +
  3. Calculez le variogramme empirique des résidus du modèle en (a). Semble-t-il y avoir une corrélation spatiale entre les points?

  4. +
+

Note: L’argument cutoff de la fonction variogram spécifie la distance maximale à laquelle le variogramme est calculé. Vous pouvez ajuster manuellement cette valeur pour bien voir le palier.

+
    +
  1. Ré-ajustez le modèle linéaire en (a) avec la fonction gls du package nlme, en essayant différents types de corrélations spatiales (exponentielle, gaussienne, sphérique). Comparez les modèles (incluant celui sans corrélation spatiale) avec l’AIC.

  2. +
  3. Quel est l’effet de la fraction de forêts et de milieux humides selon le modèle en (c)? Expliquez les différences entre les conclusions de ce modèle et du modèle en (a).

  4. +
+
+
+
+

23 Krigeage

+

Tel que mentionné précédemment, une application courante des modèles géostatistiques consiste à prédire la valeur de la variable de réponse à des points non-échantillonnés, une forme d’interpolation spatiale appelée krigeage (kriging).

+

Il existe trois principaux types de krigeage selon les suppositions faites au sujet de la variable réponse:

+
    +
  • Krigeage ordinaire: variable stationnaire avec une moyenne inconnue.

  • +
  • Krigeage simple: Variable stationnaire avec une moyenne connue.

  • +
  • Krigeage universel: Variable dont la tendance est donnée par un modèle linéaire ou non linéaire.

  • +
+

Pour toutes les méthodes de krigeage, les prédictions à un nouveau point sont une moyenne pondérée des valeurs à des points connus. Ces pondérations sont choisies de manière à ce que le krigeage fournisse la meilleure prédiction linéaire non biaisée de la variable de réponse, si les hypothèses du modèle (en particulier le variogramme) sont correctes. C’est-à-dire que, parmi toutes les prédictions non biaisées possibles, les poids sont choisis de manière à donner l’erreur quadratique moyenne minimale. Le krigeage fournit également une estimation de l’incertitude de chaque prédiction.

+

Bien que nous ne présentions pas ici les équations détaillées du krigeage, les poids dépendent à la fois des corrélations (estimées par le variogramme) entre les points échantillonnés et le nouveau point, ainsi que des corrélations entre les points échantillonnés eux-mêmes. Autrement dit, les points échantillonnés proches du nouveau point ont plus de poids, mais les points échantillonnés isolés ont également plus de poids, car les points échantillonnés proches les uns des autres fournissent une informations redondante.

+

Le krigeage est une méthode d’interpolation, donc la prédiction à un point échantillonné sera toujours égale à la valeur mesurée (la variable est supposée être mesurée sans erreur, elle varie seulement entre les points). Cependant, en présence d’un effet de pépite, tout petit déplacement par rapport à l’endroit échantillonné présentera une variabilité en fonction de la pépite.

+

Dans l’exemple ci-dessous, nous générons un nouvel ensemble de données composé de coordonnées (x, y) générées de façon aléatoire dans la zone d’étude ainsi que des valeurs de pH générées de façon aléatoire sur la base des données oxford. Nous appliquons ensuite la fonction krige pour prédire les valeurs de magnésium à ces nouveaux points. Notez que nous spécifions le variogramme dérivé des résultats du gls dans l’argument model de krige.

+
+
set.seed(14)
+new_points <- data.frame(
+    XCOORD = runif(100, min(oxford$XCOORD), max(oxford$XCOORD)),
+    YCOORD = runif(100, min(oxford$YCOORD), max(oxford$YCOORD)),
+    PH1 = rnorm(100, mean(oxford$PH1), sd(oxford$PH1))
+)
+
+pred <- krige(MG1 ~ PH1, locations = ~ XCOORD + YCOORD, data = oxford,
+              newdata = new_points, model = gls_vgm)
+
+
[using universal kriging]
+
+
head(pred)
+
+
    XCOORD    YCOORD var1.pred var1.var
+1 227.0169  162.1185  47.13065 1269.002
+2 418.9136  465.9013  79.68437 1427.269
+3 578.5943 2032.7477  60.30539 1264.471
+4 376.2734 1530.7193 127.22366 1412.875
+5 591.5336  421.6290 105.88124 1375.485
+6 355.7369  404.3378 127.73055 1250.114
+
+
+

Le résultat de krige comprend les nouvelles coordonnées du point, la prédiction de la variable var1.pred ainsi que sa variance estimée var1.var. Dans le graphique ci-dessous, nous montrons les prédictions moyennes de MG1 à partir du krigeage (triangles) ainsi que les mesures (cercles).

+
+
pred$MG1 <- pred$var1.pred
+
+ggplot(oxford, aes(x = YCOORD, y = XCOORD, color = MG1)) +
+    geom_point() +
+    geom_point(data = pred, shape = 17, size = 2) +
+    coord_fixed()
+
+

+
+
+

La moyenne et la variance estimées par krigeage peuvent être utilisées pour simuler les valeurs possibles de la variable à chaque nouveau point, conditionnellement aux valeurs échantillonnées. Dans l’exemple ci-dessous, nous avons effectué 4 simulations conditionnelles en ajoutant l’argument nsim = 4 à la même instruction krige.

+
+
sim_mg <- krige(MG1 ~ PH1, locations = ~ XCOORD + YCOORD, data = oxford,
+                newdata = new_points, model = gls_vgm, nsim = 4)
+
+
drawing 4 GLS realisations of beta...
+[using conditional Gaussian simulation]
+
+
head(sim_mg)
+
+
    XCOORD    YCOORD       sim1      sim2      sim3      sim4
+1 227.0169  162.1185   9.638739  34.53159  46.08685  77.86376
+2 418.9136  465.9013  60.029144  20.17179  76.46333  59.57924
+3 578.5943 2032.7477 100.791412  77.47887  73.50058  59.40279
+4 376.2734 1530.7193 112.615730 150.96664  78.76125 146.83928
+5 591.5336  421.6290  70.925240  72.85522 153.90610 126.63758
+6 355.7369  404.3378 161.608032 118.93640 134.45695 142.20074
+
+
+
+
library(tidyr)
+sim_mg <- pivot_longer(sim_mg, cols = c(sim1, sim2, sim3, sim4), 
+                       names_to = "sim", values_to = "MG1")
+ggplot(sim_mg, aes(x = YCOORD, y = XCOORD, color = MG1)) +
+    geom_point() +
+    coord_fixed() +
+    facet_wrap(~ sim)
+
+

+
+
+
+
+

24 Solutions

+
+
bryo_lm <- lm(sqrt(richness) ~ forest + wetland, data = bryo_belg)
+summary(bryo_lm)
+
+

+Call:
+lm(formula = sqrt(richness) ~ forest + wetland, data = bryo_belg)
+
+Residuals:
+    Min      1Q  Median      3Q     Max 
+-1.8847 -0.4622  0.0545  0.4974  2.3116 
+
+Coefficients:
+            Estimate Std. Error t value Pr(>|t|)    
+(Intercept)  2.34159    0.08369  27.981  < 2e-16 ***
+forest       1.11883    0.13925   8.034 9.74e-15 ***
+wetland     -0.59264    0.17216  -3.442 0.000635 ***
+---
+Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+
+Residual standard error: 0.7095 on 417 degrees of freedom
+Multiple R-squared:  0.2231,    Adjusted R-squared:  0.2193 
+F-statistic: 59.86 on 2 and 417 DF,  p-value: < 2.2e-16
+
+
+

La proportion de forêts a un effet positif significatif et la proportion de milieux humides a un effet négatif significatif sur la richesse des bryophytes.

+
+
plot(variogram(sqrt(richness) ~ forest + wetland, locations = ~ x + y,
+               data = bryo_belg, cutoff = 50), col = "black")
+
+

+
+
+

Le variogramme augmente au moins jusqu’à une distance de 40 km, il semble donc y avoir des corrélations spatiales dans les résidus du modèle.

+
+
bryo_exp <- gls(sqrt(richness) ~ forest + wetland, data = bryo_belg,
+                correlation = corExp(form = ~ x + y, nugget = TRUE))
+bryo_gaus <- gls(sqrt(richness) ~ forest + wetland, data = bryo_belg,
+                correlation = corGaus(form = ~ x + y, nugget = TRUE))
+bryo_spher <- gls(sqrt(richness) ~ forest + wetland, data = bryo_belg,
+                  correlation = corSpher(form = ~ x + y, nugget = TRUE))
+
+
+
AIC(bryo_lm)
+
+
[1] 908.6358
+
+
AIC(bryo_exp)
+
+
[1] 867.822
+
+
AIC(bryo_gaus)
+
+
[1] 870.9592
+
+
AIC(bryo_spher)
+
+
[1] 866.9117
+
+
+

Le modèle sphérique a l’AIC le plus faible.

+
+
summary(bryo_spher)
+
+
Generalized least squares fit by REML
+  Model: sqrt(richness) ~ forest + wetland 
+  Data: bryo_belg 
+       AIC      BIC    logLik
+  866.9117 891.1102 -427.4558
+
+Correlation Structure: Spherical spatial correlation
+ Formula: ~x + y 
+ Parameter estimate(s):
+     range     nugget 
+43.1727664  0.6063187 
+
+Coefficients:
+                 Value Std.Error   t-value p-value
+(Intercept)  2.0368769 0.2481636  8.207800   0.000
+forest       0.6989844 0.1481690  4.717481   0.000
+wetland     -0.2441130 0.1809118 -1.349348   0.178
+
+ Correlation: 
+        (Intr) forest
+forest  -0.251       
+wetland -0.235  0.241
+
+Standardized residuals:
+        Min          Q1         Med          Q3         Max 
+-1.75204183 -0.06568688  0.61415597  1.15240370  3.23322743 
+
+Residual standard error: 0.7998264 
+Degrees of freedom: 420 total; 417 residual
+
+
+

La magnitude des deux effets est moins importante et l’effet des milieux humides n’est plus significatif. Comme c’est le cas pour d’autres types de résidus non indépendants, la “taille effective” de l’échantillon est ici inférieure au nombre de points, car des points proches les uns des autres fournissent une information redondante. Par conséquent, la relation entre les prédicteurs et la réponse est moins claire que celle donnée par le modèle supposant que tous ces points étaient indépendants.

+

Notez que les résultats pour les trois modèles gls sont assez similaires, donc le choix d’inclure des corrélations spatiales était plus important que la forme exacte supposée pour le variogramme.

+
+
+

25 Données aréales

+

Les données aréales sont des variables mesurées pour des régions de l’espace; ces régions sont définies par des polygones. Ce type de données est plus courant en sciences sociales, en géographie humaine et en épidémiologie, où les données sont souvent disponibles à l’échelle de divisions administratives du territoire.

+

Ce type de données apparaît aussi fréquemment dans la gestion des ressources naturelles. Par exemple, la carte suivante montre les unités d’aménagement forestier du Ministère de la Forêts, de la Faune et des Parcs du Québec.

+

+

Supposons qu’une certaine variable soit disponible au niveau de ces divisions du territoire. Comment pouvons-nous modéliser la corrélation spatiale entre les unités qui sont spatialement rapprochées?

+

Une option serait d’appliquer les méthodes géostatistiques vues précédemment, en calculant par exemple la distance entre les centres des polygones.

+

Une autre option, qui est davantage privilégiée pour les données aréales, consiste à définir un réseau où chaque région est connectée aux régions voisines par un lien. On suppose ensuite que les variables sont directement corrélées entre régions voisines seulement. (Notons toutefois que les corrélations directes entre voisins immédiats génèrent aussi des corrélations indirectes pour une chaîne de voisins.)

+

Dans ce type de modèle, la corrélation n’est pas nécessairement la même d’un lien à un autre. Dans ce cas, chaque lien du réseau peut être associé à un poids représentant son importance pour la corrélation spatiale. Nous représentons ces poids par une matrice \(W\)\(w_{ij}\) est le poids du lien entre les régions \(i\) et \(j\). Une région n’a pas de lien avec elle-même, donc \(w_{ii} = 0\).

+

Un choix simple pour \(W\) consiste à assigner un poids égal à 1 si les régions sont voisines, sinon 0 (poids binaires).

+

Outre les divisions du territoire en polygones, un autre exemple de données aréales consiste en une grille où la variable est compilée pour chaque cellule de la grille. Dans ce cas, une cellule a généralement 4 ou 8 cellules voisines, selon que les diagonales soient incluses ou non.

+
+
+

26 Indice de Moran

+

Avant de discuter des modèles d’autocorrélation spatiale, nous présentons l’indice \(I\) de Moran, qui permet de tester si une corrélation significative est présente entre régions voisines.

+

L’indice de Moran est un coefficient d’autocorrélation spatiale des \(z\), pondéré par les poids \(w_{ij}\). Il prend donc des valeurs entre -1 et 1.

+

\[I = \frac{N}{\sum_i \sum_j w_{ij}} \frac{\sum_i \sum_j w_{ij} (z_i - \bar{z}) (z_j - \bar{z})}{\sum_i (z_i - \bar{z})^2}\]

+

Dans cette équation, nous reconnaissons l’expression d’une corrélation, soit le produit des écarts à la moyenne de deux variables \(z_i\) et \(z_j\), divisé par le produit de leurs écarts-types (qui est le même, donc on obtient la variance). La contribution de chaque paire \((i, j)\) est multipliée par son poids \(w_{ij}\) et le terme à gauche (le nombre de régions \(N\) divisé par la somme des poids) assure que le résultat soit borné entre -1 et 1.

+

Puisque la distribution de \(I\) est connue en l’absence d’autocorrélation spatiale, cette statistique permet de tester l’hypothèse nulle selon laquelle il n’y a pas de corrélation spatiale entre régions voisines.

+

Bien que nous ne verrons pas d’exemple dans ce cours-ci, l’indice de Moran peut aussi être appliqué aux données ponctuelles. Dans ce cas, on divise les paires de points en classes de distance et on calcule \(I\) pour chaque classe de distance; le poids \(w_{ij} = 1\) si la distance entre \(i\) et \(j\) se trouve dans la classe de distance voulue, 0 autrement.

+
+
+

27 Modèles d’autorégression spatiale

+

Rappelons-nous la formule pour une régression linéaire avec dépendance spatiale:

+

\[v = \beta_0 + \sum_i \beta_i u_i + z + \epsilon\]

+

\(z\) est la portion de la variance résiduelle qui est spatialement corrélée.

+

Il existe deux principaux types de modèles autorégressifs pour représenter la dépendance spatiale de \(z\): l’autorégression conditionnelle (CAR) et l’autorégression simultanée (SAR).

+
+

Autorégression conditionnelle (CAR)

+

Dans le modèle d’autorégression conditionnelle, la valeur de \(z_i\) pour la région \(i\) suit une distribution normale: sa moyenne dépend de la valeur \(z_j\) des régions voisines, multipliée par le poids \(w_{ij}\) et un coefficient de corrélation \(\rho\); son écart-type \(\sigma_{z_i}\) peut varier d’une région à l’autre.

+

\[z_i \sim \text{N}\left(\sum_j \rho w_{ij} z_j,\sigma_{z_i} \right)\]

+

Dans ce modèle, si \(w_{ij}\) est une matrice binaire (0 pour les non-voisins, 1 pour les voisins), alors \(\rho\) est le coefficient de corrélation partielle entre régions voisines. Cela est semblable à un modèle autorégressif d’ordre 1 dans le contexte de séries temporelles, où le coefficient d’autorégression indique la corrélation partielle.

+
+
+

Autorégression simultanée (SAR)

+

Dans le modèle d’autorégression simultanée, la valeur de \(z_i\) est donnée directement par la somme de contributions des valeurs voisines \(z_j\), multipliées par \(\rho w_{ij}\), avec un résidu indépendant \(\nu_i\) d’écart-type \(\sigma_z\).

+

\[z_i = \sum_j \rho w_{ij} z_j + \nu_i\]

+

À première vue, cela ressemble à un modèle autorégressif temporel. Il existe cependant une différence conceptuelle importante. Pour les modèles temporels, l’influence causale est dirigée dans une seule direction: \(v(t-2)\) affecte \(v(t-1)\) qui affecte ensuite \(v(t)\). Pour un modèle spatial, chaque \(z_j\) qui affecte \(z_i\) dépend à son tour de \(z_i\). Ainsi, pour déterminer la distribution conjointe des \(z\), il faut résoudre simultanément (d’où le nom du modèle) un système d’équations.

+

Pour cette raison, même si ce modèle ressemble à la formule du modèle conditionnel (CAR), les solutions des deux modèles diffèrent et dans le cas du SAR, le coefficient \(\rho\) n’est pas directement égal à la corrélation partielle due à chaque région voisine.

+

Pour plus de détails sur les aspects mathématiques de ces modèles, vous pouvez consulter l’article de Ver Hoef et al. (2018) suggéré en référence.

+

Pour l’instant, nous considérerons les SAR et les CAR comme deux types de modèles possibles pour représenter une corrélation spatiale sur un réseau. Nous pouvons toujours ajuster plusieurs modèles et les comparer avec l’AIC pour choisir la meilleure forme de la corrélation ou la meilleure matrice de poids.

+

Les modèles CAR et SAR partagent un avantage sur les modèles géostatistiques au niveau de l’efficacité. Dans un modèle géostatistique, les corrélations spatiales sont définies entre chaque paire de points, même si elles deviennent négligeables lorsque la distance augmente. Pour un modèle CAR ou SAR, seules les régions voisines contribuent et la plupart des poids sont égaux à 0, ce qui rend ces modèles plus rapides à ajuster qu’un modèle géostatistique lorsque les données sont massives.

+
+
+
+

28 Analyse des données aréales dans R

+

Pour illustrer l’analyse de données aréales dans R, nous chargeons les packages sf (pour lire des données géospatiales), spdep (pour définir des réseaux spatiaux et calculer l’indice de Moran) et spatialreg (pour les modèles SAR et CAR).

+
+
library(sf)
+library(spdep)
+library(spatialreg)
+
+

Nous utiliserons comme exemple un jeu de données qui présente une partie des résultats de l’élection provinciale de 2018 au Québec, avec des caractéristiques de la population de chaque circonscription. Ces données sont inclues dans un fichier de type shapefile (.shp), que nous pouvons lire avec la fonction read_sf du package sf.

+
+
elect2018 <- read_sf("data/elect2018.shp")
+head(elect2018)
+
+
Simple feature collection with 6 features and 9 fields
+Geometry type: MULTIPOLYGON
+Dimension:     XY
+Bounding box:  xmin: 97879.03 ymin: 174515.3 xmax: 694261.1 ymax: 599757.1
+Projected CRS: LambertAQ
+# A tibble: 6 × 10
+  circ             age_moy pct_frn pct_prp rev_med propCAQ propPQ propPLQ propQS
+  <chr>              <dbl>   <dbl>   <dbl>   <int>   <dbl>  <dbl>   <dbl>  <dbl>
+1 Abitibi-Est         40.8   0.963   0.644   34518    42.7   19.5    18.8   15.7
+2 Abitibi-Ouest       42.2   0.987   0.735   33234    34.1   33.3    11.3   16.6
+3 Acadie              40.3   0.573   0.403   25391    16.5    9      53.8   13.8
+4 Anjou-Louis-Riel    43.5   0.821   0.416   31275    28.9   14.7    39.1   14.5
+5 Argenteuil          43.3   0.858   0.766   31097    38.9   21.1    17.4   12.2
+6 Arthabaska          43.4   0.989   0.679   30082    61.8    9.4    11.4   12.6
+# … with 1 more variable: geometry <MULTIPOLYGON [m]>
+
+
+

Note: Le jeu de données est en fait composé de 4 fichiers avec les extensions .dbf, .prj, .shp et .shx, mais il suffit d’inscrire le nom du fichier .shp dans read_sf.

+

Les colonnes du jeu de données sont dans l’ordre:

+
    +
  • le nom de la circonscription électorale;
  • +
  • quatre caractéristiques de la population (âge moyen, fraction de la population qui parle principalement français à la maison, fraction des ménages qui sont propriétaires de leur logement, revenu médian);
  • +
  • quatre colonnes montrant la fraction des votes obtenues par les principaux partis (CAQ, PQ, PLQ, QS);
  • +
  • une colonne geometry qui contient l’objet géométrique (multipolygone) correspondant à la circonscription.
  • +
+

Pour illustrer une des variables sur une carte, nous appelons la fonction plot avec le nom de la colonne entre crochets et guillemets.

+
+
plot(elect2018["rev_med"])
+
+

+
+
+

Dans cet exemple, nous voulons modéliser la fraction des votes obtenue par la CAQ en fonction des caractéristiques de la population dans chaque circonscription et en tenant compte des corrélations spatiales entre circonscriptions voisines.

+
+

Définition du réseau de voisinage

+

La fonction poly2nb du package spdep définit un réseau de voisinage à partir de polygones. Le résultat vois est une liste de 125 éléments où chaque élément contient les indices des polygones voisins (limitrophes) d’un polygone donné.

+
+
vois <- poly2nb(elect2018)
+vois[[1]]
+
+
[1]   2  37  63  88 101 117
+
+
+

Ainsi, la première circonscription (Abitibi-Est) a 6 circonscriptions voisines, dont on peut trouver les noms ainsi:

+
+
elect2018$circ[vois[[1]]]
+
+
[1] "Abitibi-Ouest"               "Gatineau"                   
+[3] "Laviolette-Saint-Maurice"    "Pontiac"                    
+[5] "Rouyn-Noranda-Témiscamingue" "Ungava"                     
+
+
+

Nous pouvons illustrer ce réseau en faisant l’extraction des coordonnées du centre de chaque circonscription, en créant une carte muette avec plot(elect2018["geometry"]), puis en ajoutant le réseau comme couche additionnelle avec plot(vois, add = TRUE, coords = coords).

+
+
coords <- st_centroid(elect2018) %>%
+    st_coordinates()
+plot(elect2018["geometry"])
+plot(vois, add = TRUE, col = "red", coords = coords)
+
+

+
+
+

On peut faire un “zoom” sur le sud du Québec en choisissant les limites xlim et ylim appropriées.

+
+
plot(elect2018["geometry"], 
+     xlim = c(400000, 800000), ylim = c(100000, 500000))
+plot(vois, add = TRUE, col = "red", coords = coords)
+
+

+
+
+

Il nous reste à ajouter des poids à chaque lien du réseau avec la fonction nb2listw. Le style de poids “B” correspond aux poids binaires, soit 1 pour la présence de lien et 0 pour l’absence de lien entre deux circonscriptions.

+

Une fois ces poids définis, nous pouvons vérifier avec le test de Moran s’il y a une autocorrélation significative des votes obtenus par la CAQ entre circonscriptions voisines.

+
+
poids <- nb2listw(vois, style = "B")
+
+moran.test(elect2018$propCAQ, poids)
+
+

+    Moran I test under randomisation
+
+data:  elect2018$propCAQ  
+weights: poids    
+
+Moran I statistic standard deviate = 13.148, p-value < 2.2e-16
+alternative hypothesis: greater
+sample estimates:
+Moran I statistic       Expectation          Variance 
+      0.680607768      -0.008064516       0.002743472 
+
+
+

La valeur de \(I = 0.68\) est très significative à en juger par la valeur \(p\) du test.

+

Vérifions si la corrélation spatiale persiste après avoir tenu compte des quatre caractéristiques de la population, donc en inspectant les résidus d’un modèle linéaire incluant ces quatre prédicteurs.

+
+
elect_lm <- lm(propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, data = elect2018)
+summary(elect_lm)
+
+

+Call:
+lm(formula = propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, 
+    data = elect2018)
+
+Residuals:
+     Min       1Q   Median       3Q      Max 
+-30.9890  -4.4878   0.0562   6.2653  25.8146 
+
+Coefficients:
+              Estimate Std. Error t value Pr(>|t|)    
+(Intercept)  1.354e+01  1.836e+01   0.737    0.463    
+age_moy     -9.170e-01  3.855e-01  -2.378    0.019 *  
+pct_frn      4.588e+01  5.202e+00   8.820 1.09e-14 ***
+pct_prp      3.582e+01  6.527e+00   5.488 2.31e-07 ***
+rev_med     -2.624e-05  2.465e-04  -0.106    0.915    
+---
+Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+
+Residual standard error: 9.409 on 120 degrees of freedom
+Multiple R-squared:  0.6096,    Adjusted R-squared:  0.5965 
+F-statistic: 46.84 on 4 and 120 DF,  p-value: < 2.2e-16
+
+
moran.test(residuals(elect_lm), poids)
+
+

+    Moran I test under randomisation
+
+data:  residuals(elect_lm)  
+weights: poids    
+
+Moran I statistic standard deviate = 6.7047, p-value = 1.009e-11
+alternative hypothesis: greater
+sample estimates:
+Moran I statistic       Expectation          Variance 
+      0.340083290      -0.008064516       0.002696300 
+
+
+

L’indice de Moran a diminué mais demeure significatif, donc une partie de la corrélation précédente était induite par ces prédicteurs, mais il reste une corrélation spatiale due à d’autres facteurs.

+
+
+

Modèles d’autorégression spatiale

+

Finalement, nous ajustons des modèles SAR et CAR à ces données avec la fonction spautolm (spatial autoregressive linear model) de spatialreg. Voici le code pour un modèle SAR incluant l’effet des même quatre prédicteurs.

+
+
elect_sar <- spautolm(propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, 
+                      data = elect2018, listw = poids)
+summary(elect_sar)
+
+

+Call: spautolm(formula = propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, 
+    data = elect2018, listw = poids)
+
+Residuals:
+      Min        1Q    Median        3Q       Max 
+-23.08342  -4.10573   0.24274   4.29941  23.08245 
+
+Coefficients: 
+               Estimate  Std. Error z value  Pr(>|z|)
+(Intercept) 15.09421119 16.52357745  0.9135   0.36098
+age_moy     -0.70481703  0.32204139 -2.1886   0.02863
+pct_frn     39.09375061  5.43653962  7.1909 6.435e-13
+pct_prp     14.32329345  6.96492611  2.0565   0.03974
+rev_med      0.00016730  0.00023209  0.7208   0.47101
+
+Lambda: 0.12887 LR test value: 42.274 p-value: 7.9339e-11 
+Numerical Hessian standard error of lambda: 0.012069 
+
+Log likelihood: -433.8862 
+ML residual variance (sigma squared): 53.028, (sigma: 7.282)
+Number of observations: 125 
+Number of parameters estimated: 7 
+AIC: 881.77
+
+
+

La valeur donnée par Lambda dans le sommaire correspond au coefficient \(\rho\) dans notre description du modèle. Le test du rapport de vraisemblance (LR test) confirme que cette corrélation spatiale résiduelle (après avoir tenu compte de l’effet des prédicteurs) est significative.

+

Les effets estimés pour les prédicteurs sont semblables à ceux du modèle linéaire sans corrélation spatiale. Les effets de l’âge moyen, de la fraction de francophones et la fraction de propriétaires demeurent significatifs, bien que leur magnitude ait un peu diminué.

+

Pour évaluer un modèle CAR plutôt que SAR, nous devons spécifier family = "CAR".

+
+
elect_car <- spautolm(propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, 
+                      data = elect2018, listw = poids, family = "CAR")
+summary(elect_car)
+
+

+Call: spautolm(formula = propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, 
+    data = elect2018, listw = poids, family = "CAR")
+
+Residuals:
+      Min        1Q    Median        3Q       Max 
+-21.73315  -4.24623  -0.24369   3.44228  23.43749 
+
+Coefficients: 
+               Estimate  Std. Error z value  Pr(>|z|)
+(Intercept) 16.57164696 16.84155327  0.9840  0.325128
+age_moy     -0.79072151  0.32972225 -2.3981  0.016478
+pct_frn     38.99116707  5.43667482  7.1719 7.399e-13
+pct_prp     17.98557474  6.80333470  2.6436  0.008202
+rev_med      0.00012639  0.00023106  0.5470  0.584364
+
+Lambda: 0.15517 LR test value: 40.532 p-value: 1.9344e-10 
+Numerical Hessian standard error of lambda: 0.0026868 
+
+Log likelihood: -434.7573 
+ML residual variance (sigma squared): 53.9, (sigma: 7.3416)
+Number of observations: 125 
+Number of parameters estimated: 7 
+AIC: 883.51
+
+
+

Pour un modèle CAR avec des poids binaires, la valeur de Lambda (que nous avions appelé \(\rho\)) donne directement le coefficient de corrélation partielle entre circonscriptions voisines. Notez que l’AIC ici est légèrement supérieur au modèle SAR, donc ce dernier donnait un meilleur ajustement.

+
+
+

Exercice

+

Le jeu de données rls_covid, en format shapefile, contient des données sur les cas de COVID-19 détectés, le nombre de cas par 1000 personnes (taux_1k) et la densité de population (dens_pop) dans chacun des réseaux locaux de service de santé (RLS) du Québec. (Source: Données téléchargées de l’Institut national de santé publique du Québec en date du 17 janvier 2021.)

+
+
rls_covid <- read_sf("data/rls_covid.shp")
+head(rls_covid)
+
+
Simple feature collection with 6 features and 5 fields
+Geometry type: MULTIPOLYGON
+Dimension:     XY
+Bounding box:  xmin: 785111.2 ymin: 341057.8 xmax: 979941.5 ymax: 541112.7
+Projected CRS: Conique_conforme_de_Lambert_du_MTQ_utilis_e_pour_Adresse_Qu_be
+# A tibble: 6 × 6
+  RLS_code RLS_nom                 cas taux_1k dens_…¹                  geometry
+  <chr>    <chr>                 <dbl>   <dbl>   <dbl>        <MULTIPOLYGON [m]>
+1 0111     RLS de Kamouraska       152    7.34    6.76 (((827028.3 412772.4, 82…
+2 0112     RLS de Rivière-du-Lo…   256    7.34   19.6  (((855905 452116.9, 8557…
+3 0113     RLS de Témiscouata       81    4.26    4.69 (((911829.4 441311.2, 91…
+4 0114     RLS des Basques          28    3.3     5.35 (((879249.6 471975.6, 87…
+5 0115     RLS de Rimouski         576    9.96   15.5  (((917748.1 503148.7, 91…
+6 0116     RLS de La Mitis          76    4.24    5.53 (((951316 523499.3, 9525…
+# … with abbreviated variable name ¹​dens_pop
+
+
+

Ajustez un modèle linéaire du nombre de cas par 1000 en fonction de la densité de population (il est suggéré d’appliquer une transformation logarithmique à cette dernière). Vérifiez si les résidus du modèle sont corrélés entre RLS limitrophes avec un test de Moran, puis modélisez les mêmes données avec un modèle autorégressif conditionnel.

+
+
+

Référence

+

Ver Hoef, J.M., Peterson, E.E., Hooten, M.B., Hanks, E.M. et Fortin, M.-J. (2018) Spatial autoregressive models for statistical inference from ecological data. Ecological Monographs 88: 36-59.

+
+
+
+

29 GLMM avec processus spatial gaussien

+

Dans les parties précédentes, nous avons vu comment tenir compte de la dépendance spatiale dans les modèles de régression linéaire avec des modèles géostatistiques (également appelés processus gaussiens) ou des modèles d’autocorrélation spatiale (CAR/SAR). Dans cette dernière partie, nous verrons comment combiner ces caractéristiques avec des modèles de régression plus complexes, en particulier les modèles linéaires généralisés à effets mixtes (GLMM).

+
+

Données

+

Le jeu de données gambia inclus avec le package geoR présente les résultats d’une étude sur la prévalence du paludisme chez les enfants de 65 villages en Gambie. Nous utiliserons une version légèrement transformée des données contenues dans le fichier gambia.csv.

+
+
library(geoR)
+
+gambia <- read.csv("data/gambia.csv")
+head(gambia)
+
+
  id_village        x        y pos  age netuse treated green phc
+1          1 349.6313 1458.055   1 1783      0       0 40.85   1
+2          1 349.6313 1458.055   0  404      1       0 40.85   1
+3          1 349.6313 1458.055   0  452      1       0 40.85   1
+4          1 349.6313 1458.055   1  566      1       0 40.85   1
+5          1 349.6313 1458.055   0  598      1       0 40.85   1
+6          1 349.6313 1458.055   1  590      1       0 40.85   1
+
+
+

Voici les champs de ce jeu de données:

+
    +
  • id_village: Identifiant du village.
  • +
  • x and y: Coordonnées spatiales du village (en km, basé sur les coordonnées UTM).
  • +
  • pos: Réponse binaire, si l’enfant a eu un test positif du paludisme.
  • +
  • age: Âge de l’enfant en jours.
  • +
  • netuse: Si l’enfant dort sous un moustiquaire ou non.
  • +
  • treated: Si le moustiquaire est traité ou non.
  • +
  • green: Mesure de la végétation basée sur les données de télédétection (disponible à l’échelle du village).
  • +
  • phc: Présence ou absence d’un centre de santé publique pour le village.
  • +
+

Nous pouvons compter le nombre de cas positifs et le nombre total d’enfants testés par village pour cartographier la fraction des cas positifs (ou prévalence, prev).

+
+
# Jeu de données à l'échelle du village
+gambia_agg <- group_by(gambia, id_village, x, y, green, phc) %>%
+    summarize(pos = sum(pos), total = n()) %>%
+    mutate(prev = pos / total) %>%
+    ungroup()
+
+
`summarise()` has grouped output by 'id_village', 'x', 'y', 'green'. You can
+override using the `.groups` argument.
+
+
head(gambia_agg)
+
+
# A tibble: 6 × 8
+  id_village     x     y green   phc   pos total  prev
+       <int> <dbl> <dbl> <dbl> <int> <int> <int> <dbl>
+1          1  350. 1458.  40.8     1    17    33 0.515
+2          2  359. 1460.  40.8     1    19    63 0.302
+3          3  360. 1460.  40.1     0     7    17 0.412
+4          4  364. 1497.  40.8     0     8    24 0.333
+5          5  366. 1460.  40.8     0    10    26 0.385
+6          6  367. 1463.  40.8     0     7    18 0.389
+
+
+
+
ggplot(gambia_agg, aes(x = x, y = y)) +
+    geom_point(aes(color = prev)) +
+    geom_path(data = gambia.borders, aes(x = x / 1000, y = y / 1000)) +
+    coord_fixed() +
+    theme_minimal() +
+    scale_color_viridis_c()
+
+

+
+
+

Nous utilisons le jeu de données gambia.borders du package geoR pour tracer les frontières des pays avec geom_path. Comme ces frontières sont en mètres, nous les divisons par 1000 pour obtenir la même échelle que nos points. Nous utilisons également coord_fixed pour assurer un rapport d’aspect de 1:1 entre les axes et utilisons la palette de couleur viridis, qui permet de visualiser plus facilement une variable continue par rapport à la palette par défaut dans ggplot2.

+

Sur la base de cette carte, il semble y avoir une corrélation spatiale dans la prévalence du paludisme, le groupe de villages de l’est montrant des valeurs de prévalence plus élevées (jaune-vert) et le groupe du milieu montrant des valeurs de prévalence plus faibles (violet).

+
+
+

GLMM non spatial

+

Pour ce premier exemple, nous allons ignorer l’aspect spatial des données et modéliser la présence du paludisme (pos) en fonction de l’utilisation d’une moustiquaire (netuse) et de la présence d’un centre de santé publique (phc). Comme nous avons une réponse binaire, nous devons utiliser un modèle de régression logistique (un GLM). Comme nous avons des prédicteurs au niveau individuel et au niveau du village et que nous nous attendons à ce que les enfants d’un même village aient une probabilité plus similaire d’avoir le paludisme même après avoir pris en compte ces prédicteurs, nous devons ajouter un effet aléatoire du village. Le résultat est un GLMM que nous ajustons en utilisant la fonction glmer du package lme4.

+
+
library(lme4)
+
+mod_glmm <- glmer(pos ~ netuse + phc + (1 | id_village), 
+                  data = gambia, family = binomial)
+summary(mod_glmm)
+
+
Generalized linear mixed model fit by maximum likelihood (Laplace
+  Approximation) [glmerMod]
+ Family: binomial  ( logit )
+Formula: pos ~ netuse + phc + (1 | id_village)
+   Data: gambia
+
+     AIC      BIC   logLik deviance df.resid 
+  2428.0   2450.5  -1210.0   2420.0     2031 
+
+Scaled residuals: 
+    Min      1Q  Median      3Q     Max 
+-2.1286 -0.7120 -0.4142  0.8474  3.3434 
+
+Random effects:
+ Groups     Name        Variance Std.Dev.
+ id_village (Intercept) 0.8149   0.9027  
+Number of obs: 2035, groups:  id_village, 65
+
+Fixed effects:
+            Estimate Std. Error z value Pr(>|z|)    
+(Intercept)   0.1491     0.2297   0.649   0.5164    
+netuse       -0.6044     0.1442  -4.190 2.79e-05 ***
+phc          -0.4985     0.2604  -1.914   0.0556 .  
+---
+Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+
+Correlation of Fixed Effects:
+       (Intr) netuse
+netuse -0.422       
+phc    -0.715 -0.025
+
+
+

D’après ces résultats, les variables netuse et phc sont toutes deux associées à une diminution de la prévalence du paludisme, bien que l’effet de phc ne soit pas significatif à un seuil \(\alpha = 0.05\). L’ordonnée à l’origine (0.149) est le logit de la probabilité de présence du paludisme pour un enfant sans moustiquaire et sans centre de santé publique, mais c’est l’ordonnée à l’origine moyenne pour tous les villages. Il y a beaucoup de variation entre les villages selon l’écart-type de l’effet aléatoire (0.90). Nous pouvons obtenir l’ordonnée à l’origine estimée pour chaque village avec la fonction coef:

+
+
head(coef(mod_glmm)$id_village)
+
+
  (Intercept)     netuse        phc
+1  0.93727515 -0.6043602 -0.4984835
+2  0.09204843 -0.6043602 -0.4984835
+3  0.22500620 -0.6043602 -0.4984835
+4 -0.46271089 -0.6043602 -0.4984835
+5  0.13680037 -0.6043602 -0.4984835
+6 -0.03723346 -0.6043602 -0.4984835
+
+
+

Par exemple, l’ordonnée à l’origine pour le village 1 est environ 0.94, équivalente à une probabilité de 72%:

+
+
plogis(0.937)
+
+
[1] 0.7184933
+
+
+

tandis que celle pour le village 2 est équivalente à une probabilité de 52%:

+
+
plogis(0.092)
+
+
[1] 0.5229838
+
+
+

Le package DHARMa fournit une méthode générale pour vérifier si les résidus d’un GLMM sont distribués selon le modèle spécifié et s’il existe une tendance résiduelle. Il simule des réplicats de chaque observation selon le modèle ajusté et détermine ensuite un “résidu standardisé”, qui est la position relative de la valeur observée par rapport aux valeurs simulées, par exemple 0 si l’observation est plus petite que toutes les simulations, 0.5 si elle se trouve au milieu, etc. Si le modèle représente bien les données, chaque valeur du résidu standardisé entre 0 et 1 doit avoir la même probabilité, de sorte que les résidus standardisés doivent produire une distribution uniforme entre 0 et 1.

+

La fonction simulateResiduals effectue le calcul des résidus standardisés, puis la fonction plot trace les graphiques de diagnostic avec les résultats de certains tests.

+
+
library(DHARMa)
+res_glmm <- simulateResiduals(mod_glmm)
+plot(res_glmm)
+
+

+
+
+

Le graphique de gauche est un graphique quantile-quantile des résidus standardisés. Les résultats de trois tests statistiques sont également présentés: un test de Kolmogorov-Smirnov (KS) qui vérifie s’il y a un écart par rapport à la distribution théorique, un test de dispersion qui vérifie s’il y a une sous-dispersion ou une surdispersion et un test de valeurs aberrantes (outlier) basé sur le nombre de résidus qui sont plus extrêmes que toutes les simulations. Ici, nous obtenons un résultat significatif pour les valeurs aberrantes, bien que le message indique que ce résultat pourrait avoir un taux d’erreur de type I plus grand que prévu dans ce cas.

+

À droite, nous obtenons généralement un graphique des résidus standardisés (en y) en fonction du rang des valeurs prédites, afin de vérifier l’absence de tendance résiduelle. Ici, les prédictions sont regroupées par quartile, il serait donc préférable d’agréger les prédictions et les résidus par village, ce que nous pouvons faire avec la fonction recalculateResiduals.

+
+
plot(recalculateResiduals(res_glmm, group = gambia$id_village))
+
+
DHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details
+
+
+

+
+
+

Le graphique de droite montre les points individuels, ainsi qu’une régression quantile pour le 1er quartile, la médiane et le 3e quartile. En théorie, ces trois courbes devraient être des lignes droites horizontales (pas de tendance des résidus par rapport aux prévisions). La courbe pour le 3e quartile (en rouge) est significativement différente d’une ligne horizontale, ce qui pourrait indiquer un effet systématique manquant dans le modèle.

+
+
+

GLMM spatial avec spaMM

+

Le package spaMM (modèles mixtes spatiaux) est un package R relativement récent qui permet d’effectuer une estimation approximative du maximum de vraisemblance des paramètres pour les GLM avec dépendance spatiale, modélisés soit comme un processus gaussien, soit avec un CAR (nous verrons ce dernier dans la dernière section). Le package implémente différents algorithmes, mais il existe une fonction unique fitme qui choisit l’algorithme approprié pour chaque type de modèle. Par exemple, voici le même modèle (non spatial) que nous avons vu ci-dessus, ajusté avec spaMM.

+
+
library(spaMM)
+
+mod_spamm_glmm <- fitme(pos ~ netuse + phc + (1 | id_village),
+                        data = gambia, family = binomial)
+summary(mod_spamm_glmm)
+
+
formula: pos ~ netuse + phc + (1 | id_village)
+Estimation of lambda by ML (p_v approximation of logL).
+Estimation of fixed effects by ML (p_v approximation of logL).
+family: binomial( link = logit ) 
+ ------------ Fixed effects (beta) ------------
+            Estimate Cond. SE t-value
+(Intercept)   0.1491   0.2287  0.6519
+netuse       -0.6045   0.1420 -4.2567
+phc          -0.4986   0.2593 -1.9231
+ --------------- Random effects ---------------
+Family: gaussian( link = identity ) 
+           --- Variance parameters ('lambda'):
+lambda = var(u) for u ~ Gaussian; 
+   id_village  :  0.8151  
+             --- Coefficients for log(lambda):
+      Group        Term Estimate Cond.SE
+ id_village (Intercept)  -0.2045  0.2008
+# of obs: 2035; # of groups: id_village, 65 
+ ------------- Likelihood values  -------------
+                        logLik
+logL       (p_v(h)): -1210.016
+
+
+

Notez que les estimés des effets fixes ainsi que la variance des effets aléatoires sont presque identiques à ceeux obtenues par glmer ci-dessus.

+

Nous pouvons maintenant utiliser spaMM pour ajuster le même modèle avec l’ajout de corrélations spatiales entre les villages. Dans la formule du modèle, ceci est représenté comme un effet aléatoire Matern(1 | x + y), ce qui signifie que les ordonnées à l’origine sont spatialement corrélées entre les villages suivant une fonction de corrélation de Matérn des coordonnées (x, y). La fonction de Matérn est une fonction flexible de corrélation spatiale qui comprend un paramètre de forme \(\nu\) (nu), de sorte que lorsque \(\nu = 0,5\), elle est équivalente à la corrélation exponentielle, mais quand \(\nu\) prend de grandes valeurs, elle se rapproche d’une corrélation gaussienne. Nous pourrions laisser la fonction estimer \(\nu\), mais ici nous le fixons à 0.5 avec l’argument fixed de fitme.

+
+
mod_spamm <- fitme(pos ~ netuse + phc + Matern(1 | x + y) + (1 | id_village),
+                   data = gambia, family = binomial, fixed = list(nu = 0.5))
+
+
Increase spaMM.options(separation_max=<.>) to at least 21 if you want to check separation (see 'help(separation)').
+
+
summary(mod_spamm)
+
+
formula: pos ~ netuse + phc + Matern(1 | x + y) + (1 | id_village)
+Estimation of corrPars and lambda by ML (p_v approximation of logL).
+Estimation of fixed effects by ML (p_v approximation of logL).
+Estimation of lambda by 'outer' ML, maximizing logL.
+family: binomial( link = logit ) 
+ ------------ Fixed effects (beta) ------------
+            Estimate Cond. SE t-value
+(Intercept)  0.06861   0.3352  0.2047
+netuse      -0.51719   0.1407 -3.6757
+phc         -0.44416   0.2052 -2.1648
+ --------------- Random effects ---------------
+Family: gaussian( link = identity ) 
+                   --- Correlation parameters:
+      1.nu      1.rho 
+0.50000000 0.05128692 
+           --- Variance parameters ('lambda'):
+lambda = var(u) for u ~ Gaussian; 
+   x + y  :  0.6421 
+   id_village  :  0.1978  
+# of obs: 2035; # of groups: x + y, 65; id_village, 65 
+ ------------- Likelihood values  -------------
+                        logLik
+logL       (p_v(h)): -1197.968
+
+
+

Commençons par vérifier les effets aléatoires du modèle. La fonction de corrélation spatiale a un paramètre rho égal à 0.0513. Ce paramètre dans spaMM est l’inverse de la portée, donc ici la portée de la corrélation exponentielle est de 1/0.0513 ou environ 19.5 km. Il y a maintenant deux pramètres de variance, celui identifié comme x + y est la variance à longue distance (i.e. le palier) pour le modèle de corrélation exponentielle alors que celui identifié comme id_village montre la portion non corrélée de la variation entre les villages.

+

Si nous avions ici laissé les effets aléatoires (1 | id_village) dans la formule pour représenter la partie non spatiale de la variation entre les villages, nous pourrions également représenter ceci avec un effet de pépite dans le modèle géostatistique. Dans les deux cas, cela représenterait l’idée que même deux villages très proches l’un de l’autre auraient des prévalences de base différentes dans le modèle.

+

Par défaut, la fonction Matern n’a pas d’effet de pépite, mais nous pouvons en ajouter un en spécifiant une pépite non nulle dans la liste initiale des paramètres init.

+
+
mod_spamm2 <- fitme(pos ~ netuse + phc + Matern(1 | x + y),
+                    data = gambia, family = binomial, fixed = list(nu = 0.5),
+                    init = list(Nugget = 0.1))
+
+
Increase spaMM.options(separation_max=<.>) to at least 21 if you want to check separation (see 'help(separation)').
+
+
summary(mod_spamm2)
+
+
formula: pos ~ netuse + phc + Matern(1 | x + y)
+Estimation of corrPars and lambda by ML (p_v approximation of logL).
+Estimation of fixed effects by ML (p_v approximation of logL).
+Estimation of lambda by 'outer' ML, maximizing logL.
+family: binomial( link = logit ) 
+ ------------ Fixed effects (beta) ------------
+            Estimate Cond. SE t-value
+(Intercept)  0.06861   0.3352  0.2047
+netuse      -0.51719   0.1407 -3.6757
+phc         -0.44416   0.2052 -2.1648
+ --------------- Random effects ---------------
+Family: gaussian( link = identity ) 
+                   --- Correlation parameters:
+      1.nu   1.Nugget      1.rho 
+0.50000000 0.23551027 0.05128692 
+           --- Variance parameters ('lambda'):
+lambda = var(u) for u ~ Gaussian; 
+   x + y  :  0.8399  
+# of obs: 2035; # of groups: x + y, 65 
+ ------------- Likelihood values  -------------
+                        logLik
+logL       (p_v(h)): -1197.968
+
+
+

Comme vous pouvez le voir, toutes les estimations sont les mêmes, sauf que la variance de la portion spatiale (palier) est maintenant de 0.84 et que la pépite est égale à une fraction 0.235 de ce palier, soit une variance de 0.197, ce qui est identique à l’effet aléatoire id_village dans la version ci-dessus. Les deux formulations sont donc équivalentes.

+

Maintenant, rappelons les coefficients que nous avions obtenus pour le GLMM non spatial :

+
+
summary(mod_glmm)$coefficients
+
+
              Estimate Std. Error    z value     Pr(>|z|)
+(Intercept)  0.1490596  0.2296971  0.6489399 5.163772e-01
+netuse      -0.6043602  0.1442448 -4.1898243 2.791706e-05
+phc         -0.4984835  0.2604083 -1.9142382 5.558973e-02
+
+
+

Dans la version spatiale, les deux effets fixes se sont légèrement rapprochés de zéro, mais l’erreur-type de l’effet de phc a diminué. Il est intéressant de noter que l’inclusion de la dépendance spatiale nous a permis d’estimer plus précisément l’effet de la présence d’un centre de santé publique dans le village. Ce ne serait pas toujours le cas: pour un prédicteur qui est également fortement corrélé dans l’espace, la corrélation spatiale dans la réponse rend plus difficile l’estimation de l’effet de ce prédicteur, puisqu’il est confondu avec l’effet spatial. Cependant, pour un prédicteur qui n’est pas corrélé dans l’espace, l’inclusion de l’effet spatial réduit la variance résiduelle (non spatiale) et peut donc augmenter la précision de l’effet du prédicteur.

+

Le package spaMM est également compatible avec DHARMa pour les diagnostics résiduels. (Vous pouvez ignorer l’avertissement selon lequel il ne fait pas partie de la classe des modèles pris en charge, cela est dû à l’utilisation de la fonction fitme plutôt que d’une fonction d’algorithme spécifique dans spaMM).

+
+
res_spamm <- simulateResiduals(mod_spamm2)
+plot(res_spamm)
+
+
DHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details
+
+
+

+
+
plot(recalculateResiduals(res_spamm, group = gambia$id_village))
+
+
DHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details
+
+
+

+
+
+

Enfin, bien que nous allons montrer comment calculer et visualiser des prédictions spatiales ci-dessous, nous pouvons produire une carte rapide des effets spatiaux estimés dans un modèle spaMM avec la fonction filled.mapMM.

+
+
filled.mapMM(mod_spamm2)
+
+

+
+
+
+
+

Processus gaussiens vs. splines de lissage

+

Si vous connaissez bien les modèles additifs généralisés (GAM), vous avez peut-être pensé à représenter la variation spatiale de la prévalence du paludisme (comme le montre la carte ci-dessus) par une spline de lissage en 2D (en fonction de \(x\) et \(y\)) dans un GAM.

+

Le code ci-dessous correspond à l’équivalent GAM de notre GLMM avec processus gaussien ci-dessus, ajusté avec la fonction gam du package mgcv. L’effet spatial est représenté par la spline 2D s(x, y) alors que l’effet aléatoire non spatial de village est représenté par s(id_village, bs = "re"), qui est équivalent à (1 | id_village) dans les modèles précédents. Notez que pour la fonction gam, les variables catégorielles doivent être explicitement converties en facteurs.

+
+
library(mgcv)
+gambia$id_village <- as.factor(gambia$id_village)
+mod_gam <- gam(pos ~ netuse + phc + s(id_village, bs = "re") + s(x, y), 
+               data = gambia, family = binomial)
+
+

Pour visualiser la spline en 2D, nous utiliserons le package gratia.

+
+
library(gratia)
+draw(mod_gam)
+
+

+
+
+

Notez que le graphique de la spline s(x, y) (en haut à droite) ne s’étend pas trop loin des emplacements des données (les autres zones sont vides). Dans ce graphique, on peut également voir que les effets aléatoires des villages suivent la distribution gaussienne attendue (en haut à gauche).

+

Ensuite, nous utiliserons à la fois le GLMM spatial de la section précédente et ce GAMM pour prédire la prévalence moyenne sur une grille spatiale de points contenue dans le fichier gambia_pred.csv. Le graphique ci-dessous ajoute ces points de prédiction (en noir) sur la carte précédente des points de données.

+
+
gambia_pred <- read.csv("data/gambia_pred.csv")
+
+ggplot(gambia_agg, aes(x = x, y = y)) +
+    geom_point(data = gambia_pred) +
+    geom_point(aes(color = prev)) +
+    geom_path(data = gambia.borders, aes(x = x / 1000, y = y / 1000)) +
+    coord_fixed() +
+    theme_minimal() +
+    scale_color_viridis_c()
+
+

+
+
+

Pour faire des prédictions à partir du modèle GAMM à ces endroits, le code ci-dessous effectue les étapes suivantes:

+
    +
  • Tous les prédicteurs du modèle doivent se trouver dans le tableau de données de prédiction, nous ajoutons donc des valeurs constantes de netuse et phc (toutes deux égales à 1) pour tous les points. Ainsi, nous ferons des prédictions sur la prévalence du paludisme dans le cas où un moustiquaire est utilisée et où un centre de santé publique est présent. Nous ajoutons également un id_village constant, bien qu’il ne soit pas utilisé dans les prédictions (voir ci-dessous).

  • +
  • Nous appelons la fonction predict à la sortie de gam pour produire des prédictions aux nouveaux points de données (argument newdata), en incluant les erreurs-types (se.fit = TRUE) et en excluant les effets aléatoires du village, donc la prédiction est faite pour un “village moyen”. L’objet résultant gam_pred aura des colonnes fit (prédiction moyenne) et se.fit (erreur-type). Ces prédictions et erreurs-types sont sur l’échelle du lien (logit).

  • +
  • Nous rattachons le jeu de données de prédiction original à gam_pred avec cbind.

  • +
  • Nous ajoutons des colonnes pour la prédiction moyenne et les limites de l’intervalle de confiance à 50% (moyenne \(\pm\) 0.674 erreur-type), converties de l’échelle logit à l’échelle de probabilité avec plogis. Nous choisissons un intervalle de 50% car un intervalle de 95% peut être trop large ici pour contraster les différentes prédictions sur la carte à la fin de cette section.

  • +
+
+
gambia_pred <- mutate(gambia_pred, netuse = 1, phc = 1, id_village = 1)
+
+gam_pred <- predict(mod_gam, newdata = gambia_pred, se.fit = TRUE, 
+                    exclude = "s(id_village)")
+gam_pred <- cbind(gambia_pred, as.data.frame(gam_pred))
+gam_pred <- mutate(gam_pred, pred = plogis(fit), 
+                   lo = plogis(fit - 0.674 * se.fit), # 50% CI
+                   hi = plogis(fit + 0.674 * se.fit))
+
+

Note : La raison pour laquelle nous ne faisons pas de prédictions directement sur l’échelle de probabilité (réponse) est que la formule normale des intervalles de confiance s’applique plus précisément sur l’échelle logit. L’ajout d’un certain nombre d’erreurs-types autour de la moyenne sur l’échelle de probabilité conduirait à des intervalles moins précis et peut-être même à des intervalles de confiance en dehors de la plage de valeurs possible (0, 1) pour une probabilité.

+

Nous appliquons la même stratégie pour faire des prédictions à partir du GLMM spatial avec spaMM. Il y a quelques différences dans la méthode predict par rapport au cas du GAMM.

+
    +
  • L’argument binding = "fit" signifie que les prédictions moyennes (colonne fit) seront attachées à l’ensemble de données de prédiction et retournées sous forme de tableau de données spamm_pred.

  • +
  • L’argument variances = list(linPred = TRUE) indique à predict de calculer la variance du prédicteur linéaire (donc le carré de l’erreur-type). Cependant, il apparaît comme un attribut predVar dans le tableau de données de sortie plutôt que dans une colonne se.fit, donc nous le déplaçons vers une colonne sur la ligne suivante.

  • +
+
+
spamm_pred <- predict(mod_spamm, newdata = gambia_pred, type = "link",
+                      binding = "fit", variances = list(linPred = TRUE))
+spamm_pred$se.fit <- sqrt(attr(spamm_pred, "predVar"))
+spamm_pred <- mutate(spamm_pred, pred = plogis(fit), 
+                     lo = plogis(fit - 0.674 * se.fit),
+                     hi = plogis(fit + 0.674 * se.fit))
+
+

Enfin, nous combinons les deux ensembles de prédictions sous la forme de différentes rangées d’un tableau de données pred_all avec bind_rows. Le nom du tableau de données d’où provient chaque prédiction (gam ou spamm) apparaîtra dans la colonne “model” (argument .id). Pour simplifier la production du prochain graphique, nous utilisons ensuite pivot_longer dans le package tidyr pour changer les trois colonnes “pred”, “lo” et “hi” en deux colonnes, “stat” et “value” (pred_tall a donc trois rangées pour chaque rangée dans pred_all).

+
+
pred_all <- bind_rows(gam = gam_pred, spamm = spamm_pred, .id = "model")
+
+library(tidyr)
+pred_tall <- pivot_longer(pred_all, c(pred, lo, hi), names_to = "stat",
+                          values_to = "value")
+
+

Une fois ces étapes franchies, nous pouvons enfin examiner les cartes de prédiction (moyenne, limites inférieure et supérieure de l’intervalle de confiance à 50 %) à l’aide d’un graphique ggplot. Les points de données originaux sont indiqués en rouge.

+
+
ggplot(pred_tall, aes(x = x, y = y)) +
+    geom_point(aes(color = value)) +
+    geom_point(data = gambia_agg, color = "red", size = 0) +
+    coord_fixed() +
+    facet_grid(stat~model) +
+    scale_color_viridis_c() +
+    theme_minimal()
+
+

+
+
+

Bien que les deux modèles s’accordent à dire que la prévalence est plus élevée près du groupe de villages de l’est, le GAMM estime également une prévalence plus élevée en quelques points (bord ouest et autour du centre) où il n’y a pas de données. Il s’agit d’un artefact de la forme de la spline autour des points de données, puisqu’une spline est censée correspondre à une tendance globale, bien que non linéaire. En revanche, le modèle géostatistique représente l’effet spatial sous forme de corrélations locales et revient à la prévalence moyenne globale lorsqu’il est éloigné de tout point de données, ce qui est une supposition plus sûre. C’est l’une des raisons pour lesquelles il est préférable de choisir un modèle géostatistique / processus gaussien dans ce cas.

+
+
+

Méthodes bayésiennes pour les GLMM avec processus gaussiens

+

Les modèles bayésiens fournissent un cadre flexible pour exprimer des modèles avec une structure de dépendance complexe entre les données, y compris la dépendance spatiale. Cependant, l’ajustement d’un modèle de processus gaussien avec une approche entièrement bayésienne peut être lent, en raison de la nécessité de calculer une matrice de covariance spatiale entre toutes les paires de points à chaque itération.

+

La méthode INLA (pour integrated nested Laplace approximation) effectue un calcul approximatif de la distribution postérieure bayésienne, ce qui la rend adaptée aux problèmes de régression spatiale. Nous ne l’abordons pas dans ce cours, mais je recommande le manuel de Paula Moraga (dans la section des références ci-dessous) qui fournit des exemples concrets d’utilisation de la méthode INLA pour divers modèles de données géostatistiques et aréales, dans le contexte de l’épidémiologie, y compris des modèles avec une dépendance à la fois spatiale et temporelle. Le livre présente les mêmes données sur le paludisme en Gambie comme exemple d’un ensemble de données géostatistiques, ce qui a inspiré son utilisation dans ce cours.

+
+
+
+

30 GLMM avec autorégression spatiale

+

Nous revenons au dernier exemple de la partie précédente, où nous avions modélisé le taux de cas de COVID-19 (cas / 1000) pour les divisions administratives du réseau de la santé (RLS) au Québec en fonction de leur densité de population. Le taux est donné par la colonne “taux_1k” dans le shapefile rls_covid.

+
+
library(sf)
+rls_covid <- read_sf("data/rls_covid.shp")
+rls_covid <- rls_covid[!is.na(rls_covid$dens_pop), ]
+plot(rls_covid["taux_1k"])
+
+

+
+
+

Auparavant, nous avions modélisé le logarithme de ce taux comme une fonction linéaire du logarithme de la densité de population, la variance résiduelle étant corrélée entre les unités voisines via une structure CAR (autorégression conditionnelle), comme le montre le code ci-dessous.

+
+
library(spdep)
+library(spatialreg)
+
+rls_nb <- poly2nb(rls_covid)
+rls_w <- nb2listw(rls_nb, style = "B")
+
+car_lm <- spautolm(log(taux_1k) ~ log(dens_pop), data = rls_covid,
+                   listw = rls_w, family = "CAR")
+summary(car_lm)
+
+

+Call: spautolm(formula = log(taux_1k) ~ log(dens_pop), data = rls_covid, 
+    listw = rls_w, family = "CAR")
+
+Residuals:
+      Min        1Q    Median        3Q       Max 
+-1.201858 -0.254084 -0.053348  0.281482  1.427053 
+
+Coefficients: 
+              Estimate Std. Error z value  Pr(>|z|)
+(Intercept)   1.702068   0.168463 10.1035 < 2.2e-16
+log(dens_pop) 0.206623   0.032848  6.2903 3.169e-10
+
+Lambda: 0.15762 LR test value: 23.991 p-value: 9.6771e-07 
+Numerical Hessian standard error of lambda: 0.0050486 
+
+Log likelihood: -80.68953 
+ML residual variance (sigma squared): 0.2814, (sigma: 0.53048)
+Number of observations: 95 
+Number of parameters estimated: 4 
+AIC: 169.38
+
+
+

Rappel: La fonction poly2nb du package spdep crée une liste de voisins basée sur les polygones limitrophes dans un shapefile, puis nb2listw la convertit en une liste de poids, ici des poids binaires (style = "B") de sorte que chaque région limitrophe reçoive le même poids de 1 dans le modèle autorégressif.

+

Au lieu d’utiliser les taux, il serait possible de modéliser directement les cas avec une régression de Poisson, qui est appropriée pour les données de comptage. Pour tenir compte du fait que si le risque par personne était égal, les cas seraient proportionnels à la population, nous pouvons ajouter la population de l’unité pop comme offset dans la régression de Poisson. Par conséquent, le modèle ressemblerait à : cas ~ log(dens_pop) + offset(log(pop)). Notez que puisque la régression de Poisson utilise un lien logarithmique, ce modèle avec log(pop) comme offset suppose que log(cas / pop) (donc le taux logarithmique) est proportionnel à log(dens_pop), tout comme le modèle linéaire ci-dessus, mais il a l’avantage de modéliser la variabilité des données brutes (le nombre de cas) directement avec une distribution de Poisson.

+

Nous n’avons pas la population dans ces données, mais nous pouvons l’estimer à partir des cas et du taux (cas / 1000) comme suit:

+
+
rls_covid$pop <- rls_covid$cas / rls_covid$taux_1k * 1000
+
+

Pour définir un modèle CAR dans spaMM, nous avons besoin d’une matrice de poids plutôt que d’une liste de poids comme dans le package spatialreg. Heureusement, le package spdep comprend également une fonction nb2mat pour convertir la liste des voisins en une matrice de poids, là encore en utilisant des poids binaires. Pour éviter un avertissement dans R, nous spécifions que les noms des lignes et des colonnes de cette matrice doivent être égaux aux identifiants associés à chaque unité (RLS_code). Ensuite, nous ajoutons un terme adjacency(1 | RLS_code) au modèle pour spécifier que la variation résiduelle entre les différents groupes définis par RLS_code est spatialement corrélée avec une structure CAR (ici, chaque groupe n’a qu’une observation puisque nous avons un point de données par unité RLS).

+
+
library(spaMM)
+
+rls_mat <- nb2mat(rls_nb, style = "B")
+rownames(rls_mat) <- rls_covid$RLS_code
+colnames(rls_mat) <- rls_covid$RLS_code
+
+rls_spamm <- fitme(cas ~ log(dens_pop) + offset(log(pop)) + adjacency(1 | RLS_code),
+                   data = rls_covid, adjMatrix = rls_mat, family = poisson)
+summary(rls_spamm)
+
+
formula: cas ~ log(dens_pop) + offset(log(pop)) + adjacency(1 | RLS_code)
+Estimation of corrPars and lambda by ML (p_v approximation of logL).
+Estimation of fixed effects by ML (p_v approximation of logL).
+Estimation of lambda by 'outer' ML, maximizing logL.
+family: poisson( link = log ) 
+ ------------ Fixed effects (beta) ------------
+              Estimate Cond. SE t-value
+(Intercept)    -5.1618  0.16855 -30.625
+log(dens_pop)   0.1999  0.03267   6.119
+ --------------- Random effects ---------------
+Family: gaussian( link = identity ) 
+                   --- Correlation parameters:
+    1.rho 
+0.1576605 
+           --- Variance parameters ('lambda'):
+lambda = var(u) for u ~ Gaussian; 
+   RLS_code  :  0.266  
+# of obs: 95; # of groups: RLS_code, 95 
+ ------------- Likelihood values  -------------
+                        logLik
+logL       (p_v(h)): -709.3234
+
+
+

Notez que le coefficient de corrélation spatiale rho (0.158) est similaire à la quantité équivalente dans le modèle spautolm ci-dessus, où il était appelé Lambda. L’effet de log(dens_pop) est également d’environ 0.2 dans les deux modèles.

+
+

Référence

+

Moraga, Paula (2019) Geospatial Health Data: Modeling and Visualization with R-INLA and Shiny. Chapman & Hall/CRC Biostatistics Series. Disponible en ligne: https://www.paulamoraga.com/book-geospatial/.

+ + +
+
+ +
+ +
+ + + + \ No newline at end of file diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-10-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-10-1.png new file mode 100644 index 0000000..e827710 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-10-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-100-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-100-1.png new file mode 100644 index 0000000..847c620 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-100-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-102-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-102-1.png new file mode 100644 index 0000000..1579e74 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-102-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-103-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-103-1.png new file mode 100644 index 0000000..62429cd Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-103-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-104-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-104-1.png new file mode 100644 index 0000000..678ea3c Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-104-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-105-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-105-1.png new file mode 100644 index 0000000..e40ccbd Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-105-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-106-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-106-1.png new file mode 100644 index 0000000..0bc1352 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-106-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-107-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-107-1.png new file mode 100644 index 0000000..8c30a64 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-107-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-108-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-108-1.png new file mode 100644 index 0000000..c897569 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-108-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-109-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-109-1.png new file mode 100644 index 0000000..6512cb3 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-109-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-11-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-11-1.png new file mode 100644 index 0000000..847c620 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-11-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-111-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-111-1.png new file mode 100644 index 0000000..3d21a0f Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-111-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-112-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-112-1.png new file mode 100644 index 0000000..f80ce79 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-112-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-113-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-113-1.png new file mode 100644 index 0000000..f04fb55 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-113-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-114-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-114-1.png new file mode 100644 index 0000000..c6d591f Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-114-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-115-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-115-1.png new file mode 100644 index 0000000..3462250 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-115-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-116-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-116-1.png new file mode 100644 index 0000000..18b37bb Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-116-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-116-2.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-116-2.png new file mode 100644 index 0000000..d46c839 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-116-2.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-117-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-117-1.png new file mode 100644 index 0000000..c256353 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-117-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-118-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-118-1.png new file mode 100644 index 0000000..da04932 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-118-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-119-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-119-1.png new file mode 100644 index 0000000..27d6996 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-119-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-121-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-121-1.png new file mode 100644 index 0000000..5ec164e Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-121-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-122-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-122-1.png new file mode 100644 index 0000000..eaa9c35 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-122-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-124-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-124-1.png new file mode 100644 index 0000000..b3e984a Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-124-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-125-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-125-1.png new file mode 100644 index 0000000..a9a8154 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-125-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-128-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-128-1.png new file mode 100644 index 0000000..1c86bb1 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-128-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-13-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-13-1.png new file mode 100644 index 0000000..1579e74 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-13-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-130-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-130-1.png new file mode 100644 index 0000000..4d9a258 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-130-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-133-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-133-1.png new file mode 100644 index 0000000..1112bc2 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-133-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-135-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-135-1.png new file mode 100644 index 0000000..a150946 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-135-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-137-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-137-1.png new file mode 100644 index 0000000..6403054 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-137-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-14-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-14-1.png new file mode 100644 index 0000000..62429cd Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-14-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-143-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-143-1.png new file mode 100644 index 0000000..cfeb3c9 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-143-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-146-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-146-1.png new file mode 100644 index 0000000..6845184 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-146-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-147-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-147-1.png new file mode 100644 index 0000000..87c7739 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-147-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-15-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-15-1.png new file mode 100644 index 0000000..678ea3c Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-15-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-155-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-155-1.png new file mode 100644 index 0000000..291b9ff Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-155-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-16-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-16-1.png new file mode 100644 index 0000000..e40ccbd Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-16-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-160-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-160-1.png new file mode 100644 index 0000000..029b711 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-160-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-161-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-161-1.png new file mode 100644 index 0000000..896bd8e Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-161-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-166-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-166-1.png new file mode 100644 index 0000000..cecdab5 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-166-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-166-2.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-166-2.png new file mode 100644 index 0000000..8da716d Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-166-2.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-167-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-167-1.png new file mode 100644 index 0000000..3018796 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-167-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-169-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-169-1.png new file mode 100644 index 0000000..052f19c Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-169-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-17-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-17-1.png new file mode 100644 index 0000000..0bc1352 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-17-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-170-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-170-1.png new file mode 100644 index 0000000..b4040f8 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-170-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-174-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-174-1.png new file mode 100644 index 0000000..fa24509 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-174-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-175-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-175-1.png new file mode 100644 index 0000000..2cc612d Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-175-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-18-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-18-1.png new file mode 100644 index 0000000..1e0adb8 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-18-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-19-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-19-1.png new file mode 100644 index 0000000..c897569 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-19-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-2-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-2-1.png new file mode 100644 index 0000000..be5f7aa Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-2-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-20-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-20-1.png new file mode 100644 index 0000000..6512cb3 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-20-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-22-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-22-1.png new file mode 100644 index 0000000..3d21a0f Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-22-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-23-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-23-1.png new file mode 100644 index 0000000..f80ce79 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-23-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-24-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-24-1.png new file mode 100644 index 0000000..f04fb55 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-24-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-25-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-25-1.png new file mode 100644 index 0000000..c6d591f Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-25-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-26-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-26-1.png new file mode 100644 index 0000000..3462250 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-26-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-27-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-27-1.png new file mode 100644 index 0000000..18b37bb Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-27-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-27-2.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-27-2.png new file mode 100644 index 0000000..d46c839 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-27-2.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-28-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-28-1.png new file mode 100644 index 0000000..115f34f Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-28-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-29-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-29-1.png new file mode 100644 index 0000000..a0d2cc1 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-29-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-30-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-30-1.png new file mode 100644 index 0000000..91357a9 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-30-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-32-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-32-1.png new file mode 100644 index 0000000..1cb19de Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-32-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-33-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-33-1.png new file mode 100644 index 0000000..ccfb6d4 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-33-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-35-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-35-1.png new file mode 100644 index 0000000..b3e984a Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-35-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-36-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-36-1.png new file mode 100644 index 0000000..a9a8154 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-36-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-39-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-39-1.png new file mode 100644 index 0000000..1c86bb1 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-39-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-4-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-4-1.png new file mode 100644 index 0000000..2af9406 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-4-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-41-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-41-1.png new file mode 100644 index 0000000..4d9a258 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-41-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-44-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-44-1.png new file mode 100644 index 0000000..e0251f1 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-44-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-46-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-46-1.png new file mode 100644 index 0000000..c4e88bd Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-46-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-48-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-48-1.png new file mode 100644 index 0000000..6403054 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-48-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-54-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-54-1.png new file mode 100644 index 0000000..cfeb3c9 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-54-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-57-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-57-1.png new file mode 100644 index 0000000..6845184 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-57-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-58-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-58-1.png new file mode 100644 index 0000000..87c7739 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-58-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-66-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-66-1.png new file mode 100644 index 0000000..291b9ff Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-66-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-7-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-7-1.png new file mode 100644 index 0000000..af4ee7e Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-7-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-71-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-71-1.png new file mode 100644 index 0000000..029b711 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-71-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-72-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-72-1.png new file mode 100644 index 0000000..896bd8e Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-72-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-77-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-77-1.png new file mode 100644 index 0000000..cecdab5 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-77-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-77-2.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-77-2.png new file mode 100644 index 0000000..8da716d Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-77-2.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-78-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-78-1.png new file mode 100644 index 0000000..3018796 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-78-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-80-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-80-1.png new file mode 100644 index 0000000..a61302d Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-80-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-81-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-81-1.png new file mode 100644 index 0000000..b4040f8 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-81-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-85-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-85-1.png new file mode 100644 index 0000000..fa24509 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-85-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-86-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-86-1.png new file mode 100644 index 0000000..2cc612d Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-86-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-9-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-9-1.png new file mode 100644 index 0000000..1a45f62 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-9-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-91-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-91-1.png new file mode 100644 index 0000000..134fc0b Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-91-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-93-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-93-1.png new file mode 100644 index 0000000..7e46c5c Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-93-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-96-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-96-1.png new file mode 100644 index 0000000..af4ee7e Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-96-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-98-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-98-1.png new file mode 100644 index 0000000..1a45f62 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-98-1.png differ diff --git a/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-99-1.png b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-99-1.png new file mode 100644 index 0000000..e827710 Binary files /dev/null and b/docs/posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index_files/figure-html/unnamed-chunk-99-1.png differ diff --git a/docs/posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/L'equite la Diversite et l'Inclusion_Sciences (BIOS2+_2e cycle - 1h30)_English.pdf b/docs/posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/L'equite la Diversite et l'Inclusion_Sciences (BIOS2+_2e cycle - 1h30)_English.pdf new file mode 100644 index 0000000..cc09a98 Binary files /dev/null and b/docs/posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/L'equite la Diversite et l'Inclusion_Sciences (BIOS2+_2e cycle - 1h30)_English.pdf differ diff --git a/docs/posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/L'equite la Diversite et l'Inclusion_Sciences (BIOS2+_2e cycle - 1h30)_Francais.pdf b/docs/posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/L'equite la Diversite et l'Inclusion_Sciences (BIOS2+_2e cycle - 1h30)_Francais.pdf new file mode 100644 index 0000000..24a4adc Binary files /dev/null and b/docs/posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/L'equite la Diversite et l'Inclusion_Sciences (BIOS2+_2e cycle - 1h30)_Francais.pdf differ diff --git a/docs/posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/image.jpg b/docs/posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/image.jpg new file mode 100644 index 0000000..4def10c Binary files /dev/null and b/docs/posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/image.jpg differ diff --git a/docs/posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/index.html b/docs/posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/index.html new file mode 100644 index 0000000..d09562c --- /dev/null +++ b/docs/posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/index.html @@ -0,0 +1,374 @@ + + + + + + + + + + + + + +BIOS2 Education resources - Introduction to EDI concepts in a scientific context + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

Introduction to EDI concepts in a scientific context

+
+
+

A short introduction to EDI concepts in a scientific context.

+
+
+
+
Transversal competencies
+
FR
+
EN
+
+
+
+ +
+
Authors
+
+ +
+ Agathe Riallan +
+
+

+ Faculté des Sciences à Université de Sherbrooke +

+
+
+ Marie-José Naud +
+
+

+ Centre d’études nordiques (CEN) +

+
+
+ +
+ + +
+
Published
+
+

January 22, 2021

+
+
+ + +
+ + +
+ + + + +
+ + + + +

Texte en français à la suite.

+
+

1 Introduction to EDI concepts in a scientific context

+

In 2021, the BIOS2 training program will be holding a series of training and reflection activities on equity, diversity and inclusion issues. The goal is to develop an EDI action plan for the program in order to consolidate a more inclusive, respectful and open environment.

+

The objectives of this workshop are:

+
    +
  • Define the concepts of equity, diversity and inclusion
  • +
  • Identify the benefits and challenges of EDI in the university context
  • +
  • Recongnize how to become an EDI bearer during one’s university career
  • +
  • Raise awareness of intercultural communication (professional competence of tomorrow)
  • +
+

The workshop is developed by Agathe Riallan, Faculty Coordinator for Equity, Diversity and Inclusion (EDI) at the Faculty of Science, Université de Sherbrooke, in collaboration with Marie-José Naud, Equity, Diversity and Inclusion Advisor and Coordinator at the Centre d’études nordiques (CEN).

+ +






+
+
+
+

2 Introduction aux concepts EDI en contexte scientifique

+

En 2021, nous aurons une série de formations et d’activités de réflexion sur les questions d’équité, diversité et d’inclusion. Notre objectif est de mettre en place un plan d’action EDI pour le programme afin de consolider un environnement plus inclusif, respectueux et ouvert.

+

Les objectifs de cet ateliers sont:

+
    +
  • Définir les concepts d’équité, de diversité et d’inclusion
  • +
  • Identifier les avantages et les défis de l’ÉDI en contexte universitaire
  • +
  • Identifier comment être porteuse ou porteur de l’ÉDI lors de son parcours universitaire
  • +
  • Se sensibiliser à la communication interculturelle (compétence professionnelle de demain)
  • +
+

L’atelier est développé par Agathe Riallan, Coordinatrice facultaire de l’Équité, de la Diversité et de l’Inclusion (ÉDI) de la Faculté des Sciences à Université de Sherbrooke, en collaboration avec Marie-José Naud, Conseillère en équité, diversité et inclusion et coordonnatrice au Centre d’études nordiques (CEN).

+ +





+ + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/docs/posts/2021-03-25-point-count-data-analysis/index.html b/docs/posts/2021-03-25-point-count-data-analysis/index.html new file mode 100644 index 0000000..f59de96 --- /dev/null +++ b/docs/posts/2021-03-25-point-count-data-analysis/index.html @@ -0,0 +1,587 @@ + + + + + + + + + + + + +BIOS2 Education resources - Point-count Data Analysis + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

Point-count Data Analysis

+
+
+

Analysis of point-count data in the presence of variable survey methodologies and detection error offered by Peter Solymos to BIOS2 Fellows in March 2021.

+
+
+
+
Technical
+
EN
+
+
+
+ + +
+ +
+
Author
+
+

Peter Solymos

+
+
+ +
+
Published
+
+

March 25, 2021

+
+
+ + +
+ + +
+ + + + +
+ + + + +

This course is aimed towards researchers analyzing field observations, who are often faced by data heterogeneities due to field sampling protocols changing from one project to another, or through time over the lifespan of projects, or trying to combine ‘legacy’ data sets with new data collected by recording units.

+

Such heterogeneities can bias analyses when data sets are integrated inadequately, or can lead to information loss when filtered and standardized to common standards. Accounting for these issues is important for better inference regarding status and trend of species and communities.

+

Analysts of such ‘messy’ data sets need to feel comfortable with manipulating the data, need a full understanding the mechanics of the models being used (i.e. critically interpreting the results and acknowledging assumptions and limitations), and should be able to make informed choices when faced with methodological challenges.

+

The course emphasizes critical thinking and active learning through hands on programming exercises. We will use publicly available data sets to demonstrate the data manipulation and analysis. We will use freely available and open-source R packages.

+

The expected outcome of the course is a solid foundation for further professional development via increased confidence in applying these methods for field observations.

+
+

Instructor

+

Dr. Peter Solymos
+Boreal Avian Modelling Project and the Alberta Biodiversity Monitoring Institute
+Department of Biological Sciences, University of Alberta

+
+
+

Outline

+

Each day will consist of 3 sessions, roughly one hour each, with short breaks in between.

+
+

The video recordings from the workshop can be found on YouTube.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SessionTopicFilesVideos
Day 1Naive techniques
1. IntroductionsSlidesVideo
2. Organizing point count dataNotesPart 1, Part 2
3. Regression techniquesNotesPart 1, Part 2
Day 2Behavioral complexities
1. Statistical assumptions and nuisance variablesSlidesVideo
2. Behavioral complexitiesNotesbSims, Video
3. Removal modeling techniquesNotesVideo
4. Finite mixture models and testing assumptionsNotesMixtures, Testing
Day 3The detection process
1. The detection processSlidesVideo
2. Distance sampling and densityNotesVideo
3. Estimating population densityNotesVideo
4. AssumptionsNotesVideo
Day 4Coming full circle
1. QPAD overviewSlidesVideo
2. Models with detectability offsetsNotesOffsets, Models
3. Model validation and error propagationNotesValidation, Error
4. Recordings, roadsides, closing remarksNotesVideo
+
+
+

Get course materials

+
+

Install required software

+

Follow the instructions at the R website to download and install the most up-to-date base R version suitable for your operating system (the latest R version at the time of writing these instructions is 4.0.4).

+

Then run the following script in R:

+
source("https://raw.githubusercontent.com/psolymos/qpad-workshop/main/src/install.R")
+

Having RStudio is not absolutely necessary, but it will make life easier. RStudio is also available for different operating systems. Pick the open source desktop edition from here (the latest RStudio Desktop version at the time of writing these instructions is 1.4.1106).

+

Prior exposure to R programming is not necessary, but knowledge of basic R object types and their manipulation (arrays, data frames, indexing) is useful for following hands-on exercises. Software Carpentry’s Data types and structures in R is a good resource to brush up your R skills.

+
+
+

Get the notes

+

If you don’t want to use git:

+
    +
  1. Download the workshop archive release into a folder
  2. +
  3. Extract the zip archive
  4. +
  5. Open the workshop.Rproj file in RStudio (or open any other R GUI/console and setwd() to the directory where you downloaded the file)
  6. +
  7. (You can delete the archive)
  8. +
+

If you want to use git: fork or clone the repository

+
cd into/your/dir
+git clone https://github.com/psolymos/qpad-workshop.git
+
+
+
+

Useful resources

+ +
+
+

References

+

Sólymos, P., Toms, J. D., Matsuoka, S. M., Cumming, S. G., Barker, N. K. S., Thogmartin, W. E., Stralberg, D., Crosby, A. D., Dénes, F. V., Haché, S., Mahon, C. L., Schmiegelow, F. K. A., and Bayne, E. M., 2020. Lessons learned from comparing spatially explicit models and the Partners in Flight approach to estimate population sizes of boreal birds in Alberta, Canada. Condor, 122: 1-22. PDF

+

Sólymos, P., Matsuoka, S. M., Cumming, S. G., Stralberg, D., Fontaine, P., Schmiegelow, F. K. A., Song, S. J., and Bayne, E. M., 2018. Evaluating time-removal models for estimating availability of boreal birds during point-count surveys: sample size requirements and model complexity. Condor, 120: 765-786. PDF

+

Sólymos, P., Matsuoka, S. M., Stralberg, D., Barker, N. K. S., and Bayne, E. M., 2018. Phylogeny and species traits predict bird detectability. Ecography, 41: 1595-1603. PDF

+

Van Wilgenburg, S. L., Sólymos, P., Kardynal, K. J. and Frey, M. D., 2017. Paired sampling standardizes point count data from humans and acoustic recorders. Avian Conservation and Ecology, 12(1):13. PDF

+

Yip, D. A., Leston, L., Bayne, E. M., Sólymos, P. and Grover, A., 2017. Experimentally derived detection distances from audio recordings and human observers enable integrated analysis of point count data. Avian Conservation and Ecology, 12(1):11. PDF

+

Sólymos, P., and Lele, S. R., 2016. Revisiting resource selection probability functions and single-visit methods: clarification and extensions. Methods in Ecology and Evolution, 7:196-205. PDF

+

Matsuoka, S. M., Mahon, C. L., Handel, C. M., Sólymos, P., Bayne, E. M., Fontaine, P. C., and Ralph, C. J., 2014. Reviving common standards in point-count surveys for broad inference across studies. Condor 116:599-608. PDF

+

Sólymos, P., Matsuoka, S. M., Bayne, E. M., Lele, S. R., Fontaine, P., Cumming, S. G., Stralberg, D., Schmiegelow, F. K. A. & Song, S. J., 2013. Calibrating indices of avian density from non-standardized survey data: making the most of a messy situation. Methods in Ecology and Evolution 4:1047-1058. PDF

+

Matsuoka, S. M., Bayne, E. M., Sólymos, P., Fontaine, P., Cumming, S. G., Schmiegelow, F. K. A., & Song, S. A., 2012. Using binomial distance-sampling models to estimate the effective detection radius of point-counts surveys across boreal Canada. Auk 129:268-282. PDF

+
+
+

License

+

The course material is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) license. Source code is under MIT license.

+ + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/docs/posts/2021-03-25-point-count-data-analysis/qpad-workshop-Final.zip b/docs/posts/2021-03-25-point-count-data-analysis/qpad-workshop-Final.zip new file mode 100644 index 0000000..1ef8245 Binary files /dev/null and b/docs/posts/2021-03-25-point-count-data-analysis/qpad-workshop-Final.zip differ diff --git a/docs/posts/2021-03-25-point-count-data-analysis/thumb.jpeg b/docs/posts/2021-03-25-point-count-data-analysis/thumb.jpeg new file mode 100644 index 0000000..ad324fe Binary files /dev/null and b/docs/posts/2021-03-25-point-count-data-analysis/thumb.jpeg differ diff --git a/docs/posts/2021-05-04-building-r-packages/altumcode-PNbDkQ2DDgM-unsplash.jpeg b/docs/posts/2021-05-04-building-r-packages/altumcode-PNbDkQ2DDgM-unsplash.jpeg new file mode 100644 index 0000000..d118b68 Binary files /dev/null and b/docs/posts/2021-05-04-building-r-packages/altumcode-PNbDkQ2DDgM-unsplash.jpeg differ diff --git a/docs/posts/2021-05-04-building-r-packages/index.html b/docs/posts/2021-05-04-building-r-packages/index.html new file mode 100644 index 0000000..2fdb10d --- /dev/null +++ b/docs/posts/2021-05-04-building-r-packages/index.html @@ -0,0 +1,521 @@ + + + + + + + + + + + + +BIOS2 Education resources - Building R packages + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

Building R packages

+
+
+

This practical training will cover the basics of modern package development in R with a focus on the following three aspects: (1) how to turn your code into functions, (2) how to write tests and documentation, and (3) how to share your R package on GitHub..

+
+
+
+
Technical
+
EN
+
+
+
+ + +
+ +
+
Author
+
+

Andrew MacDonald

+
+
+ +
+
Published
+
+

May 4, 2021

+
+
+ + +
+ + +
+ + + + +
+ + + + + +

+via GIPHY +

+

R packages! they are kind of like cookies:

+
    +
  • Almost everyone enjoys them

  • +
  • delicious when homemade

  • +
  • Lots of storebought options available

  • +
  • Great skill to have

  • +
  • not necessary to sell them!

    +
  • +
+

But most of all: cookies are delicious for what they contain: chocolate chunks, candy, oats, cocoa. However, all cookies share some fundamental ingredients and nearly identical structure. Flour, saturated with fat and sugar hydrated only with an egg, flavoured with vanilla and salt. The basic formula is invariant and admits only slight deviation – otherwise, it becomes something other than a cookie.

+

This workshop is devoted to the study of cookie dough.

+
+

Mise en place : development environment

+

We’ll explore a few useful packages in this workshop. The first two in particular are very popular tools for modern-day R package development:

+
install.packages("devtools")
+install.packages("usethis")
+install.packages("testthat")
+install.packages("assertthat")
+

Building an R package also requires specific tools for compiling the finished package. Run the following line to make sure you have the development environment:

+
devtools::has_devel()
+

If you do not have the software to build R packages, you should see a message which will help you find the correct links to download what you need!

+

Windows will need RTools. First do the check above to see if you are already set up. If not then download the software here.

+

and Install. After that, open R and run the following:

+
writeLines('PATH="${RTOOLS40_HOME}\\usr\\bin;${PATH}"', con = "~/.Renviron")
+

and restart R. Then run the check above once more to confirm

+ +
+
+

The structure: flour and sugar

+
+

No cookies without carbs

+
+

An R package is essentially a folder on your computer with specific structure. We will begin by creating an empty R package and taking a tour!

+

Open your R code editor, and find out where you are:

+
getwd()
+

This is to prepare for the next step, where we will choose a location for our R package folder. Please be intentional about where you place your R package! Do not place it in the same space as another package, Rstudio project or other project. Create a new and isolated location for it.

+

I am working from an existing R project in my typical R Projects folder, so I go up one level:

+
usethis::create_package("../netwerk")
+ +

+

Let’s run R CMD CHECK right away. We will do this MANY TIMES.

+
devtools::check()
+

We should see some warnings! let’s keep these in mind as we continue our tour.

+
+

The DESCRIPTION file

+

The most important file to notice is the DESCRIPTION. This gives general information about the entire package. It is written in a specific file format

+
Package: netwerk
+Title: Werks with Networks
+Version: 0.0.0.9000
+Authors@R: 
+    person(given = "Andrew",
+           family = "MacDonald",
+           role = c("aut", "cre"),
+           email = "<you@email.com>")
+Description: it does networks.
+License: MIT + file LICENSE
+Encoding: UTF-8
+LazyData: true
+Roxygen: list(markdown = TRUE)
+RoxygenNote: 7.1.1
+Suggests: 
+    testthat (>= 3.0.0)
+Config/testthat/edition: 3
+

Here are some things to edit manually in DESCRIPTION:

+
    +
  • package name [tk naming of R packages] – make it short and convenient if you can!
  • +
  • Title: write this part In Title Case. Don’t end the title with a period.
  • +
  • Description: Describe the package in a short block of text. This should end with a period.
  • +
  • Authors: Add your name here and the name of anyone building the package with you. usethis will have done the first step for you, and filled in the structure. Only “aut” (author) and “cre” (creator) are essential. but many others are possible
  • +
+

Add your name here.

+

Add a license

+
usethis::use_mit_license(copyright_holder = "")
+

note about the different roles taht R package authors can have. Funny ones. but creator and maintainer are the key ones.

+

Note the R folder. We’ll get much more into that later

+
    +
  • Rbuildignore
  • +
+
+
+
+

Keeping notes

+

create an R file

+
usethis::use_build_ignore("dev.R")
+

the docs folder

+

here we have a very minimal version of an R packages we’re going to be adding to it as the course progresses.

+

One thing we can do right away is build and check the R package

+

What exactly is happining here? slide from R package tutorial.

+

Lots of checkpoints and progress confrimations along the way.

+

OK so what is that all about? we have compiled the R package and it has gone to where the R packages on our computer go.

+

There is a natural cycle to how the different steps in an R package workflow proceed – see the documentation for this lesson – we will be following this process (TK another pictures?

+

Ok so now that we ahve the basic structure, let’s talk about some content for the R package. I received the donation of a little R function already that we can use to create this workflow in a nice way

+

This R function (explain what the function does)

+

OK so let’s focus on just one part of this function.

+

load all – shortcut

+
+

how do we do this in VScode?

+
+
+

how to add something to the .Rbuildignore? it would be nice to have a little .dev script as a space to create all the ohter dependencies that are involved in making an R package.

+
+
+
+
✔ Setting active project to '/Users/katherine/Documents/GitHub/bios2.github.io-quarto'
+✔ Adding '^development\\.R$' to 'posts/2021-05-04-building-r-packages/.Rbuildignore'
+
+
+
+ + +
+ +
+ + + + \ No newline at end of file diff --git a/docs/posts/2021-05-04-building-r-packages/start_pkg.png b/docs/posts/2021-05-04-building-r-packages/start_pkg.png new file mode 100644 index 0000000..40072d2 Binary files /dev/null and b/docs/posts/2021-05-04-building-r-packages/start_pkg.png differ diff --git "a/docs/posts/2021-06-22-introduction-to-shiny-apps/Capture d\342\200\231\303\251cran, le 2021-06-23 \303\240 05.25.32.png" "b/docs/posts/2021-06-22-introduction-to-shiny-apps/Capture d\342\200\231\303\251cran, le 2021-06-23 \303\240 05.25.32.png" new file mode 100644 index 0000000..742209e Binary files /dev/null and "b/docs/posts/2021-06-22-introduction-to-shiny-apps/Capture d\342\200\231\303\251cran, le 2021-06-23 \303\240 05.25.32.png" differ diff --git "a/docs/posts/2021-06-22-introduction-to-shiny-apps/Capture d\342\200\231\303\251cran, le 2021-06-23 \303\240 05.58.08.png" "b/docs/posts/2021-06-22-introduction-to-shiny-apps/Capture d\342\200\231\303\251cran, le 2021-06-23 \303\240 05.58.08.png" new file mode 100644 index 0000000..b02a6aa Binary files /dev/null and "b/docs/posts/2021-06-22-introduction-to-shiny-apps/Capture d\342\200\231\303\251cran, le 2021-06-23 \303\240 05.58.08.png" differ diff --git "a/docs/posts/2021-06-22-introduction-to-shiny-apps/Capture d\342\200\231\303\251cran, le 2021-06-23 \303\240 06.25.38.png" "b/docs/posts/2021-06-22-introduction-to-shiny-apps/Capture d\342\200\231\303\251cran, le 2021-06-23 \303\240 06.25.38.png" new file mode 100644 index 0000000..1d35049 Binary files /dev/null and "b/docs/posts/2021-06-22-introduction-to-shiny-apps/Capture d\342\200\231\303\251cran, le 2021-06-23 \303\240 06.25.38.png" differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/image.jpg b/docs/posts/2021-06-22-introduction-to-shiny-apps/image.jpg new file mode 100644 index 0000000..325cf34 Binary files /dev/null and b/docs/posts/2021-06-22-introduction-to-shiny-apps/image.jpg differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/images/add_elements_diagram.png b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/add_elements_diagram.png new file mode 100644 index 0000000..935a311 Binary files /dev/null and b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/add_elements_diagram.png differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-ids.png b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-ids.png new file mode 100644 index 0000000..b1540a1 Binary files /dev/null and b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-ids.png differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-in1.png b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-in1.png new file mode 100644 index 0000000..dd93dcb Binary files /dev/null and b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-in1.png differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-in2.png b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-in2.png new file mode 100644 index 0000000..2612ed2 Binary files /dev/null and b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-in2.png differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-output.png b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-output.png new file mode 100644 index 0000000..5cbb723 Binary files /dev/null and b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-output.png differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-reactiveid.png b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-reactiveid.png new file mode 100644 index 0000000..944e581 Binary files /dev/null and b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/app-reactiveid.png differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/images/darklytheme.png b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/darklytheme.png new file mode 100644 index 0000000..4090cc6 Binary files /dev/null and b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/darklytheme.png differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/images/plotOutput.png b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/plotOutput.png new file mode 100644 index 0000000..bcba3ab Binary files /dev/null and b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/plotOutput.png differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/images/populated_shiny.png b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/populated_shiny.png new file mode 100644 index 0000000..325cf34 Binary files /dev/null and b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/populated_shiny.png differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/images/shiny_dashboard_layout.png b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/shiny_dashboard_layout.png new file mode 100644 index 0000000..53e9894 Binary files /dev/null and b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/shiny_dashboard_layout.png differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/images/thematic.png b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/thematic.png new file mode 100644 index 0000000..915f958 Binary files /dev/null and b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/thematic.png differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/images/thematic_plot.png b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/thematic_plot.png new file mode 100644 index 0000000..40e2d22 Binary files /dev/null and b/docs/posts/2021-06-22-introduction-to-shiny-apps/images/thematic_plot.png differ diff --git a/docs/posts/2021-06-22-introduction-to-shiny-apps/index.html b/docs/posts/2021-06-22-introduction-to-shiny-apps/index.html new file mode 100644 index 0000000..ec8ae2d --- /dev/null +++ b/docs/posts/2021-06-22-introduction-to-shiny-apps/index.html @@ -0,0 +1,1216 @@ + + + + + + + + + + + + + + + +BIOS2 Education resources - Introduction to Shiny Apps + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

Introduction to Shiny Apps

+
+
+

Introduction to interactive app development with R Shiny.

+
+
+
+
Technical
+
Fellow contributed
+
EN
+
+
+
+ + +
+ +
+
Authors
+
+

Katherine Hébert

+

Andrew MacDonald

+

Jake Lawlor

+

Vincent Bellevance

+
+
+ +
+
Published
+
+

June 22, 2021

+
+
+ + +
+ + +
+ + + + +
+ + + + +
+

Why do you want to use Shiny?

+

There are many reasons to consider using Shiny for a project:

+
    +
  • Sharing results from a paper with your readers;
  • +
  • Helping you explore a model, mathematics, simulations;
  • +
  • Letting non R users use R.
  • +
+
+
+

Hello Shiny!

+

Here is an example of a Shiny app that RStudio generates when you open a new Shiny Web App file:

+
+
# Define UI for app that draws a histogram ----
+ui <- fluidPage(
+
+  # App title ----
+  titlePanel("Hello Shiny!"),
+
+  # Sidebar layout with input and output definitions ----
+  sidebarLayout(
+
+    # Sidebar panel for inputs ----
+    sidebarPanel(
+
+      # Input: Slider for the number of bins ----
+      sliderInput(inputId = "bins",
+                  label = "Number of bins:",
+                  min = 1,
+                  max = 50,
+                  value = 30)
+
+    ),
+
+    # Main panel for displaying outputs ----
+    mainPanel(
+
+      # Output: Histogram ----
+      plotOutput(outputId = "distPlot")
+
+    )
+  )
+)
+
+
+
+

1 How a Shiny app works

+
+

Building blocks

+

We’ve now seen the basic building blocks of a Shiny app:

+
    +
  • The user interface, which determines how the app “looks”. This is how we tell Shiny where to ask for user inputs, and where to put any outputs we create.
  • +
  • Reactive values, which are values that change according to user inputs. These are values that affect the outputs we create in the Shiny app, such as tables or plots.
  • +
  • The server, where we use reactive values to generate some outputs.
  • +
+
+

IDs

+

The user interface and server communicate through IDs that we assign to inputs from the user and outputs from the server.

+

+

We use an ID (in orange) to link the user input in the UI to the reactive values used in the server:

+

+

We use another ID (in blue) to link the output created in the server to the output shown in the user interface:

+

+
+
+

Organisation

+

These elements can all be placed in one script named app.R or separately in scripts named ui.R and server.R. The choice is up to you, although it becomes easier to work in separate ui.R and server.R scripts when the Shiny app becomes more complex.

+

Example 1: Everything in app.R

+

Example 2: Split things into ui.R and server.R

+

+
+
+
+

Plots

+

Shiny is an excellent tool for visual exploration - it is at its most useful when a user can see something change before their eyes according to some selections. This is a great way to allow users to explore a dataset, explore the results of some analyses according to different parameters, and so on!

+

Let’s now add a plot to our Shiny app, to visualize the distribution of a variable depending on user input. We’ll be adding the ggplot2 and ggridges packages in the set-up step at the top of our app.R to allow us to make a plot.

+
+
# load packages
+library(shiny)
+library(ggridges)
+library(ggplot2)
+library(here)
+library(readr)
+
+
+

User interface

+

To add a plot in our Shiny, we need to indicate where the plot should appear in the app. We can do this with plotOutput(), a similar function to tableOutput() in the previous section that is meant for plot outputs, as the name suggests.

+
+
# Define UI for application that makes a table andplots the Volcano Explosivity 
+# Index for the most eruptive volcanoes within a selected range of years
+
+ui <- fluidPage(
+  
+  # Application title ----
+  
+  titlePanel("Exploring volcano explosivity"),
+  
+  # Input interface ----
+  
+  sidebarLayout(
+    sidebarPanel(
+      
+      # Sidebar with a slider range input
+      sliderInput("years", # the id your server needs to use the selected value
+                  label = h3("Years"),
+                  min = 1900, max = 2020, # maximum range that can be selected
+                  value = c(2010, 2020) # this is the default slider position
+      )
+    )
+  ),
+  
+  # Show the outputs from the server ---------------
+  mainPanel(
+    
+    # Show a ridgeplot of explosivity index for selected volcanoes
+    plotOutput("ridgePlot"),
+    
+    # then, show the table we made in the previous step
+    tableOutput("erupt_table")
+    
+  )
+)
+
+

Now our Shiny app knows where we want to place our plot.

+
+
+

Server

+

We now need to create the plot we want to show in our app. This plot will change depending on one or several reactive values that the user can input or select in our UI.

+

We link the UI and server together with IDs that are assigned to each object. Above, we told the UI to expect a plot output with the ID "ridgePlot". In the server, we will create a plot and render it as a plot object using renderPlot(), and we will assign this plot output to the ID we call in the UI (as output$ridgePlot).

+
+
# Define server logic required to make your output(s)
+server <- function(input, output) {
+
+  
+  # prepare the data
+  # ----------------------------------------------------------
+  
+  # read the dataset
+  eruptions <- readr::read_rds(here::here("data", "eruptions.rds"))
+  
+  # filter the dataset to avoid overloading the plot 
+  eruptions <- eruptions[which(eruptions$volcano_name %in% names(which(table(eruptions$volcano_name) > 30))),]
+  # this subsets to volcanoes that have erupted more than 30 times
+  
+  
+  # make reactive dataset
+  # ----------------------------------------------------------
+  
+  # subset volcano data with input year range
+  eruptions_filtered <- reactive({
+    subset(eruptions, start_year >= input$years[1] & end_year <= input$years[2])
+  })
+  
+    
+  # create and render the outputs
+  # ----------------------------------------------------------
+  
+  # create the table of volcanoes
+  output$erupt_table <- renderTable({
+    head(eruptions_filtered())
+  })
+  
+  # render the plot output
+  output$ridgePlot <- renderPlot({
+    
+    # create the plot
+    ggplot(data = eruptions_filtered(),
+           aes(x = vei,
+               y = volcano_name,
+               fill = volcano_name)) +
+      # we are using a ridgeplot geom here, from the ggridges package
+      geom_density_ridges( size = .5) + # line width
+      
+      # label the axes
+      labs(x = "Volcano Explosivity Index", y = "") +
+      
+      # adjust the ggplot theme to make the plot "prettier"
+      theme_classic() + 
+      theme(legend.position = "none",
+            axis.text = element_text(size = 12, face = "bold"),
+            axis.title = element_text(size = 14, face = "bold"))
+  })
+}
+
+
+
+

The Shiny app

+

Now, if we run the Shiny app, we have a plot above the table we made previously. They are positioned in this way because the plotOutput() comes before the tableOutput() in the UI.

+
+
# Run the application
+shinyApp(ui = ui, server = server)
+
+

+
+
+
+

Customising the theme

+

If you’d like to go one step further, you can also customize the appearance of your Shiny app using built-in themes, or creating your own themes.

+
+

Using built-in themes

+

There are several built-in themes in Shiny, which allow you to quickly change the appearance of your app. You can browse a gallery of available themes here here, or test themes out interactively here.

+

Let’s try the darkly theme on our Shiny app. To do this, we will need the shinythemes package.

+
+
library(shinythemes)
+
+

We can change the theme of our previous app with one line of code:

+
+
# Define UI for application that makes a table andplots the Volcano Explosivity 
+# Index for the most eruptive volcanoes within a selected range of years
+
+ui <- fluidPage(
+  
+  # Application title ----
+  
+  titlePanel("Exploring volcano explosivity"),
+  
+  # Input interface ----
+  
+  sidebarLayout(
+    sidebarPanel(
+      
+      # Sidebar with a slider range input
+      sliderInput("years", # the id your server needs to use the selected value
+                  label = h3("Years"),
+                  min = 1900, max = 2020, # maximum range that can be selected
+                  value = c(2010, 2020) # this is the default slider position
+      )
+    )
+  ),
+  
+  # Show the outputs from the server ---------------
+  mainPanel(
+    
+    # Show a ridgeplot of explosivity index for selected volcanoes
+    plotOutput("ridgePlot"),
+    
+    # then, show the table we made in the previous step
+    tableOutput("erupt_table")
+    
+  ),
+  
+  # Customize the theme ----------------------
+  
+  # Use the darkly theme
+  theme = shinythemes::shinytheme("darkly")
+)
+
+

Now, if we run the app, it looks a little different:

+

+
+
+

Using a custom theme

+

You can also go beyond the built-in themes, and create your own custom theme with the fonts and colours of your choice. You can also apply this theme to the outputs rendered in the app, to bring all the visuals together for a more cohesive look.

+
+

Customizing a theme

+

To create a custom theme, we will be using the bs_theme() function from the bslib package.

+
+
library(bslib)
+
+
+
# Create a custom theme 
+cute_theme <- bslib::bs_theme(
+  
+  bg = "#36393B", # background colour
+  fg = "#FFD166", # most of the text on your app
+  primary = "#F26430", # buttons, ...
+  
+  # you can also choose fonts
+  base_font = font_google("Open Sans"),
+  heading_font = font_google("Open Sans")
+)
+
+

To apply this theme to our Shiny app (and the outputs), we will be using the thematic package.

+
+
library(thematic)
+
+

There are two essential steps to apply a custom theme to a Shiny app:

+
    +
  1. Activating thematic.
  2. +
  3. Setting the user interface’s theme to the custom theme (cute_theme).
  4. +
+
+
# Activate thematic
+# so your R outputs will be changed to match up with your chosen styling
+thematic::thematic_shiny()
+
+# Define UI for application that makes a table andplots the Volcano Explosivity 
+# Index for the most eruptive volcanoes within a selected range of years
+
+ui <- fluidPage(
+  
+  # Application title ----
+  
+  titlePanel("Exploring volcano explosivity"),
+  
+  # Input interface ----
+  
+  sidebarLayout(
+    sidebarPanel(
+      
+      # Sidebar with a slider range input
+      sliderInput("years", # the id your server needs to use the selected value
+                  label = h3("Years"),
+                  min = 1900, max = 2020, # maximum range that can be selected
+                  value = c(2010, 2020) # this is the default slider position
+      )
+    )
+  ),
+  
+  # Show the outputs from the server ---------------
+  mainPanel(
+    
+    # Show a ridgeplot of explosivity index for selected volcanoes
+    plotOutput("ridgePlot"),
+    
+    # then, show the table we made in the previous step
+    tableOutput("erupt_table")
+    
+  ),
+  
+  # Customize the theme ----------------------
+  
+  # Use our custom theme
+  theme = cute_theme
+)
+
+

Now, if we run the app, the user interface and plot theme is set to the colours and fonts we set in cute_theme:

+

+

Here, thematic is not changing the colours used to represent a variable in our plot, because this is an informative colour scale (unlike the colour of axis labels, lines, and the plot background). However, if we remove this colour variable in our ridgeplot in the server, thematic will change the plot colours as well. Here is a simplified example of our server to see what these changes would look like:

+
+
# Define server logic required to make your output(s)
+server <- function(input, output) {
+  
+  #... (all the good stuff we wrote above)
+  
+  # render the plot output
+  output$ridgePlot <- renderPlot({
+    
+    # create the plot
+    ggplot(data = eruptions_filtered(),
+           aes(x = vei,
+               y = volcano_name)) + # we are no longer setting 
+             # the fill argument to a variable
+             
+             # we are using a ridgeplot geom here, from the ggridges package
+             geom_density_ridges(size = .5) + 
+             
+             # label the axes
+             labs(x = "Volcano Explosivity Index", y = "") +
+             
+             # remove the "classic" ggplot2 so it doesn't override thematic's changes
+             # theme_classic() + 
+             theme(legend.position = "none",
+                   axis.text = element_text(size = 12, face = "bold"),
+                   axis.title = element_text(size = 14, face = "bold"))
+           })
+    }
+
+

Now, our plot’s theme follows the app’s custom theme as well:

+

+
+
+
+
+
+

2 Constructing a Shiny app using shinyDashboards

+
+

Taking advantage of good defaults

+

Here, we will use shiny extension shinyDashboards and leaflet to construct a custom Shiny App to map volcanoes of the world. First, we need a few additional packages.

+

Note: All Source code for this app can be found here on the BIOS2 Github.

+
+
# load packages
+library(shiny)
+library(shinydashboard)  # dashboard layout package
+library(shinyWidgets)  # fancy widgets package
+library(leaflet)  # interactive maps package
+library(dplyr)
+library(ggplot2)
+
+
+

Using ShinyDashboard

+

We will create our app using defaults from the ShinyDashboard package, which always includes three main components: a header, using dashboardHeader(), a sidebar, using dashboardSidebar(), and a body, using dashboardBody(). These are then added together using the dashboardPage() function.

+

Building these elements is less like usual R coding, and more like web design, since we are, in fact, designing a unser interface for a web app. Here, we’ll make a basic layout before populating it.

+
+
# create the header of our app
+header <- dashboardHeader(
+    title = "Exploring Volcanoes of the World",
+    titleWidth = 350 # since we have a long title, we need to extend width element in pixels
+)
+
+
+# create dashboard body - this is the major UI element
+body <- dashboardBody(
+
+    # make first row of elements (actually, this will be the only row)
+    fluidRow(
+        
+        # make first column, 25% of page - width = 3 of 12 columns
+        column(width = 3,
+               
+               
+               # Box 1: text explaining what this app is
+               #-----------------------------------------------
+               box( width = NULL,
+                    status="primary", # this line can change the automatic color of the box.
+                    title = NULL,
+                    p("here, we'll include some info about this app")
+
+                 
+               ), # end box 1
+               
+               
+               # box 2 : input for selecting volcano type
+               #-----------------------------------------------
+               box(width = NULL, status = "primary",
+                   title  = "Selection Criteria", solidHeader = T, 
+                   
+                   p("here, we'll add a UI element for selecting volcano types"),
+
+               ), # end box 2
+               
+               
+               
+               # box 3: ggplot of selected volcanoes by continent
+               #------------------------------------------------
+               box(width = NULL, status = "primary",
+                   solidHeader = TRUE, collapsible = T,
+                   title = "Volcanoes by Continent",
+                   p("here, we'll add a bar plot of volcanoes in each continent")
+               ) # end box 3
+               
+        ), # end column 1
+         
+        # second column - 75% of page (9 of 12 columns)
+        #--------------------------------------------------
+        column(width = 9,
+               # Box 4: leaflet map
+               box(width = NULL, background = "light-blue", height = 850,
+                   p("here, we'll show volcanoes on a map"),
+               ) # end box with map
+        ) # end second column
+        
+    ) # end fluidrow
+) # end body
+
+
+# add elements together
+dashboardPage(
+    skin = "blue",
+    header = header,
+    sidebar = dashboardSidebar(disable = TRUE), # here, we only have one tab of our app, so we don't need a sidebar
+    body = body
+)
+
+

+
+
+
+

Populating the Layout

+

Now, we are going to fill out app with elements. In this app, we will only have one user input: a selection of the volcano type to show. We will use this input (input$volcano_type), which will be used to filter data in the server (i.e. make a smaller dataset using only volcanoes of the selected types), then use this filtered dataset to create output elements (plots and maps).

+

Below, we show the necessary code to include in both the UI and the Server to create each plot element. Notice that after the reactive value selected_volcanoes is created in the selection box, this is the only object that is used to create the other elements in the app.

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LocationElementUIServer
Box 1Intro TextboxMarkdown/HTML text code
Box 2Selection WigetscheckboxGroupButtons( inputID = "volcano_type")selected_volcanoes <- reactive({ volcano_df %>% filter(type %in% input$volcano_type)}) to create a filtered dataset that will react to user input
Box 3Bar GraphplotOutput("continentplot")output$continentplot <- renderPlot(...)) which will plot from the selectied_volcanoes reactive object
Box 4Leaflet MapleafletOutput("volcanomap")output$volcanomap <- renderLeaflet(...) to map points from the selectied_volcanoes reactive object
+

+
+
+

Challenge!

+

Use the code provided to add your own additional user input to the Shiny App. The code (which you can access here leaves a space for an additional UI input inside box 2). Then, you’ll need to use your new input element to the reactive value in the Server, as noted in the server code.

+

Use the Default Shiny Widgets or shinyWidgets extended package galleries to explore the types of elements you can add.

+

+
+

See the completed app

+

See our completed app HERE

+
+
+
+
+

3 Constructing a Shiny app using Golem

+

First step is creating your own golem project:

+

+

Golem provides you with some very helpful “workflow” scripts:

+

Edit the Description by filling in this function in 01_dev.R

+

Then, add all the dependencies

+

Together, this edits the DESCRIPTION of your R package to look something like this:

+

Now we can start building the app.

+
+
app_ui <- function(request) {
+  tagList(
+    # Leave this function for adding external resources
+    golem_add_external_resources(),
+    # Your application UI logic 
+    shinydashboard::dashboardPage(
+      header = shinydashboard::dashboardHeader(
+        title = "Exploring Volcanoes of the World",
+        titleWidth = 350 # since we have a long title, we need to extend width element in pixels
+      ),
+      sidebar = shinydashboard::dashboardSidebar(disable = TRUE), # here, we only have one tab, so we don't need a sidebar
+      body = shinydashboard::dashboardBody(
+        # make first row of elements (actually, this will be the only row)
+        fluidRow(
+          # make first column, 25% of page - width = 3 of 12 colums
+          column(width = 3,
+                 # box 1 : input for selecting volcano type
+                 #-----------------------------------------------
+                 shinydashboard::box(width = NULL, status = "primary",
+                     title  = "Selection Criteria", solidHeader = T
+                     
+                     ## CHECKBOX HERE
+                     
+                 ), # end box 1
+                 # box 2: ggplot of selected volcanoes by continent
+                 #------------------------------------------------
+                 shinydashboard::box(width = NULL, status = "primary",
+                     solidHeader = TRUE, collapsible = T,
+                     title = "Volcanoes by Continent"
+                     
+                     ## PLOT HERE
+
+                 ) # end box 2
+          ), # end column 1
+          
+          # second column - 75% of page (9 of 12 columns)
+          column(width = 9,
+                 
+                 # Box 3: leaflet map
+                 shinydashboard::box(width = NULL, background = "light-blue"
+                                     
+                                     ## MAP HERE 
+                                     
+                 ) # end box with map
+          ) # end second column
+        ) # end fluidrow
+      ) # end body
+    )
+  )
+}
+
+

This indicates where each of the three components of the app would go.

+

At this point we can run the app to get a very empty-looking UI:

+

+
+

Golem modules

+

We could split this app into three different sections, corresponding to each of the three boxes:

+
    +
  1. Filter the type of volcano we see
  2. +
  3. take the filtered volcanoes and plot a stacked bar chart
  4. +
  5. take the filtered volcanoes and plot a map
  6. +
+
+
+

Selecting the volcanoes

+
+
#' volcano_select UI Function
+#'
+#' @description A shiny Module.
+#'
+#' @param id,input,output,session Internal parameters for {shiny}.
+#'
+#' @noRd 
+#'
+#' @importFrom shiny NS tagList 
+mod_volcano_select_ui <- function(id){
+  ns <- NS(id)
+  tagList(
+    # Widget specifying the species to be included on the plot
+    shinyWidgets::checkboxGroupButtons(
+      inputId = ns("volcano_type"),
+      label = "Volcano Type",
+      choices = c("Stratovolcano" , "Shield" ,"Cone" ,   "Caldera" ,    "Volcanic Field",
+                  "Complex" , "Other",   "Lava Dome"  , "Submarine"    ),
+      checkIcon = list(
+        yes = tags$i(class = "fa fa-check-square", 
+                     style = "color: steelblue"),
+        no = tags$i(class = "fa fa-square-o", 
+                    style = "color: steelblue"))
+    ) # end checkboxGroupButtons
+  )
+}
+    
+#' volcano_select Server Functions
+#'
+#' @noRd 
+mod_volcano_select_server <- function(id, volcano){
+  moduleServer( id, function(input, output, session){
+    ns <- session$ns
+    
+    # make reactive dataset
+    # ------------------------------------------------
+    # Make a subset of the data as a reactive value
+    # this subset pulls volcano rows only in the selected types of volcano
+    selected_volcanoes <- reactive({
+      
+      req(input$volcano_type)
+      
+      volcano %>%
+        
+        # select only volcanoes in the selected volcano type (by checkboxes in the UI)
+        dplyr::filter(volcano_type_consolidated %in% input$volcano_type) %>%
+        # Space to add your suggested filter here!! 
+        # --- --- --- --- --- --- --- --- --- --- --- --- ---
+        # filter() %>%
+        # --- --- --- --- --- --- --- --- --- --- --- --- ---
+        # change volcano type into factor (this makes plotting it more consistent)
+        dplyr::mutate(volcano_type_consolidated = factor(volcano_type_consolidated,
+                                                  levels = c("Stratovolcano" , "Shield",  "Cone",   "Caldera", "Volcanic Field",
+                                                             "Complex" ,  "Other" ,  "Lava Dome" , "Submarine" ) ) )
+    })
+    
+  })
+}
+    
+## To be copied in the UI
+# mod_volcano_select_ui("volcano_select_1")
+    
+## To be copied in the server
+# mod_volcano_select_server("volcano_select_1")
+
+

I also like to test my modules by using them to create a toy Shiny app. The best place to do this is by using a testthat directory. This is another great advantage of using a package workflow. You can set this up easily with usethis::use_test(): just run usethis::use_test from the R console when you have the module open.

+

Then write a simple test like this

+
+
test_that("volcano selection module works", {
+  
+  testthat::skip_if_not(interactive())
+  
+  
+  ui <- fluidPage(
+  ## To be copied in the UI
+  mod_volcano_select_ui("volcano_select_1"),
+  tableOutput("table")
+  )
+  
+  server <- function(input, output) {
+    ## To be copied in the server
+    volcano_data <- readRDS("data/volcanoes.rds")
+    selected_data <- mod_volcano_select_server("volcano_select_1",
+                                               volcano = volcano_data)
+    
+    output$table <- renderTable(selected_data())
+  }
+  
+  shinyApp(ui = ui, server = server)
+  
+})
+
+

Which generates the following simple app:

+

+
+
+

Barplot of continents

+
+
#' continentplot UI Function
+#'
+#' @description A shiny Module.
+#'
+#' @param id,input,output,session Internal parameters for {shiny}.
+#'
+#' @noRd 
+#'
+#' @importFrom shiny NS tagList 
+mod_continentplot_ui <- function(id){
+  ns <- NS(id)
+  tagList(
+    plotOutput(ns("barplot"), # this calls to object continentplot that is made in the server page
+               height = 350)
+  )
+}
+    
+#' continentplot Server Functions
+#'
+#' @noRd 
+mod_continentplot_server <- function(id, volcano, selected_volcanoes){
+  
+  # kind of helpful
+  stopifnot(is.reactive(selected_volcanoes))
+  
+  moduleServer( id, function(input, output, session){
+    ns <- session$ns
+ 
+    output$barplot <- renderPlot({
+      
+      # create basic barplot
+      barplot <- ggplot2::ggplot(data = volcano,
+                                 ggplot2::aes(x=continent,
+                            fill = volcano_type_consolidated))+
+        # update theme and axis labels:
+        ggplot2::theme_bw()+
+        ggplot2::theme(plot.background  = ggplot2::element_rect(color="transparent",fill = "transparent"),
+                       panel.background = ggplot2::element_rect(color="transparent",fill="transparent"),
+                       panel.border     = ggplot2::element_rect(color="transparent",fill="transparent"))+
+        ggplot2::labs(x=NULL, y=NULL, title = NULL) +
+        ggplot2::theme(axis.text.x = ggplot2::element_text(angle=45,hjust=1))
+      
+      
+      # IF a selected_volcanoes() object exists, update the blank ggplot. 
+      # basically this makes it not mess up when nothing is selected
+      
+      barplot <- barplot +
+        ggplot2::geom_bar(data = selected_volcanoes(), show.legend = F) +
+        ggplot2::scale_fill_manual(values = RColorBrewer::brewer.pal(9,"Set1"), drop=F) +
+        ggplot2::scale_x_discrete(drop=F)
+      
+      
+      # print the plot
+      barplot
+      
+    }) # end renderplot command
+    
+    
+  })
+}
+    
+## To be copied in the UI
+# mod_continentplot_ui("continentplot_1")
+    
+## To be copied in the server
+# mod_continentplot_server("continentplot_1")
+
+

the test

+
+
test_that("volano barplot works", {
+  
+  testthat::skip_if_not(interactive())
+  
+  
+  ui <- fluidPage(
+    ## To be copied in the UI
+    mod_continentplot_ui("continentplot_1"),
+    tableOutput("table")
+  )
+  
+  server <- function(input, output) {
+    ## To be copied in the server
+    volcano_data <- readRDS("data/volcanoes.rds")
+    volcano_recent <- subset(volcano_data, last_eruption_year > 2000)
+    mod_continentplot_server("continentplot_1",
+                                              volcano = volcano_data,
+                                              selected_volcanoes = reactive(volcano_recent))
+  }
+  
+  shinyApp(ui = ui, server = server)
+})
+
+ + +
+
+ +
+ +
+ + + + \ No newline at end of file diff --git a/docs/posts/2021-07-19-glm-community-ecology/Gaussian.png b/docs/posts/2021-07-19-glm-community-ecology/Gaussian.png new file mode 100755 index 0000000..8753544 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/Gaussian.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/InflatedApproach4thcorner.png b/docs/posts/2021-07-19-glm-community-ecology/InflatedApproach4thcorner.png new file mode 100755 index 0000000..5655436 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/InflatedApproach4thcorner.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/UtilityFunctions.R b/docs/posts/2021-07-19-glm-community-ecology/UtilityFunctions.R new file mode 100644 index 0000000..37d8a5e --- /dev/null +++ b/docs/posts/2021-07-19-glm-community-ecology/UtilityFunctions.R @@ -0,0 +1,115 @@ +######################################################### +## Utility function to compute the different correlations +######################################################### +library(ade4) +TraitEnvCor <- function(L,E,T, Chessel = TRUE){ + + E<-as.matrix(E) + T<-as.matrix(T) + L<-as.matrix(L) + # centering_mat <- function(X,w){ X - rep(1,length(w))%*%t(w)%*% X } + standardize_w <- function(X,w){ + ones <- rep(1,length(w)) + Xc <- X - ones %*% t(w)%*% X + Xc / ones%*%sqrt(t(ones)%*%(Xc*Xc*w)) + } + + # check_L() + rows<-seq_len(nrow(L)) + cols<-seq_len(ncol(L)) + rni <-which(rowSums(L)==0) + repeat { + if (length(rni)) {L <- L[-rni,,drop = FALSE]; rows <-rows[-rni]} + ksi <- which(colSums(L)==0) + if (length(ksi)) {L <- L[,-ksi, drop = FALSE]; cols <- cols[-ksi]} + rni <-which(rowSums(L)==0) + if ( length(rni)==0 & length(ksi)==0){break} + } + E <-E[rows,,drop = FALSE] + T <-T[cols,,drop = FALSE] + # end check_L() + + L<-L/sum(L) + # dimensions + #S <- ncol(L) # number of species + #n <- nrow(L) # number of communities + p <- ncol(E) # number of environmental predictors + q <- ncol(T) # number of traits + + # setting up matrices + Wn <- rowSums(L) + Ws <- colSums(L) + # cor matrices are trait by environment + CWM <- L%*%T/Wn # weighted means wrt to T + CWM.cor <- cor(CWM,E) + + SNC <- t(L)%*%E/Ws # weighted means wrt to E + SNC.cor <- cor(T,SNC) + + CWMstd_w <- standardize_w(CWM,Wn) + Estd_w <- standardize_w(E,Wn) + wCWM.cor <- t(t(Estd_w)%*%(CWMstd_w*Wn)) + + SNCstd_w <- standardize_w(SNC,Ws) + Tstd_w <- standardize_w(T,Ws) + wSNC.cor <- t(Tstd_w)%*%(SNCstd_w*Ws) + + # Fourth corner calculated as W_n weighted covariance between + # CWM and standardized T (trait) + + CWM_std_tw <- L%*%Tstd_w/Wn #CWM wrt to standardized T (trait) + Fourthcorner <- t(CWM_std_tw)%*%(Estd_w*Wn) + if (Chessel){ + singular_val1 <- sqrt(ade4::dudi.coa(L, scannf = FALSE)$eig[1]) + Chessel.4thcor<-Fourthcorner/ singular_val1 + }else { Chessel.4thcor<-NA;singular_val1 <-1} + + + # variation components + # Among communities + Among.Variation <- sum(diag(t(CWM_std_tw)%*%(CWM_std_tw* Wn))) + # Within communities + Within.Variation <- 1 - Among.Variation + + # result specialized to one trait and one environment variables; use array(0, dim(6,k,p)) in the general case + # array.result<-matrix(c(CWM.cor,wCWM.cor,SNC.cor,wSNC.cor,Fourthcorner,Chessel.4thcor,Mean.Variation),ncol=1) + array.result<-array(0, dim=c(8,q,p)) + rownames(array.result)<- c("CWM.cor","wCWM.cor","SNC.cor","wSNC.cor","Fourthcorner","Chessel.4thcor","Among Wn-variance (%)", "Within Wn-variance (%)") + array.result[1,,]<-CWM.cor + array.result[2,,]<-wCWM.cor + array.result[3,,]<-SNC.cor + array.result[4,,]<-wSNC.cor + array.result[5,,]<-Fourthcorner + array.result[6,,]<-Chessel.4thcor + array.result[7,,]<-Among.Variation * 100 + array.result[8,,]<-Within.Variation * 100 + return(array.result[,,]) +} + +################################################################### +## Utility function for the row, column, and row-column permutation schemes +## for a single trait and a single environmental variable +## and the five test statistics/approaches of the paper +## CWM.cor, wCWM.cor, SNC.cor wSNC.cor and Fourthcorner +################################################################### + +CorPermutationTest <- function(L, E, T, nrepet = 999){ + E<-as.matrix(E) + T<-as.matrix(T) + L<-as.matrix(L) + obs <- TraitEnvCor(L,E,T)[1:5] + sim.row <- matrix(0, nrow = nrepet, ncol = ncol(E) * 5) + sim.col <- matrix(0, nrow = nrepet, ncol = ncol(E) * 5) + for(i in 1:nrepet){ + per.row <- sample(nrow(L)) + per.col <- sample(ncol(L)) + sim.row[i, ] <- c(as.matrix(data.frame(TraitEnvCor(L,E[per.row,,drop= FALSE],T))))[1:5] + sim.col[i, ] <- c(as.matrix(data.frame(TraitEnvCor(L,E,T[per.col,,drop= FALSE]))))[1:5] + } + pval.row <- (rowSums(apply(sim.row^2, 1, function(i) i >= obs^2)) + 1) / (nrepet + 1) + pval.col <- (rowSums(apply(sim.col^2, 1, function(i) i >= obs^2)) + 1) / (nrepet + 1) + + result <- cbind(cor = obs, prow = pval.row, pcol = pval.col, pmax = apply(cbind(pval.row, pval.col), 1, max)) + return(result) +} + diff --git a/docs/posts/2021-07-19-glm-community-ecology/aravo.png b/docs/posts/2021-07-19-glm-community-ecology/aravo.png new file mode 100755 index 0000000..615814d Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/aravo.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/bilinear.png b/docs/posts/2021-07-19-glm-community-ecology/bilinear.png new file mode 100755 index 0000000..4e0af74 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/bilinear.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/image.jpg b/docs/posts/2021-07-19-glm-community-ecology/image.jpg new file mode 100755 index 0000000..615814d Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/image.jpg differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index.html b/docs/posts/2021-07-19-glm-community-ecology/index.html new file mode 100644 index 0000000..2881e5a --- /dev/null +++ b/docs/posts/2021-07-19-glm-community-ecology/index.html @@ -0,0 +1,3114 @@ + + + + + + + + + + + + +BIOS2 Education resources - Generalized Linear Models for Community Ecology + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

Generalized Linear Models for Community Ecology

+
+
+ In this workshop we will explore, discuss, and apply generalized linear models to combine information on species distributions, traits, phylogenies, environmental and landscape variation. We will also discuss inference under spatial and phylogenetic autocorrelation under fixed and random effects implementations. We will discuss technical elements and cover implementations using R. +
+
+
+
Technical
+
EN
+
+
+
+ + +
+ +
+
Author
+
+

Pedro Peres-Neto

+
+
+ +
+
Published
+
+

May 17, 2021

+
+
+ + +
+ + +
+ + + + +
+ + + + +

Generalized Linear Model for Community Ecology

+Pedro Peres-Neto, Concordia University
+BIOS2 workshop, May 17 to 21, 2021
+This document was put together for the first time for this workshop.
+Let me know if you have suggestions or find any issues in the document.
+ +
+ +

Tentative schedule

+
    +
  • Day 1:
    +Introduction to types of data and approaches using GLMs in community ecology.
    +Types of patterns in species distributions involving trait and environmental variation.
    +Simulating data as a path to understand GLMs in community ecology.
    +The simplest GLM: widely used bivariate correlations.
    +The challenges of statistical inference regarding linking different types of information from communities and species.
    +Understanding estimators and their properties in GLMs.

  • +
  • Day 2:
    +From bivariate correlations to a variety of more complex GLMs: the case of Binomial and Poisson.
    +The role of latents in specifying GLMs for community ecology.
    +The issues underlying autocorrelation in ecological data: the cases of spatial and phylogenetic autocorrelation.
    +Simple GLMM approaches (Generalized Linear Mixed Models).

  • +
  • Day 3:
    +More complex GLMM approaches.
    +Potential approaches for incorporating intraspecific data on traits.
    +Discussion with participants: your research interests, your questions or your data (or anything really).

  • +
+

Philosophy: We can’t cover everything with extreme details. I’ve chosen a level that should be interesting enough and cover many different important aspects of GLMs applied to community ecology.

+

Note: I mostly apply here base functions so that participants without strong knowledge of certain packages (e.g., ggplot, dplyr) can follow the code more easily.

+

Questions: Participants should feel free to ask questions either directly or in the zoom chat. I’ve also set a good doc where participants can put questions there during the week when we are not connected. I’ll read them and try to provide an answer or cover the question somehow:

+

https://docs.google.com/document/d/17GQvGkBFs9MmLv6Yn473_Dr1t1Ps03VdHOHMhbZhBKk/edit

+
+ +
+Simulating data +
+

Simulating a single species

+

One way to develop good intuition underlying quantitative methods is to be able to simulate data according to certain desired characteristics. We can then apply methods (GLMs here) to see how well they retrieve the data characteristics.

+

Let’s start with a very simple GLM, the logistic regression for one single species. Here, for simplicity, we considered one predictor. In many ecological simulations, this single predictor is considered an “environmental gradient” containing many environmental predictors. We can consider more gradients and we will discuss that later on in the workshop.

+
+
set.seed(100) # so that we all have the same results
+n.sites <- 100
+X <- rnorm(n.sites)
+b0 <- 0.5 # controls the max prob. values
+prob.presence <- 1./(1+exp(-(b0+3*X)))
+plot(prob.presence ~ X)
+
+

+
+
+

This model is pretty simple and its form is:

+

\[p=\frac{1}{1+e^{-(\beta_0+\beta_1X_1)}} = \frac{1}{1+e^{-(0.5+3X_1)}}\]

+

Now let’s generate presences and absences according to the logistic model expectation. Since is a logistic model, we use rbinom,i.e., binomial trials:

+
+
Distribution <- rbinom(n.sites,1,prob.presence)
+
+
View(cbind(prob.presence,Distribution))
+

Let’s model the data using logistic regression:

+
+
model <- glm(Distribution ~ X,family=binomial(link=logit))
+coefficients(model)
+
+
(Intercept)           X 
+ 0.09200133  3.66168492 
+
+
+
View(cbind(prob.presence,Distribution,model$fitted.values))
+

Plotting the predicted versus the observed presence-absence values:

+
+
plot(model$fitted.values ~ Distribution)
+
+

+
+
+

At this point, we won’t cover model diagnostics. Data were simulated according to the model and, as such, assumptions hold well. Plus, this is a single-species model; and this workshop is about community data, i.e., multiple species :).

+

This is a good blog explaining how to check for assumptions of logistic regressions.

+

Simulating a more realistic single species

+

Species don’t tend to respond linearly to environmental features:

+
+
+

+
+
+

Now that we understand some basics of presence-absence data, let’s concentrate on more realistic species distribution data and multi-species data. There are many ways (found in the ecological literature) in which we can simulate these type of data. Below we will generate data using a standard Gaussian model for presence-absence data according to a trait and environmental feature (we will cover abundance data later on). This is a commonly used way to simulate data. Let’s start with a single species and one environmental variable.

+
+
set.seed(100) # so that we all have the same results
+n.sites <- 100
+X <- rnorm(n.sites)
+optimum <- 0.2
+niche.breadth <- 0.5
+b0 <- 1 # controls the max prob. values
+b1 <- -2
+# this is a logistic model:
+prob.presence <- 1./(1+exp(-(b0+(b1*(X-optimum)^2)/(2*niche.breadth^2)))) 
+
+

This more “complex” model has the following form:

+

\[p=\frac{1}{1+e^{-(\beta_0+\beta_1\frac{(X-\mu)^2}{2\sigma^2})}}=\frac{1}{1+e^{-(1+2\frac{(X-0.2)^2}{2\cdot0.5^2})}}\] where \(\mu\) represents the species optimum and \(\sigma\) its niche breadth.

+

Let’s plot these probabilities:

+
+
plot(X,prob.presence,ylim=c(0,1))
+# plot optimum
+abline(v=optimum,col="red")
+
+

+
+
+

Now let’s simulate the distribution, i.e., presences and absences according to the model. Since is a logistic, we use rbinom,i.e., binomial trials:

+
+
Distribution <- rbinom(n.sites,1,prob.presence)
+
+

Plot the species distribution against the environmental variable:

+
+
plot(X,prob.presence,ylim=c(0,1))
+sites.present <- which(Distribution==1)
+points(X[sites.present],Distribution[sites.present],col="green",pch=16,cex=0.5)
+sites.absent <- which(Distribution==0)
+points(X[sites.absent],Distribution[sites.absent],col="red",pch=16,cex=0.5)
+
+

+
+
+

The parameters can be then estimated from the data using a logistic regression:

+
+
predictor <- cbind(X,X^2) 
+model <- glm(Distribution ~ predictor,family=binomial(link=logit))
+coeffs <- coefficients(model)
+b0 <- coeffs[1]
+b1 <- coeffs[2]
+b2 <- coeffs[3]
+estimated.optimum <- -b1/(2*b2) # as in ter Braak and Looman 1986
+estimated.niche.breadth <- 1/sqrt(-2*b2)
+c(estimated.optimum,estimated.niche.breadth) # estimated by the glm
+
+
predictorX  predictor 
+ 0.3317377  0.3922625 
+
+
c(optimum,niche.breadth) # set in our simulations above
+
+
[1] 0.2 0.5
+
+
+

We can demonstrate computationally that the parameter estimations are unbiased as they are maximum likelihood via the GLM. Here we will be showing the sampling variation only for niche optimum and breadth. The other two parameters, \(\beta_0\) and \(\beta_1\) can be placed in the code below as well, demonstrating that they are also not biased.

+
+
n.samples <- 1000
+estimation.matrix <- matrix(0,n.samples,2)
+colnames(estimation.matrix) <- c("optimum","niche.breadth")
+# remember that we already set the parameters for the model above, i.e., optimum and niche breadth
+for (i in 1:n.samples){
+   X <- rnorm(n.sites)
+   prob.presence <- 1./(1+exp((-b0+((X-optimum)^2)/(2*niche.breadth^2)))) # this is a logistic model
+   Distribution <- rbinom(n.sites,1,prob.presence)
+   predictor <- cbind(X,X^2) 
+   model <- glm(Distribution ~ predictor,family=binomial(link=logit))
+   coeffs <- coefficients(model)
+   intercept <- coeffs[1]
+   b1 <- coeffs[2]
+   b2 <- coeffs[3]
+   estimation.matrix[i,"optimum"] <- -b1/(2*b2)
+   estimation.matrix[i,"niche.breadth"] <- 1/sqrt(-2*b2)
+}
+
+

There may be warnings “glm.fit: fitted probabilities numerically 0 or 1 occurred”. But that is not a problem per se. It just tells us that the for some species, their models capture the distribution values perfectly. By the way, that also happens with real data.

+

Let’s observe the random variation around the parameter estimates and the average values:

+
+
boxplot(estimation.matrix)
+abline(h=apply(estimation.matrix,2,mean),col="firebrick")
+
+

+
+
apply(estimation.matrix,2,mean)
+
+
      optimum niche.breadth 
+    0.2016913     0.4834230 
+
+
c(optimum,niche.breadth) # set in our simulations above
+
+
[1] 0.2 0.5
+
+
+

Note how the mean values are pretty close to the true values used to generate the data. This small simulation helps one understand the principles of sampling variation and unbiased estimation.

+

Simulating multiple species

+

Now, let’s generalize our code to multiple species. We will create a function that allow us to make sure that all sites have at least one species present and all species are present at least in one site; this is a common (but not necessary) characteristic of data used in community ecology.

+
+
generate_communities <- function(tolerance,E,T,n.species,n.communities){
+    repeat {
+        # generates variation in niche breadth across species
+        niche.breadth <- runif(n.species)*tolerance 
+        b0 <- runif(n.species,min=-4,max=4)
+        prob.presence <- matrix(data=0,nrow=n.communities,ncol=n.species)
+        Dist.matrix <- matrix(data=0,nrow=n.communities,ncol=n.species)
+        for(j in 1:n.species){
+          # species optima are trait values; which makes sense ecologically
+          prob.presence[,j] <- 1./(1+exp((-b0[j]+((E-T[j])^2)/(2*niche.breadth[j]^2)))) 
+          Dist.matrix[,j] <- rbinom(n.communities,1,prob.presence[,j])
+        }
+        n_species_c <- sum(colSums(Dist.matrix)!=0) # _c for check
+        n_communities_c <- sum(rowSums(Dist.matrix)!=0)
+        if ((n_species_c == n.species) & (n_communities_c==n.communities)){break}
+    }
+    result <- list(Dist.matrix=Dist.matrix,prob.presence=prob.presence)
+    return(result)
+}
+
+

Now let’s generate a community. Note that we are using one environmental gradient and one trait. We could consider more variables (trait or environmental features) by adding terms to the logistic equation above. But for the time being, that will suffice. Note, thout, that in many ecological simulations, this single predictor is considered an “environmental gradient” containing many environmental predictors. We can consider more gradients and we will discuss that later on in the workshop.

+
+
set.seed(12351) # so that we all have the same results
+n.communities <- 100
+n.species <- 50
+E <- rnorm(n.communities)
+T <- rnorm(n.species)
+Dist <- generate_communities(tolerance = 1.5, E, T, n.species, n.communities)
+Probs <- Dist$prob.presence
+Distribution <- Dist$Dist.matrix
+
+

Let’s plot the probability values across environmental values. To do that nicely, we need to order the communities according to their environmental values as follows:

+
+
E.sorted <- sort(E, index.return=TRUE)
+Probs.sorted <- Probs[E.sorted$ix,]
+E.sorted <- E.sorted$x
+matplot(E.sorted, Probs.sorted, cex.lab=1.5,cex.axis=2,lty = "solid", type = "l", pch = 1:10, cex = 0.8,
+        xlab = "Enviroment", ylab = "Probability of presence")
+
+

+
+
+

And let’s plot presences and absences against ordered environmental and trait values:

+
+
heatmap(as.matrix(Distribution),scale="none",Rowv=E,Colv=T,col=c("white","black"),labCol="species",labRow="communities")
+
+

+
+
+
+ +
+Classic and simple GLMs for one trait and one environment (bivariate correlations) +
+

Now that we have a basic understanding of one GLM (logistic) and how they can model different types of community ecology data, i.e., species distributions, traits and environmental variation, we can start looking into approaches that that are used by ecologists to estimate the importance of environmental and trait variation to species distributions.

+

Let’s start by calculating the simplest and widely used metric of the community weighted trait mean:

+
+
CWM <- Distribution %*% T / rowSums(Distribution)
+
+

For data that are based on presence-absence, this is simply the average of species trait values within communities.

+

Let’s now correlate CWM with the environment, i.e., community weighted means correlation. This is a widely used approach by ecologists:

+
+
plot(CWM ~ E)
+
+

+
+
cor(CWM,E)
+
+
          [,1]
+[1,] 0.9296338
+
+
+

Again, the community weighted means correlation is likely the most commonly used approach with 1000s of studies having been published with it.

+

Another approach is to calculate the species weighted environment means and correlate with trait values. This approach is less common (but still quite used in the ecological literature) and is sometimes referred as to species niche centroid (SNC):

+
+
SNC <- t(E %*% Distribution) / colSums(Distribution)
+
+

Let’s now correlate SNC with species traits:

+
+
plot(T ~ SNC)
+
+

+
+
cor(T,SNC)
+
+
          [,1]
+[1,] 0.7700065
+
+
+

Note that the two correlations (CWM- and SNC-based) differ. That’s odd as they were both calculated on exactly the same information: the same Species Matrix, Environment and Trait. Peres-Neto, Dray & ter Braak (2017) demonstrated (mathematically) that this issue is related to the fact that although CWM and SNC are based on weights, they don’t standardized and correlate them with the proper weights. CWM is based on averages calculated based on the sum of species (richness or total abundance per community) and SNC is based on averages calculated based on the number of communities in which species are presence (prevalence) or their total abundance.

+

Because of that, we have found (Peres-Neto et al. 2017) a few undesirable properties of these two correlations (CWM and SNC-based correlations). One is that when the correlation is expected to be zero, the sampling variation of these correlations are quite large (i.e., low precision). Let’s evaluate this issue: Below we generate data with structure, but then use a false trait completely independent of the original one, thus destroying the link between trait and environmental variation.

+
+
set.seed(120) # so that we all have the same results
+n.communities <- 100
+n.species <- 50
+n.samples <- 100 # set to larger later
+
+CWM.cor <- as.matrix(0,n.samples)
+for (i in 1:n.samples){
+  E <- rnorm(n.communities)
+  T <- rnorm(n.species)
+  Dist <- generate_communities(tolerance = 1.5, E, T, n.species, n.communities)
+  T.false <- rnorm(n.species)
+  CWM <- Dist$Dist.matrix %*% T.false / rowSums(Dist$Dist.matrix)
+  CWM.cor[i] <- cor(CWM,E)
+}
+
+

Let’s plot the correlations:

+
+
boxplot(CWM.cor)
+abline(h=mean(CWM.cor),col="firebrick")
+
+

+
+
+

Note that the variation is quite large for correlations based on a random trait (i.e., T.false). For example, some correlations were greater than 0.7 and smaller than -0.60. We showed that although the variation is quite large, the expected value is zero; we would need 10000 or more simulations to make mean(CWM.cor) approach almost zero. A similar issue (i.e., large variation, low precision) happens for correlations based on SNO but we won’t simulate here for brevity. One can easily adapt the code above to do so though.

+

We have shown that precision is much increased when using the 4th corner statistic. Originally described in matrix form by Legendre et al. (1997), we (Peres-Neto et al. 2017) demonstrated that the 4th corner statisticit is a GLM assuming an identity link, i.e., normally distributed residuals.

+

The basis of the 4th corner correlation is that it starts by the standardization of the trait by the sum of their species abundances (or number of sites occupied for presence-absence data), and the standardization of the environment by the sum of their community abundances. The default standardization (function scale) transforms the variable (trait or environment) in a way that its mean and standard deviation are 0 and 1, respectively. A weighted standardization makes the weighted mean and weighted standard deviation to be 0 and 1, respectively.

+

R doesn’t have a default function for weighted standardization. But this can be done using the follow function:

+
+
standardize_w <- function(X,w){
+   ones <- rep(1,length(w))
+   Xc <- X - ones %*% t(w)%*% X
+   Xc / ones%*%sqrt(t(ones)%*%(Xc*Xc*w)) 
+} 
+
+

Let’s get back to the original data used to calculate CWM and SNC based correlations:

+
+
set.seed(12351) # so that we all have the same results
+n.communities <- 100
+n.species <- 50
+E <- rnorm(n.communities)
+T <- rnorm(n.species)
+Dist <- generate_communities(tolerance = 1.5, E, T, n.species, n.communities)
+Distribution <- Dist$Dist.matrix
+
+

We then standardize environment and trait by their respective abundance sums (rows for environment & columns for trait).

+
+
# make distribution matrix relative to its total sum; it makes calculations easier
+Dist.rel <- Distribution/sum(Distribution)
+Wn <- rowSums(Dist.rel)
+Ws <- colSums(Dist.rel)
+E.std_w <- standardize_w(E,Wn)
+T.std_w <-  standardize_w(T,Ws)
+
+

Note: In the future, include here the calculation of the weighted mean and standard deviation of E.std_w and T.std_w to show that they are zero and one, respectively (when weighted).

+

We then calculate the community average trait (weighted standardized) or the species niche centroid (weighted standardized):

+
+
CWM.w <- Dist.rel %*% T.std_w / Wn
+SNC.w <- t(E.std_w) %*% Dist.rel / Ws
+
+

We then calculate the weighted correlation between the two vectors above but their appropriate weights. In the case of CWM.w:

+
+
# either using weighted correlation:
+t(CWM.w) %*% (E.std_w*Wn)
+
+
          [,1]
+[1,] 0.2813709
+
+
# or the same value using weighted regression:
+lm(CWM.w ~ E.std_w,weights = Wn)
+
+

+Call:
+lm(formula = CWM.w ~ E.std_w, weights = Wn)
+
+Coefficients:
+(Intercept)      E.std_w  
+  8.804e-17    2.814e-01  
+
+
+

In the case of SNC.w:

+
+
# either using weighted correlation:
+SNC.w %*% (T.std_w*Ws)
+
+
          [,1]
+[1,] 0.2813709
+
+
# or the same value using weighted regression:
+lm(t(SNC.w)~T.std_w,weights = Ws)
+
+

+Call:
+lm(formula = t(SNC.w) ~ T.std_w, weights = Ws)
+
+Coefficients:
+(Intercept)      T.std_w  
+ -5.000e-17    2.814e-01  
+
+
+

Note that regardless whether SNC or CWM were used, the 4th corner correlation gives the same result, which makes sense mathematically as both correlations use the exact same information. The reason (again) that the CWM and SNC standard correlation approaches differ is because they don’t use appropriate weights in their standardization and weighted correlation.

+

Another issue to notice is that the 4th corner values are smaller than their standard CWM values. Whereas the CWM correlation was 0.9296, the 4th corner was 0.2814. The issue here is that the CWM correlation refers only to the trait variation among communities (trait beta-diversity), whereas the 4th corner refers to the total variation in traits (within, i.e., trait alpha diversity, and among communities, i.e., trait beta-diversity). This was demonstrated by algebraic proofs in Peres-Neto et al. (2017) but we won’t get into these details here.

+

This does bring an interesting point for the analysis of trait in a community ecology context. The relative trait variation among communities (i.e., total trait beta-diversity) and within communities (i.e., gamma trait diversity) can be estimated as follows:

+
+
# Among communities 
+Among.Variation <- sum(diag(t(CWM.w)%*%(CWM.w* Wn))) * 100
+# Within communities 
+Within.Variation <- 100 - Among.Variation
+c(Among.Variation,Within.Variation)
+
+
[1]  9.460287 90.539713
+
+
+

The standard CWM correlation is high because it pertains to only 9.46% of the total variation, whereas the 4th corner correlation pertains to all variation, i.e., both within and among. As the among communities component become large, the two correlations become somewhat more similar.

+

Let’s now investigate the sampling properties of the 4th corner correlation as we did above for the CWM correlation, i.e., when the trait-environment correlation is expected to be zero:

+
+
set.seed(120) # so that we all have the same results and the same communities and traits are generated as before
+n.communities <- 100
+n.species <- 50
+n.samples <- 100 # set to larger later
+
+CWM.4th.cor <- as.matrix(0,n.samples)
+for (i in 1:n.samples){
+   E <- rnorm(n.communities)
+   T <- rnorm(n.species)
+   Dist <- generate_communities(tolerance = 1.5, E, T, n.species, n.communities)
+   T.false <- rnorm(n.species) # destroys the original generated relationship
+   Dist.rel <- Dist$Dist.matrix/sum(Distribution)
+   Wn <- rowSums(Dist.rel)
+   E.std_w <- standardize_w(E,Wn)
+   T.std_w.false <-  standardize_w(T.false,Ws)
+   CWM.w.false <- Dist.rel %*% T.std_w.false / Wn
+   t(CWM.w.false) %*% (E.std_w*Wn)
+   CWM.4th.cor[i] <- cor(CWM,E)
+}
+
+

Let’s compare the two statistics:

+
+
boxplot(cbind(CWM.cor,CWM.4th.cor))
+
+

+
+
+

Note how the 4th corner correlation is a much more precise predictor around the true value of zero.

+
+ +
+Statistical hypothesis testing +
+

We know for a while that the bivariate correlations discussed so far have elevated type I error rates based on parametric testing and under certain permutation schemes (Dray and Legendre 2008; and Dray et al. 2014). That means that when the statistical null hypothesis of no link between trait and environment will be rejected more often than the preset alpha level (significance level, e.g., 0.05 or 0.01). More recently, this was also established for more complex models (more on this later). Resolving these issues are challenging and remain a very active field of research.

+

The code so far has helped to build some intuition underlying the different bivariate correlations. We will now use a more complete utility function that allows calculating these different metrics using one single function. This function is part of Peres-Neto et al. (2017).

+

Download the utility function file:

+

Click here to download it

+

Load the functions into R:

+
+
source("UtilityFunctions.R")
+
+

Let’s use the function that calculates a number of the bivariate correlations, which are essentially simple GLMs.

+
+
set.seed(125)
+E <- rnorm(n.communities)
+T <- rnorm(n.species)
+Dist <- generate_communities(tolerance = 1.5, E, T, n.species, n.communities)
+TraitEnv.res <- TraitEnvCor(Distribution,E,T, Chessel = TRUE)
+TraitEnv.res
+
+
               CWM.cor               wCWM.cor                SNC.cor 
+           0.016601826            0.054714685            0.288779046 
+              wSNC.cor           Fourthcorner         Chessel.4thcor 
+           0.039080469            0.006235766            0.015313259 
+ Among Wn-variance (%) Within Wn-variance (%) 
+           1.298888497           98.701111503 
+
+
+

If we want to isolate the 4th corner correlation, we can simply:

+
+
TraitEnv.res["Fourthcorner"]
+
+
Fourthcorner 
+ 0.006235766 
+
+
+

Let’s now run permutation Model 2, Model 4 and p.max for data without a link between trait and environment. We first create the data with no link:

+
+
set.seed(125)
+E <- rnorm(n.communities)
+T <- rnorm(n.species)
+Dist <- generate_communities(tolerance = 1.5, E, T, n.species, n.communities)
+Distribution <- Dist$Dist.matrix
+T.false <- rnorm(n.species)
+TraitEnv.res <- TraitEnvCor(Distribution,E,T.false, Chessel = FALSE)
+TraitEnv.res["Fourthcorner"]
+
+
Fourthcorner 
+  0.04168433 
+
+
+

Note how the 4th corner correlation is quite low, i.e., 0.0417. Now let’s check this value with permutations:

+
+
set.seed(125)
+nrepet <- 99
+obs <- TraitEnv.res["Fourthcorner"]
+sim.row <- matrix(0, nrow = nrepet, ncol = 1)
+sim.col <- matrix(0, nrow = nrepet, ncol = 1)
+for(i in 1:nrepet){
+   per.row <- sample(nrow(Distribution)) # permute communities
+   per.col <- sample(ncol(Distribution)) # permute species
+   sim.row[i] <- TraitEnvCor(Distribution,E[per.row],T.false)["Fourthcorner"]
+   sim.col[i] <- TraitEnvCor(Distribution,E,T.false[per.col])["Fourthcorner"]
+}
+pval.row <- (length(which(abs(sim.row) >= abs(obs))) + 1) / (nrepet + 1)
+pval.col <- (length(which(abs(sim.col) >= abs(obs))) + 1) / (nrepet + 1)
+p.max <- max(pval.row,pval.col)
+c(pval.row,pval.col,p.max)
+
+
[1] 0.01 0.47 0.47
+
+
+

As we can see, although only environmental features were important but not traits, the row permutation (across commmunities) detected the relationship as significant. Note, however, that the permutation across species did not. ter Braak et al. (2012) determined that the maximum value between the two p-values (row and column based) assures appropriate type I error rate as expected alpha.

+

The function above allows understanding the permutation procedures. That said, the utility function file has a more complete function:

+
+
set.seed(125)
+CorPermutationTest(Distribution, E, T.false, nrepet = 99)
+
+
                    cor prow pcol pmax
+CWM.cor      0.36605145 0.01 0.33 0.33
+wCWM.cor     0.28014652 0.01 0.44 0.44
+SNC.cor      0.14836877 0.39 0.36 0.39
+wSNC.cor     0.09492897 0.26 0.47 0.47
+Fourthcorner 0.04168433 0.01 0.47 0.47
+
+
+
+ +
+Bivariate correlations in practice +
+

I hope by now you are convinced that the 4th corner is a more robust metric of bivariate correlation (one trait and one environment). Here we will use the Aravo community plant data set (Massif du Grand Gabilier, France; Choler 2005) contained in the package ade4. We provide more explanation on the data in Dray et al. (2012). Here we will replicate the analysis in that paper. The data contain species abundances for 82 species distributed into 75 sites. Sites are described by 6 environmental variables: mean snowmelt date over the period 1997–1999, slope inclination, aspect, index of microscale landform, index of physical disturbance due to cryoturbation and solifluction, and an index of zoogenic disturbance due to trampling and burrowing activities of the Alpine marmot. All variables are quantitative except the landform and zoogenic disturbance indexes that are categorical variables with five and three categories, respectively. And eight quantitative functional traits (i.e., vegetative height, lateral spread, leaf elevation angle, leaf area, leaf thickness, specific leaf area, mass-based leaf nitrogen content, and seed mass) were measured on the 82 most abundant plant species (out of a total of 132 recorded species).

+
+
+

+
+
+

Load the package and the data:

+
+
# install.packages("ade4") in case you don't have it installed
+library(ade4)
+data(aravo)
+dim(aravo$spe)
+
+
[1] 75 82
+
+
dim(aravo$env)
+
+
[1] 75  6
+
+
dim(aravo$trait)
+
+
[1] 82  8
+
+
+

Let’s estimate the 4th corner correlations between each trait and environmental variable. nrept is the number of permutations and should be set to a reasonable high number (say 9999). Here we will use 999 to speed calculations. Note that all permutation tests (not only the ones for the 4th corner) include the observed correlation as part of the null distribution (i.e., permuted); hence the use of nrept as 999, i.e., 1000 possible permutations (the observed correlation is a possible permutation if we run the test infinite times; which is not possible; so we consider it as default. modeltype is set to 6, which is the largest p-value between model 2 permutation (entire communities in the distribution matrix) and model 4 (entire species in the distribution matrix). The p-max procedure is detailed in ter Braak et. 2012. Finally, p-values are adjusted using the false discovery rate for multiple testing.

+
+
four.comb.aravo.adj <- fourthcorner(aravo$env, aravo$spe,
+aravo$traits, modeltype = 6, p.adjust.method.G = "none",
+p.adjust.method.D = "fdr", nrepet = 999)
+
+

Results can be retrieved by simply typing:

+
four.comb.aravo 
+

The ‘classic’ table of results can be produced as follows. D2 indicates that the 4th corner correlation is to be used between the quantitative variable and each category of the qualitative variables. Other bivariate metrics of 4th corner association are also described in Dray and Legendre (2008) for qualitative-quantitative associations. In the default plot, blue cells correspond to negative signicant relationships while red cells correspond to positive signicant relationships (this can be modified using the argument col in the function fourthcorner).

+
+
plot(four.comb.aravo.adj, alpha = 0.05, stat = "D2")
+
+

+
+
+
+ +
+Stacking species information as a way to understand how to build more complex GLMs +
+

Although widely used (1000s of studies published using them), bivariate correlations are the simplest forms of GLMs for community data. That said, the 4th corner correlation can be calculated in a way that allows us (hopefully) to understand how more complex GLMs can be produced. They allow us understanding species stacking. Perhaps I should have considered this presentation before the calculations based on weights and standardizations (will inverst in the next version of the workshop). Let’s build a small data so that we understand this principle. Consider a very artificial distribution matrix with 4 communities and 4 species. It was made artificial so that we can understand well its structure:

+
+
Distribution <- as.matrix(rbind(c(1,1,0,0),c(1,0,0,0),c(0,0,1,1),c(0,0,1,0)))
+Distribution
+
+
     [,1] [,2] [,3] [,4]
+[1,]    1    1    0    0
+[2,]    1    0    0    0
+[3,]    0    0    1    1
+[4,]    0    0    1    0
+
+
+

Let’s create some traits and environmental features:

+
+
T <- c(1,2,5,8)
+E <- c(10,12,100,112)
+
+

Now let’s calculate its 4th corner correlation:

+
+
TraitEnvCor(Distribution,E,T)["Fourthcorner"]
+
+
Fourthcorner 
+   0.8902989 
+
+
+

The 4th corner correlation is pretty high given the highly structured data. Another way to calculate a 4th corner correlation is by using what we refer to as an “inflated approach”. This approach allows understanding the structure of stacked information. This figure demonstrates the process and calculation:

+
+
+

+
+
+

Next we stack species distributions, environment and trait information:

+
+
n.species <- ncol(Distribution)
+n.sites <- nrow(Distribution)
+Dist.stacked <- as.vector(Distribution)
+E.stacked <- rep(1, n.species) %x% E
+T.stacked <- T %x% rep(1, n.sites)  
+
+
View(cbind(Dist.stacked,E.stacked,T.stacked))
+

We then eliminatate the cells for which the distribution is zero and calculate the correlation:

+
+
zeros.dist <- which(Dist.stacked==0)
+cor(E.stacked[-zeros.dist],T.stacked[-zeros.dist])
+
+
[1] 0.8902989
+
+
+

Note: perhaps I should have started with this explanation and then move to the more complicated way of using weights. The inflated approach is in fact a way to see how weights are given.

+
+ +
+Simulating abundance data and understanding link functions in GLMs +
+

Simple model

+

Although community ecologists commonly work with presence-absence data, abundance data are also commonly used in many approaches. Here we will use a Poisson model to simulate community data involving species distributions, traits and environment. Although link functions are used in all families of GLMs (poisson, binomial, negative binomial, gamma, etc), we will try to provide an explanation here of what they mean using abundance data. But the same rationale will apply to all families.

+
+
set.seed(100) # so that we all have the same results
+n.sites <- 100
+X <- rnorm(n.sites)
+b0 <- 0.05
+b1 <- 2
+Y <- exp(b0 + b1*X)
+Abundance <- rpois(n.sites,Y)
+plot(Abundance ~ X)
+
+

+
+
+

This Poisson model has the following form. Note that multiple predictors can be considered. Here, for simplicity, we considered one predictor. Again, in many ecological simulations, this single predictor is considered an “environmental gradient” containing many environmental predictors. We can consider more gradients and we will discuss that later on in the workshop.

+

\[Y={e^{(\beta_0+\beta_1X_1)}}=e^{(0.05+1.2X_1)}=log(Y)=0.05+1.2X_1\] The model can be estimated as:

+
+
model <- glm(Abundance ~ X, family="poisson")
+coefficients(model)
+
+
(Intercept)           X 
+ 0.03095719  2.02323099 
+
+
plot(model$fitted.values ~ Abundance)
+
+

+
+
+

GLMs are linear models because they use link-functions to map non-linear relationships to a linear one. In this way, the link function connects the predictors in a model with the expected (mean) value of the response variable (dependent variable). In other words, the link-functions transforms the response values into new values that can be then regressed using linear approaches (Maximum Likelihood-based approaches and not simple OLS, ordinary least square approaches as in linear regression) against the X values. As we saw in the first example of the Poisson regression above, the relationship is not linear. The link-function for the Poisson distribution is ln of the response. Let’s understand this point by plotting the log(Y) and X. Note that Y has no error and Abundance has error (i.e., based on the rpois, i.e., poisson trials)

+
+
# without error:
+plot(log(Y) ~ X)
+
+

+
+
# with error
+plot(log(Abundance) ~ X)
+
+

+
+
+

What does the passage “the link-function connects the predictors in a model with the expected (mean) value of the response variable (dependent variable)” mean? As you can notice, we used Poisson trials to generate error around the initial Y values. Let’s create a 100 possible trials:

+
+
mult.Y <- replicate(n=100,expr=rpois(n.sites,Y))
+
+
View(mult.Y)
+

Each column in mult.Y contains one single trial. This would mimic, for instance, your error in estimating abundances when sampling real populations and assuming that a Poisson GLM would model your abundances across sites well. As such, in real data, obviously, we only have one “trial”. But this small demonstration hopefully helps you understand what the GLM is trying to estimate via the link-function.

+

Let’s repeat the predictor X 100 times`so that it becomes compatible in size with the multiple trials; and we can then plot them:

+
+
rep.X <- rep(X, times = 100)
+plot(as.vector(mult.Y) ~ rep.X,pch=16,cex=0.5,col="firebrick")
+
+

+
+
+

Note that larger values of abundances tend to have more error under the poisson model (which is also ecologically plausible).

+

Now we can understand what the passage “the link-function connects the predictors in a model with the expected (mean) value of the response”. Let’s first increase the number of trials to 10000 and for each site (for which we have an X value), calculate its mean:

+
+
mult.Y <- replicate(n=10000,expr=rpois(n.sites,Y))
+mean.mult.Y <- apply(mult.Y,1,mean)
+plot(mean.mult.Y ~ Y)
+
+

+
+
+

As we can observe, the mean across all trials (errors) equal the response variable Y, i.e., without error. Hopefully this provides a general understanding of what link functions are. A similar explanation can be given for the logistic regression (i.e., binomial error). In there we use a logit link function (transformation) instead.

+

Missing predictors in GLMs as a source of error

+

Obviously the fit is great, particularly because we considered all the important predictors in the model. We don’t usually have all predictors in a model and this can be simulated as well. Considering the following example where two environmental predictors were used to generate the abundance data but only was used in the regression model:

+

\[p={e^{(\beta_0+\beta_1X_1+\beta_1X_2)}}\]

+
+
set.seed(100) # so that we all have the same results
+n.sites <- 100
+X <- matrix(rnorm(n.sites*2),n.sites,2)
+b0 <- 2
+b1 <- 0.5
+b2 <- 1.2
+Y <- exp(b0 + b1*X[,1] + b1*X[,2]) # there are more direct matricial ways to do that
+Abundance <- rpois(n.sites,Y)
+model <- glm(Abundance ~ X[,1], family="poisson")
+model
+
+

+Call:  glm(formula = Abundance ~ X[, 1], family = "poisson")
+
+Coefficients:
+(Intercept)       X[, 1]  
+     2.0472       0.5294  
+
+Degrees of Freedom: 99 Total (i.e. Null);  98 Residual
+Null Deviance:      532.1 
+Residual Deviance: 258.8    AIC: 637.7
+
+
plot(model$fitted.values ~ Abundance)
+
+

+
+
AIC(model)
+
+
[1] 637.7152
+
+
+

Note that the errors around predicted and true values are much greater because only one predictor was included in the GLM even though two predictors were important. Now considering both predictors:

+
+
model <- glm(Abundance ~ X, family="poisson")
+model
+
+

+Call:  glm(formula = Abundance ~ X, family = "poisson")
+
+Coefficients:
+(Intercept)           X1           X2  
+     1.9808       0.5300       0.4931  
+
+Degrees of Freedom: 99 Total (i.e. Null);  97 Residual
+Null Deviance:      532.1 
+Residual Deviance: 119  AIC: 500
+
+
plot(model$fitted.values ~ Abundance)
+
+

+
+
AIC(model)
+
+
[1] 500.0011
+
+
+

This is a critical empirical (ecological) consideration because we can’t measure everything. The error is much smaller and, as a consequence, the model fit is much improved (i.e., smaller AIC values) because it considers the two predictors. It can’t be perfect because of the error related to the poisson trials that will always result in random variation (residual variation).

+

A more realistic Gaussian Poisson model

+

As for the logistic model, we can also consider a more realistic Poisson model based on a Gaussian distribution:

+

\[Y={h\cdot e^{-(\beta_0+\beta_1\frac{(X-\mu)^2}{2\sigma^2})}}\] As before, \(\mu\) represents the species optimum and \(\sigma\) its niche breadth. \(h\) represents the expected abundance in the optimum environmental value. Using code to simulate this model for one species; for simplicity, we will set \(\beta_0=0\) and \(\beta_1=1\):

+
+
set.seed(110)
+X <- rnorm(n.sites)
+optimum <- 1.2
+niche.breadth <- 0.5
+h <- 104
+Y <- h * exp(-(X-optimum)^2/(2*niche.breadth^2))
+Abundance <- rpois(n.sites,Y)
+plot(Abundance~X)
+abline(v=1.2,col="firebrick")
+
+

+
+
+

Let’s fit the Poisson model:

+
+
predictor <- cbind(X,X^2) 
+model <- glm(Abundance ~ predictor,family="poisson")
+plot(model$fitted ~ X)
+
+

+
+
coeffs <- coefficients(model)
+
+

As before, parameters used to simulate the species distribution can be estimated as:

+
+
b0 <- coeffs[1]
+b1 <- coeffs[2]
+b2 <- coeffs[3]
+estimated.optimum <- -b1/(2*b2) 
+estimated.niche.breadth <- 1/sqrt(-2*b2)
+h <- exp(b0 + b1*estimated.optimum + b2*estimated.optimum^2)
+cbind(estimated.optimum,estimated.niche.breadth,h)
+
+
           estimated.optimum estimated.niche.breadth        h
+predictorX          1.179753               0.4726181 104.8035
+
+
+

Now we can generalize the code to generate abundance data for multiple species:

+
+
generate_community_abundance <- function(tolerance,E,T,preset_nspecies,preset_ncommunities){
+    repeat {
+        # one trait, one environmental variable
+        h <- runif(preset_nspecies,min=0.3,max=1)
+        sigma <- runif(preset_nspecies)*tolerance
+        L <- matrix(data=0,nrow=preset_ncommunities,ncol=preset_nspecies)
+        for(j in 1:preset_nspecies){
+            L[,j] <- 30*h[j]*exp(-(E-T[j])^2/(2*sigma[j]^2))
+              #rpois(preset_ncommunities,30*h[j]*exp(-(E-T[j])^2/(2*sigma[j]^2)))
+        }
+        n_species_c <- sum(colSums(L)!=0) # _c for check
+        n_communities_c <- sum(rowSums(L)!=0)
+        if ((n_species_c == preset_nspecies) & (n_communities_c==preset_ncommunities)){break}
+    }
+    return(L)
+}
+
+
+
set.seed(120) # so that we all have the same results
+n.communities <- 100
+n.species <- 50
+E <- rnorm(n.communities)
+T <- rnorm(n.species)
+Y <- generate_community_abundance(tolerance = 1.5, E, T, n.species, n.communities)
+
+

Let’s plot the expected abundance values across environmental values. To do that nicely, we need to order the communities according to their environmental values as follows:

+
+
E.sorted <- sort(E, index.return=TRUE)
+Y.sorted <- Y[E.sorted$ix,]
+E.sorted <- E.sorted$x
+matplot(E.sorted, Y.sorted, cex.lab=1.5,cex.axis=2,lty = "solid", type = "l", pch = 1:10, cex = 0.8,
+        xlab = "Enviroment", ylab = "Abundance")
+
+

+
+
+

Y, however, has no error and to create abundance values for each species (i.e., each column of Y; MARGIN = 2) according to a poisson model we can simply:

+
+
Abundances <- apply(Y,MARGIN=2,function(x) rpois(n.communities,x))
+
+

Let’s plot the abundance values across environmental values. With erorr, they don’t look as nice, obviously:

+
+
E.sorted <- sort(E, index.return=TRUE)
+Abundances.sorted <- Abundances[E.sorted$ix,]
+E.sorted <- E.sorted$x
+matplot(E.sorted, Abundances.sorted, cex.lab=1.5,cex.axis=2,lty = "solid", type = "l", pch = 1:10, cex = 0.8, xlab = "Enviroment", ylab = "Abundance")
+
+

+
+
+

Finally, let’s calculate the 4th corner statistics for these data:

+
+
TraitEnvCor(Abundances,E,T, Chessel = TRUE)["Fourthcorner"]
+
+
Fourthcorner 
+   0.5365449 
+
+
+

And now for the data without error, i.e., before the poisson trials:

+
+
TraitEnvCor(Y,E,T, Chessel = TRUE)["Fourthcorner"]
+
+
Fourthcorner 
+   0.5333836 
+
+
+

Despite the error we observed once we transformed Y (values without error) into abundances (with error via the poisson trials), the bivariate correlations are pretty similar, indicating that these metrics are robust against sampling error in abundances. Note, however, that we only used one predictor which was the one used to simulate the data to begin with; empirical data are much more complex than that.

+

Finally, note that, as such, bivariate correlations are calculated in the same way regardless if the data are presence-absence or abundance; biomass data could be also considered.

+
+ +
+Moving to more complex GLMs - the bilinear model +
+

Let’s go back to our stacked model:

+
+
+

+
+
+

And now let’s get back to our stacked approach using again the simplest example we used earlier. Let’s enter the data again to make sure that we have the same data.

+
+
Distribution <- as.matrix(rbind(c(1,1,0,0),c(1,0,0,0),c(0,0,1,1),c(0,0,1,0)))
+T <- c(1,2,5,8)
+E <- c(10,12,100,112)
+n.species <- ncol(Distribution)
+n.sites <- nrow(Distribution)
+Dist.stacked <- as.vector(Distribution)
+E.stacked <- rep(1, n.species) %x% scale(E)
+T.stacked <- scale(T) %x% rep(1, n.sites)
+
+

There are two ways in which we can code the analysis. Using the stacked way or using a kronecker product. The kronecker product stacks the data in the same way but it’s a bit more “cryptic” and demonstrating the stacking is then easier by using simple coding. The stacked GLM below estimates the statistical interaction between Environment and Traits only. Note that the distribution for our ficitional example above is for presence and absences, hence we will use a binomial link-function (i.e., logistic regression). This can be referred as to the bilinear model by Gabriel (1998) which is rarely used in ecology but can provide a good introduction to what “stacking” means which is critical to understand more complex GLMs.

+

Using the stacked vectors above, we have:

+
+
 predictor <- E.stacked * T.stacked
+ model <- glm(Dist.stacked ~ predictor,family=binomial(link=logit))
+ summary(model)
+
+

+Call:
+glm(formula = Dist.stacked ~ predictor, family = binomial(link = logit))
+
+Deviance Residuals: 
+    Min       1Q   Median       3Q      Max  
+-2.1282  -0.5101  -0.2570   0.7417   1.3162  
+
+Coefficients:
+            Estimate Std. Error z value Pr(>|z|)  
+(Intercept)  -0.9160     0.7681  -1.193   0.2330  
+predictor     2.4991     1.1975   2.087   0.0369 *
+---
+Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+
+(Dispersion parameter for binomial family taken to be 1)
+
+    Null deviance: 21.170  on 15  degrees of freedom
+Residual deviance: 13.597  on 14  degrees of freedom
+AIC: 17.597
+
+Number of Fisher Scoring iterations: 5
+
+
+

The stacking we saw can be easily done using matrix algebra (the early presentation is helpful to understand the principles though). To do it in algebra, we use the kronecker product as follows:

+

\[Y= T\otimes E\]

+

As such, the bilinear model is testing the statistical interaction between traits and environmental variables.

+

which in R becomes:

+
+
predictor2 <- T %x% E
+model <- glm(Dist.stacked ~ predictor,family=binomial(link=logit))
+summary(model)
+
+

+Call:
+glm(formula = Dist.stacked ~ predictor, family = binomial(link = logit))
+
+Deviance Residuals: 
+    Min       1Q   Median       3Q      Max  
+-2.1282  -0.5101  -0.2570   0.7417   1.3162  
+
+Coefficients:
+            Estimate Std. Error z value Pr(>|z|)  
+(Intercept)  -0.9160     0.7681  -1.193   0.2330  
+predictor     2.4991     1.1975   2.087   0.0369 *
+---
+Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+
+(Dispersion parameter for binomial family taken to be 1)
+
+    Null deviance: 21.170  on 15  degrees of freedom
+Residual deviance: 13.597  on 14  degrees of freedom
+AIC: 17.597
+
+Number of Fisher Scoring iterations: 5
+
+
+

Note that the two ways to run the model results in the exact same estimates. Here we should interpret the slope for the model as the strength between trait and environment, i.e., \(\beta_1 = 2.4991\). Obviously the bilinear model can be easily extended to any class of GLMs as well depending on the nature of the response variable (e.g., poisson, negative binomial, etc; more on these below).

+

Note also that we could have considered multiple traits and environments (as long as we have enough degrees of freedom).

+

Stacked or bilinear model on the Aravo data set

+

Let’s apply the Aravo data set we saw early here. We will reduce the environmental matrix by removing the qualitative variables. These can be easily accommodated but for the sake of speed, we will reduce it.

+
+
E <- aravo$env[,c("Aspect","Slope","Snow")]
+E <- as.matrix(E)
+T <- as.matrix(aravo$trait)
+
+

Now we apply the kronecker product using the base function kronecker rather than %x% that we saw early. This function generate names for each column of the matrix (i.e., interactions between each trait and predictor). The columns contain all possible two by two (pairwise) combinations of traits and environmental features.

+
+
TE <- kronecker(T, E, make.dimnames = TRUE)
+dim(TE)
+
+
[1] 6150   24
+
+
colnames(TE)
+
+
 [1] "Height:Aspect" "Height:Slope"  "Height:Snow"   "Spread:Aspect"
+ [5] "Spread:Slope"  "Spread:Snow"   "Angle:Aspect"  "Angle:Slope"  
+ [9] "Angle:Snow"    "Area:Aspect"   "Area:Slope"    "Area:Snow"    
+[13] "Thick:Aspect"  "Thick:Slope"   "Thick:Snow"    "SLA:Aspect"   
+[17] "SLA:Slope"     "SLA:Snow"      "N_mass:Aspect" "N_mass:Slope" 
+[21] "N_mass:Snow"   "Seed:Aspect"   "Seed:Slope"    "Seed:Snow"    
+
+
+

Because we have abundance data, let’s run the GLM using the poisson model (log link function) and the negative binomial which may work better when data are overdispersed (e.g., too many zeros, i.e., absences).

+
+
Dist.stacked <- as.vector(as.matrix(aravo$spe))
+ColNames <- colnames(TE)
+TE <- scale(TE) # so that slopes can be compared directly to one another
+colnames(TE) <- ColNames
+model.bilinear.poisson <- glm(Dist.stacked ~ TE,family="poisson")
+library(MASS)
+model.bilinear.negBinom <- glm.nb(Dist.stacked  ~ TE)
+
+

Let’s compare the two models:

+
+
c(BIC(model.bilinear.poisson),BIC(model.bilinear.negBinom))
+
+
[1] 9310.771 8784.627
+
+
+

The BIC suggests that negative binomial fits the data better (smaller BIC, better fit).

+

Model diagnostics for non-Gaussian models are challenging and often standard tools don’t provide a good way to assess quality of models. Let’s check model residuals using the more classic approach. sppVec below will be used to create a different color for each species.

+
+
# create a vector of species names compatible with the stacked model:
+sppVec = rep(row.names(aravo$traits),each=nrow(aravo$spe))
+plot(residuals(model.bilinear.negBinom),log(fitted(model.bilinear.negBinom)),col=as.numeric(factor(sppVec)),xlab="Fitted values [log scale]",ylab="residuals")
+
+

+
+
+

As we can see, the plot is pretty bad; and that’s a common feature for GLMs.

+

Dunn and Smyth (1996) developed a new class of residuals that allows a much better way to diagnose whether the model fits the data well. The package DHARMa implements the approach. A tutorial for this package and the package features can be found at: <a href = “https://cran.r-project.org/web/packages/DHARMa/vignettes/DHARMa.html”https://cran.r-project.org/web/packages/DHARMa/vignettes/DHARMa.html.

+
+
# install.packages("DHARMa")
+library("DHARMa")
+
+
This is DHARMa 0.4.6. For overview type '?DHARMa'. For recent changes, type news(package = 'DHARMa')
+
+
DunnSmyth.res <- simulateResiduals(fittedModel = model.bilinear.negBinom, plot = F)
+plot(DunnSmyth.res$scaledResiduals~log(fitted(model.bilinear.negBinom)),col=as.numeric(factor(sppVec)),xlab="Fitted values [log scale]",ylab="residuals")
+
+

+
+
+

And now the Q-Q plot to assess residual normality:

+
+
plotQQunif(DunnSmyth.res)
+
+

+
+
+

Just for illustration, let’s compare it with the Q-Q plot for the poisson model which had smaller support:

+
+
DunnSmyth.res.poisson <- simulateResiduals(fittedModel = model.bilinear.poisson, plot = F)
+plotQQunif(DunnSmyth.res.poisson)
+
+
DHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details
+
+
+

+
+
+

The poisson model doesn’t fit as well the expected line as the negative binomial model. As such, the negative binomial model fits better also with the assumption of normality.

+

We can use the package jtools to create model summaries and visualization for GLMs. You can find a good introduction to this package here:

+

https://cran.r-project.org/web/packages/jtools/vignettes/summ.html

+
+
# install.packages("jtools")
+# install.packages("ggstance")
+# install.packages("broom.mixed")
+library(jtools)
+summ(model.bilinear.negBinom)
+
+
Error in glm.control(...) : 
+  unused argument (family = list("Negative Binomial(0.5278)", "log", function (mu) 
+log(mu), function (eta) 
+pmax(exp(eta), .Machine$double.eps), function (mu) 
+mu + mu^2/.Theta, function (y, mu, wt) 
+2 * wt * (y * log(pmax(1, y)/mu) - (y + .Theta) * log((y + .Theta)/(mu + .Theta))), function (y, n, mu, wt, dev) 
+{
+    term <- (y + .Theta) * log(mu + .Theta) - y * log(mu) + lgamma(y + 1) - .Theta * log(.Theta) + lgamma(.Theta) - lgamma(.Theta + y)
+    2 * sum(term * wt)
+}, function (eta) 
+pmax(exp(eta), .Machine$double.eps), expression({
+    if (any(y < 0)) stop("negative values not allowed for the negative binomial family")
+    n <- rep(1, nobs)
+    mustart <- y + (y == 0)/6
+}), function (mu) 
+all(mu > 0), function (eta) 
+TRUE, function (object, nsim) 
+{
+    ftd <- fitted(object)
+    rnegbin(nsim * length(ftd), ftd, .Theta)
+}))
+
+
+
Warning: Something went wrong when calculating the pseudo R-squared. Returning NA
+instead.
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Observations 6150
Dependent variable Dist.stacked
Type Generalized linear model
Family Negative Binomial(0.5278)
Link log
+ + + + + + + + + + + + + + + + + + + + + + +
𝛘²(NA) NA
Pseudo-R² (Cragg-Uhler) NA
Pseudo-R² (McFadden) NA
AIC 8609.80
BIC 8784.63
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Est. S.E. z val. p
(Intercept) -1.27 0.03 -40.67 0.00
TEHeight:Aspect 0.09 0.11 0.81 0.42
TEHeight:Slope 0.08 0.05 1.56 0.12
TEHeight:Snow -0.07 0.11 -0.69 0.49
TESpread:Aspect 0.06 0.10 0.56 0.58
TESpread:Slope 0.07 0.06 1.18 0.24
TESpread:Snow -0.38 0.10 -3.82 0.00
TEAngle:Aspect 0.05 0.11 0.50 0.62
TEAngle:Slope 0.21 0.07 2.99 0.00
TEAngle:Snow -0.35 0.10 -3.52 0.00
TEArea:Aspect 0.05 0.12 0.36 0.72
TEArea:Slope 0.01 0.06 0.16 0.87
TEArea:Snow -0.24 0.12 -1.90 0.06
TEThick:Aspect -0.01 0.09 -0.09 0.93
TEThick:Slope 0.10 0.05 2.09 0.04
TEThick:Snow -0.17 0.09 -1.91 0.06
TESLA:Aspect 0.45 0.19 2.43 0.02
TESLA:Slope -0.31 0.14 -2.19 0.03
TESLA:Snow -0.42 0.15 -2.81 0.00
TEN_mass:Aspect -0.60 0.19 -3.10 0.00
TEN_mass:Slope -0.06 0.15 -0.38 0.70
TEN_mass:Snow 0.67 0.15 4.54 0.00
TESeed:Aspect 0.30 0.11 2.80 0.01
TESeed:Slope 0.11 0.05 2.21 0.03
TESeed:Snow -0.50 0.11 -4.39 0.00
+ Standard errors: MLE
+
+
+

The package jtools offers a variety of table and graphical outputs and is worth exploring. Here we will produce a confidence interval plot for each slope. This will take a moment (one minute or less):

+
+
plot_summs(model.bilinear.negBinom, scale = TRUE)
+
+
Error in glm.control(...) : 
+  unused argument (family = list("Negative Binomial(0.5278)", "log", function (mu) 
+log(mu), function (eta) 
+pmax(exp(eta), .Machine$double.eps), function (mu) 
+mu + mu^2/.Theta, function (y, mu, wt) 
+2 * wt * (y * log(pmax(1, y)/mu) - (y + .Theta) * log((y + .Theta)/(mu + .Theta))), function (y, n, mu, wt, dev) 
+{
+    term <- (y + .Theta) * log(mu + .Theta) - y * log(mu) + lgamma(y + 1) - .Theta * log(.Theta) + lgamma(.Theta) - lgamma(.Theta + y)
+    2 * sum(term * wt)
+}, function (eta) 
+pmax(exp(eta), .Machine$double.eps), expression({
+    if (any(y < 0)) stop("negative values not allowed for the negative binomial family")
+    n <- rep(1, nobs)
+    mustart <- y + (y == 0)/6
+}), function (mu) 
+all(mu > 0), function (eta) 
+TRUE, function (object, nsim) 
+{
+    ftd <- fitted(object)
+    rnegbin(nsim * length(ftd), ftd, .Theta)
+}))
+
+
+
Warning: Something went wrong when calculating the pseudo R-squared. Returning NA
+instead.
+
+
+
Registered S3 methods overwritten by 'broom':
+  method            from  
+  tidy.glht         jtools
+  tidy.summary.glht jtools
+
+
+
Loading required namespace: broom.mixed
+
+
+

+
+
+

One needs to be careful when interpreting these confidence intervals as they were produced parametrically and they may be biased as we discussed in the section on statistical hypothesis testing. Again, this is a strong area of development among quantitative ecologists; but we haven’t yet derived unified views on this issue.

+

We can also plot the coefficients building:

+
+
cf <- coefficients(model.bilinear.negBinom)[-1] # removes the intercept
+cfInter <- matrix(t(cf),nrow=ncol(E))
+colnames(cfInter) <- colnames(T)
+rownames(cfInter) <- colnames(E)
+cfInter
+
+
            Height      Spread       Angle        Area        Thick        SLA
+Aspect  0.08562528  0.05659044  0.05406318  0.04512061 -0.008000594  0.4512878
+Slope   0.08477186  0.06555292  0.20518548  0.01057746  0.101762893 -0.3083102
+Snow   -0.07428183 -0.37726596 -0.35230429 -0.23652105 -0.174573655 -0.4210057
+            N_mass       Seed
+Aspect -0.59525146  0.2977853
+Slope  -0.05644061  0.1137532
+Snow    0.67458707 -0.5011741
+
+
# install.packages("lattice")
+library(lattice)
+a <- max(abs(cfInter))
+colort = colorRampPalette(c("blue","white","red"))
+levelplot(cfInter, xlab="traits",ylab="environment", col.regions=colort(100), at=seq(-a, a, length=100))
+
+

+
+
+
+ +
+Considering main effects of trait and environment, and their interactions - predicting and explaining species distributions +
+

The bilinear model estimates and test for the interactions between traits and environmental features in a single model. That allows for partial slopes to be estimated (i.e., in which the effects of one trait-environment interaction is independent of the others as in standard linear regression models and GLMs). Understanding partial slopes is essential for inference and usually covered in Intro statistics for biologists/ecologists under multiple regression. A standard definition is “The partial slope in multiple regression (or GLM) is the slope of the relationship between a predictor variable that is independent of the other predictor variables and the criterion. It is also the regression coefficient for the predictor variable in question.” (https://onlinestatbook.com/2/glossary/partial_slope.html).

+

Now, we may want to consider also the main effects of each environmental feature and traits in addition to their interactions. This is the model implemented in Jamil et al. (2013) and Brown et al. (2014). The Brown model et al. model is:

+

\[{ln(Y_{ij}) = \beta_0\ +\beta_1env_i\ +\beta_2env_i^2\ +\beta_3spp_j\ +\beta_4(env \times\ trait)_{ij}\ }\] where \(\beta_0\) is the overall intercept for the model, \(\beta_1env_i\) contains the slopes for each environmental variable, the model also consider square terms for the environmental variables \(\beta_2env_i^2\), \(\beta_3spp_j\) contains species-specific intercept terms which allows predictions for each species separately, \(\beta_4(env \times\ trait)_{ij}\) contains the slopes for each trait by environment interaction (the 4th corner slopes). Whereas Brown et al. treated \(spp_j\) as fixed, Jamil et al. (2013) treated as random (more on this later). I’ve followed the formulation notation given in Brown et al. to facilitate understanding their paper; but we could easily change by the notation used in the mixed model selection (following Gelman and Hill 2007).

+

By setting species-specific intercept terms (i.e., \(\beta_3spp_j\)) we can predict species in their appropriate scale of abundance variation. As such, we can use these types of models to predict species distributions. This sort of modelling is becoming the standard for predicting multiple species because it considers multiple types of predictors (trait, environments, non-linearities) and their interactions. Single species models, for instance, can’t consider trait variation and the interactions of traits and environment. As such, stacked models are extremely powerful tools even for modelling single species distributions.

+

The Brown et al. model can be fit using the package mvabund as follows:

+
+
# install.packages("mvabund")
+library(mvabund)
+glm.trait.res <- traitglm(as.matrix(aravo$spe),E,T,family="negative.binomial",col.intercepts=TRUE)
+BIC(glm.trait.res)
+
+
       l 
+8104.818 
+
+
+

All coefficients of the model can be retrieved by:

+
+
coefficients(glm.trait.res)
+
+
                         l
+(Intercept)   -1.939671753
+sppAlch.glau  -0.054831143
+sppAlch.pent   0.024330521
+sppAlch.vulg  -0.155929316
+sppAlop.alpi   0.069840352
+sppAndr.brig  -0.144086942
+sppAndr.vita  -0.117405506
+sppAnte.carp  -0.105193294
+sppAnte.dioi  -0.259135963
+sppAnth.alpe  -0.404567216
+sppAnth.nipp  -0.069393787
+sppArni.mont  -0.265964212
+sppAste.alpi  -0.324558310
+sppAven.vers  -0.108786793
+sppBart.alpi  -0.332898371
+sppCamp.sche  -0.008108304
+sppCard.alpi  -0.136528887
+sppCare.foet   0.027908430
+sppCare.parv  -0.174556575
+sppCare.rosa  -0.091371379
+sppCare.rupe  -0.182772040
+sppCare.semp  -0.112095430
+sppCera.cera  -0.171760014
+sppCera.stri  -0.021497460
+sppCirs.acau  -0.188888639
+sppDrab.aizo  -0.118690070
+sppDrya.octo  -0.358279264
+sppErig.unif  -0.059293913
+sppFest.laev  -0.365739677
+sppFest.quad  -0.105113832
+sppFest.viol  -0.058339848
+sppGent.acau  -0.181050369
+sppGent.camp  -0.134520188
+sppGent.vern  -0.044346876
+sppGeum.mont   0.064963289
+sppHeli.sede  -0.217416821
+sppHier.pili  -0.138692435
+sppHomo.alpi  -0.207003373
+sppKobr.myos  -0.028361647
+sppLeon.pyre   0.029558348
+sppLeuc.alpi  -0.003570705
+sppLigu.muto  -0.064014046
+sppLloy.sero  -0.284035626
+sppLotu.alpi  -0.144194010
+sppLuzu.lute  -0.193109208
+sppMinu.sedo   0.021602219
+sppMinu.vern  -0.137286811
+sppMyos.alpe  -0.092884602
+sppOmal.supi   0.033812911
+sppOxyt.camp  -0.233480701
+sppOxyt.lapp  -0.201732614
+sppPhyt.orbi  -0.327727501
+sppPlan.alpi   0.066971460
+sppPoa.alpi    0.095801892
+sppPoa.supi   -0.203286074
+sppPoly.vivi  -0.016324658
+sppPote.aure   0.053779431
+sppPote.cran  -0.126165407
+sppPote.gran  -0.231501706
+sppPuls.vern  -0.096096734
+sppRanu.kuep  -0.020389979
+sppSagi.glab  -0.011366535
+sppSali.herb   0.053863437
+sppSali.reti  -0.286340876
+sppSali.retu  -0.255645078
+sppSali.serp  -0.283448058
+sppSaxi.pani  -0.185168997
+sppScab.luci  -0.331712183
+sppSedu.alpe  -0.065750719
+sppSemp.mont  -0.074418068
+sppSene.inca  -0.162375900
+sppSesl.caer  -0.205203677
+sppSibb.proc   0.019139245
+sppSile.acau  -0.179836450
+sppTara.alpi  -0.250167730
+sppThym.poly  -0.280189375
+sppTrif.alpi  -0.134717635
+sppTrif.badi  -0.322563479
+sppTrif.thal  -0.225527793
+sppVero.alli  -0.293989557
+sppVero.alpi  -0.100779079
+sppVero.bell  -0.011889063
+Aspect         0.014997588
+Slope          0.064347175
+Snow          -0.303043451
+Aspect.squ     0.013997280
+Slope.squ     -0.047627887
+Snow.squ      -0.274070121
+Aspect.Height -0.010645817
+Aspect.Spread -0.070752741
+Aspect.Angle  -0.083977548
+Aspect.Area   -0.040276747
+Aspect.Thick  -0.082064700
+Aspect.SLA     0.065782084
+Aspect.N_mass -0.138709436
+Aspect.Seed    0.042758169
+Slope.Height  -0.020464655
+Slope.Spread   0.023128427
+Slope.Angle   -0.018699260
+Slope.Area    -0.027960323
+Slope.Thick   -0.012369639
+Slope.SLA     -0.108694248
+Slope.N_mass   0.021179434
+Slope.Seed     0.014142823
+Snow.Height   -0.209648151
+Snow.Spread    0.049505713
+Snow.Angle    -0.188496204
+Snow.Area     -0.046298194
+Snow.Thick     0.099956790
+Snow.SLA       0.309130472
+Snow.N_mass    0.317287032
+Snow.Seed     -0.169753499
+
+
+

The overall intercept \(\beta_0=-1.9397\), the individual intercept for each species \(\beta_3spp_j\) are the coefficients above starting with spp; for instance, the individual slope for Alch.glau (1st species in the list) is \(\beta_3spp_1=-0.055\). The slopes for each environmental variable appear under the names we gave. For instance, the slope for aspect is \(\beta_1env_aspect=0.015\). Note that .squ in the coefficients are the slopes for the squared environmental terms; for instance \(\beta_2env_{snow}^2=-0.274\). Finally we have the 4th corner slopes. For instance, \(\beta_4(env \times\ trait)_{snow,seed\_mass}=-0.1698\). Remember that snow here refers to the mean snowmelt date. As such, communities with large seed masses (in average) are found in sites that have early snowmelt dates compared to sites with late snowmelt dates; these sites have communities that tend to have small seed masses in average.

+

Let’s understand this model by programming it from scratch. That’s really the best way to understand models; and whenever possible I try to demonstrate them from ‘scratch’; not always possible depending on the amount of operations (e.g., mixed models) and our abilities to understand large codes . But this one is simple enough that we can do it:

+
+
n.species <- ncol(aravo$spe)
+n.communities <- nrow(aravo$spe)
+n.env.variables <- ncol(E)
+# repeats each trait to make it compatible (vectorized) with the stacked species distributions
+traitVec <- T[rep(1:n.species,each=n.communities),]
+# repeats each environmental variable to make it compatible  (vectorized) with the stacked species distributions:
+envVec <- matrix(rep(t(E),n.species),ncol=NCOL(E),byrow=TRUE)
+# creates an intercept for each species:
+species.intercepts <- rep(1:n.species,each=n.communities)
+species.intercepts <- as.factor(species.intercepts)
+mod <- as.formula("~species.intercepts-1")
+species.intercepts <- model.matrix(mod)[,-1]
+# the interaction terms:
+TE <- kronecker(T, E, make.dimnames = TRUE)
+# combining the predictors in a single matrix:
+preds <- cbind(species.intercepts,envVec,envVec^2,TE)
+# running the model
+model.bilinear.negBinom.Brown <- glm.nb(Dist.stacked  ~ preds)
+
+

And as we can see, they are exactly the same model:

+
+
BIC(glm.trait.res)
+
+
       l 
+8104.818 
+
+
BIC(model.bilinear.negBinom.Brown)
+
+
[1] 8104.818
+
+
+

We can easily adapt the graphical and diagnostic outputs for this model as well, but we won’t for simplicity.

+
+
summ(model.bilinear.negBinom)
+
+
Error in glm.control(...) : 
+  unused argument (family = list("Negative Binomial(0.5278)", "log", function (mu) 
+log(mu), function (eta) 
+pmax(exp(eta), .Machine$double.eps), function (mu) 
+mu + mu^2/.Theta, function (y, mu, wt) 
+2 * wt * (y * log(pmax(1, y)/mu) - (y + .Theta) * log((y + .Theta)/(mu + .Theta))), function (y, n, mu, wt, dev) 
+{
+    term <- (y + .Theta) * log(mu + .Theta) - y * log(mu) + lgamma(y + 1) - .Theta * log(.Theta) + lgamma(.Theta) - lgamma(.Theta + y)
+    2 * sum(term * wt)
+}, function (eta) 
+pmax(exp(eta), .Machine$double.eps), expression({
+    if (any(y < 0)) stop("negative values not allowed for the negative binomial family")
+    n <- rep(1, nobs)
+    mustart <- y + (y == 0)/6
+}), function (mu) 
+all(mu > 0), function (eta) 
+TRUE, function (object, nsim) 
+{
+    ftd <- fitted(object)
+    rnegbin(nsim * length(ftd), ftd, .Theta)
+}))
+
+
+
Warning: Something went wrong when calculating the pseudo R-squared. Returning NA
+instead.
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Observations 6150
Dependent variable Dist.stacked
Type Generalized linear model
Family Negative Binomial(0.5278)
Link log
+ + + + + + + + + + + + + + + + + + + + + + +
𝛘²(NA) NA
Pseudo-R² (Cragg-Uhler) NA
Pseudo-R² (McFadden) NA
AIC 8609.80
BIC 8784.63
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Est. S.E. z val. p
(Intercept) -1.27 0.03 -40.67 0.00
TEHeight:Aspect 0.09 0.11 0.81 0.42
TEHeight:Slope 0.08 0.05 1.56 0.12
TEHeight:Snow -0.07 0.11 -0.69 0.49
TESpread:Aspect 0.06 0.10 0.56 0.58
TESpread:Slope 0.07 0.06 1.18 0.24
TESpread:Snow -0.38 0.10 -3.82 0.00
TEAngle:Aspect 0.05 0.11 0.50 0.62
TEAngle:Slope 0.21 0.07 2.99 0.00
TEAngle:Snow -0.35 0.10 -3.52 0.00
TEArea:Aspect 0.05 0.12 0.36 0.72
TEArea:Slope 0.01 0.06 0.16 0.87
TEArea:Snow -0.24 0.12 -1.90 0.06
TEThick:Aspect -0.01 0.09 -0.09 0.93
TEThick:Slope 0.10 0.05 2.09 0.04
TEThick:Snow -0.17 0.09 -1.91 0.06
TESLA:Aspect 0.45 0.19 2.43 0.02
TESLA:Slope -0.31 0.14 -2.19 0.03
TESLA:Snow -0.42 0.15 -2.81 0.00
TEN_mass:Aspect -0.60 0.19 -3.10 0.00
TEN_mass:Slope -0.06 0.15 -0.38 0.70
TEN_mass:Snow 0.67 0.15 4.54 0.00
TESeed:Aspect 0.30 0.11 2.80 0.01
TESeed:Slope 0.11 0.05 2.21 0.03
TESeed:Snow -0.50 0.11 -4.39 0.00
+ Standard errors: MLE
+
+
+

As mentioned earlier, we can get predicted models per species, making stacked models not only a community model but also considering information from multiple sources for single species distributions as well:

+
+
fitted.by.species <- matrix(glm.trait.res$fitted,n.communities,n.species)
+
+

Predicted abundance values per species are in columns:

+
View(fitted.by.species)
+
+ +
+A very brief way to understand mixed models: the Simpson’s paradox +
+

Species and sites are not likely to differ from one another randomly but rather have some sites more similar to others (or more different). We call this a hierarchical structure. For instance, sites that are more close to one another may have more similar values than sites further way. Or some species may be more similar in abundance than others, and so on.

+

When using linear models and GLMS, researchers often ignore the hierarchical structure of the data (some sites have more similar or differences in total abundances of species, some species have more similar or differences in their total abundances). As such, standard GLMs can generate biased variance estimates and increase the likelihood of committing type I errors (i.e., rejecting the statistical null hypothesis more often than set by alpha, i.e., significance level).

+

Although this is very interesting ecologically, it does bring some inferential challenges (parameter estimation and statistical hypothesis testing) when fitting statistical models. GLMM (Generalized Linear Mixed Models) are then used to deal with these issues. This paper by Harrison et al. (2018) provides a great Introduction to GLLMs for ecologists: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5970551/.

+

One common feature here is that species may differ in the way they are structured by environmental and/or trait variation. This can be well described by the Simpson’s paradox (Simpson 1951), which is defined “as a phenomenon in probability and statistics in which a trend appears in several groups of data but disappears or reverses when the groups are combined.”

+

Let’s understand this paradox by simulating some data (code not show here) and graphing it. This sort of demonstration has become somewhat common when explaining the utility of mixed model.

+
+ +
+
+
+

+
+
+

At first glance, the influence of temperature on abundance is positive if we consider the variation across all data points independent of the sites. However, within species, the influence of the environment is negative. As such, it is obvious that there is variation among species that can’t be explained by temperature alone. As such, we should consider a mixed model with temperature as a fixed factor (measured variable) and species as a random factor. Obviously one question of interest is why do species vary in their effects of temperature. But we don’t have other predictors that could assist in explaining these differences (e.g., physiology). Perhaps considering traits could assist in determining this variation (more on that later).

+

The data was saved in a matrix called data.Simpson. For simplicity, we will treat these data as normally distributed. The data were generated assuming normality any way; the goal here is just a demonstration.

+

Let’s analyze these data with a fixed model using a simple regression:

+
+
library(jtools)
+lm.mod <- lm(abundance ~ scale(temperature),data=data.Simpson)
+summ(lm.mod,scale = TRUE)
+
+ + + + + + + + + + + + + + + + +
Observations 100
Dependent variable abundance
Type OLS linear regression
+ + + + + + + + + + + + + + +
F(1,98) 15.13
0.13
Adj. R² 0.12
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Est. S.E. t val. p
(Intercept) -0.08 0.18 -0.48 0.63
`scale(temperature)` 0.69 0.18 3.89 0.00
+ Standard errors: OLS; Continuous predictors are mean-centered and scaled by 1 s.d.
+
+
+

As we can see, the overal influence of temperature is positive and significant, explaining 12% of the variation in abundance as a function of temperature (i.e., \(R^2=0.12\)).

+

Let’s consider now a mixed effect model that we estimate the variation in intercepts but still assume a common slope for all species. This is a common procedure in mixed model effects, i.e., starting with the simplest model. This fixed effect is coded as usually and the random effect is coded as (1|species), where 1 means the intercepts (common way to code the intercept in statistical models). As such, one intercept per species is estimated. The scale=TRUE in the function summ below reports the analysis with standardized predictors.

+
+
# install.packages("lme4")
+library(lme4)
+
+
Loading required package: Matrix
+
+
+

+Attaching package: 'Matrix'
+
+
+
The following objects are masked from 'package:tidyr':
+
+    expand, pack, unpack
+
+
lm.mod.intercept <- lmer(abundance ~ temperature + (1|species),data=data.Simpson)
+summ(lm.mod.intercept,scale = TRUE)
+
+ + + + + + + + + + + + + + + + +
Observations 100
Dependent variable abundance
Type Mixed effects linear regression
+ + + + + + + + + + + + + + + + + + +
AIC 343.74
BIC 354.16
Pseudo-R² (fixed effects) 0.30
Pseudo-R² (total) 0.95
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Fixed Effects
Est. S.E. t val. d.f. p
(Intercept) -0.08 1.88 -0.04 3.94 0.97
temperature -2.84 0.35 -8.10 97.70 0.00
+ p values calculated using Kenward-Roger standard errors and d.f. ; Continuous predictors are mean-centered and scaled by 1 s.d.
+ + + + + + + + + + + + + + + + + + + + +
Random Effects
Group Parameter Std. Dev.
species (Intercept) 4.20
Residual 1.16
+ + + + + + + + + + + + + + + +
Grouping Variables
Group # groups ICC
species 5 0.93
+
+
+

Wow, what a change in the interpretation. By considering variation in intercepts across species, the fixed effect influence of temperature is now negative (as we should expect). Note, however, that we had information on a categorical factor, i.e, species, that could be used to estimate random effects related to variation among them. The variation (standard deviation) of intercepts among species is quite large in contrast to residuals; 4.20 against 1.16, respectively. The explanatory power of variation among intercepts make the \(R^2=0.95\) increase dramatically in contrast to the fixed model, demonstrating that the species random effect has a huge effect and ability to improve the model predictive power. We also find the ICC (Intra Class Correlation) which measures how similar the abundance is within groups, i.e., species. The ICC is 0.93, indicating that abundance values are more similar within than among species.
+The variation in intercepts can be plotted as follows:

+
+
library(ggplot2)
+intercepts <- coefficients(lm.mod.intercept)$species[,"(Intercept)"]
+slopes <- coefficients(lm.mod.intercept)$species[,"temperature"]
+lines <- data.frame(intercepts,slopes)
+lines["species"] <-  unique(data.Simpson[,"species"])
+data.Simpson$pred <- predict(lm.mod.intercept)
+ggplot() +
+geom_point(data=data.Simpson,aes(x=temperature,y=abundance,color=species),size=1) + 
+geom_abline(aes(intercept = `(Intercept)`, slope = temperature),size = 1.5,as.data.frame(t(fixef(lm.mod.intercept)))) +
+geom_abline(data = lines, aes(intercept=intercepts, slope=slopes, color=species)) +
+theme_classic() + 
+xlab("Temperature") + ylab("log(Abundance)")
+
+
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
+ℹ Please use `linewidth` instead.
+
+
+

+
+
+

The black line represents the common model. Since only intercepts were allowed to vary, the species per slope are the same as the fixed model (after controlling for variation across species, which made the overall slope to be negative).
+Finally, let’s estimate the random intercept and slope model. Here we estimate variation due to differences in intercepts and slopes across species:

+
+
lm.mod.interceptSlope <- lmer(abundance ~ temperature + (1 + temperature|species),data=data.Simpson)
+summ(lm.mod.interceptSlope,scale = TRUE)
+
+ + + + + + + + + + + + + + + + +
Observations 100
Dependent variable abundance
Type Mixed effects linear regression
+ + + + + + + + + + + + + + + + + + +
AIC 336.10
BIC 351.73
Pseudo-R² (fixed effects) 0.31
Pseudo-R² (total) 0.96
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Fixed Effects
Est. S.E. t val. d.f. p
(Intercept) 0.11 1.75 0.06 3.99 0.95
temperature -2.91 0.84 -3.45 3.98 0.03
+ p values calculated using Kenward-Roger standard errors and d.f. ; Continuous predictors are mean-centered and scaled by 1 s.d.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Random Effects
Group Parameter Std. Dev.
species (Intercept) 3.84
species temperature 1.73
Residual 1.05
+ + + + + + + + + + + + + + + +
Grouping Variables
Group # groups ICC
species 5 0.93
+
+
+

The variation (standard deviation) in intercepts across species in much larger (3.84) than slopes (1.73). Is the predictive power between the two models significant? In order words, does a model that estimate independent slopes for each species explain more variation than one that only considers variation in intercepts? We can simply compare the BIC of both models:

+
+
c(BIC(lm.mod),BIC(lm.mod.intercept),BIC(lm.mod.interceptSlope))
+
+
[1] 408.7963 356.1764 353.7488
+
+
+

There is more support for the mixed model that considers variation in intercepts and slopes. One can also estimate the p-value that one model fits better than the other:

+
+
anova(lm.mod.intercept,lm.mod.interceptSlope)
+
+
refitting model(s) with ML (instead of REML)
+
+
+
Data: data.Simpson
+Models:
+lm.mod.intercept: abundance ~ temperature + (1 | species)
+lm.mod.interceptSlope: abundance ~ temperature + (1 + temperature | species)
+                      npar    AIC    BIC  logLik deviance  Chisq Df Pr(>Chisq)
+lm.mod.intercept         4 346.41 356.83 -169.21   338.41                     
+lm.mod.interceptSlope    6 340.30 355.93 -164.15   328.30 10.114  2   0.006365
+                        
+lm.mod.intercept        
+lm.mod.interceptSlope **
+---
+Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+
+
+

Finally, we can plot the intercept and slope variation. The common fixed effect slope has been now estimated by pooling the variation among species, hence it become negative in contrast to the original fixed effect slope.

+
+
intercepts <- coefficients(lm.mod.interceptSlope)$species[,"(Intercept)"]
+slopes <- coefficients(lm.mod.interceptSlope)$species[,"temperature"]
+lines <- data.frame(intercepts,slopes)
+lines["species"] <-  unique(data.Simpson[,"species"])
+data.Simpson$pred <- predict(lm.mod.intercept)
+ggplot() +
+geom_point(data=data.Simpson,aes(x=temperature,y=abundance,color=species),size=2) + 
+geom_abline(aes(intercept = `(Intercept)`, slope = temperature),size = 2,as.data.frame(t(fixef(lm.mod.interceptSlope)))) +
+geom_abline(data = lines, aes(intercept=intercepts, slope=slopes, color=species),size = 2) +
+theme_classic() + 
+xlab("Temperature") + ylab("log(Abundance)")
+
+

+
+
+

An extreme example pf the Simpson’s paradox

+

Let’s consider (just visually) an even more extreme case. The fixed effect is very strong but the within species effect is almost zero. Hopefully the “Simpson’s” examples here provide a good intuition on the importance of mixed models.

+
+ +
+
+
+

+
+
+
+Our first GLMM applied to the fourth corner problem treating species as a random effect - the MLML1 model +
+

There are different ways that we can account for the potential random effects in community ecology data. Here we will review a few of the latest developments.

+

MLM stands for multilevel (i.e., hierarchical) models (MLM). The simplest of these models is the one introduced by Pollock et al. (2012) and is often referred in the ecological literature as MLM1 (see Miller et al. 2018). The model has the following form (following the notation of Gelman and Hill 2007; as in Miller et al. 2018). This is a model that considers species as a random effect while estimating variation in both intercepts and slopes as the last model in the previous session (Simpson’s paradox)

+

\[{ln(Y_{i}) = \alpha\ +a_{spp[i]}\ +\beta_{12}env_{site[i]}\times trait_{spp[i]} + (\beta_1+c_{spp[i]})env_{site[i]}+e_i}\] \(a,c \sim Gaussian(0,\sigma_a^2,\sigma_c^2,\rho_{ac})\) \(e \sim Gaussian(0,\sigma_e^2)\)

+

Note that we changed the notation of Brown et al. \(ij\) that served as an index for the \(i^{th}\) site and \(j^{th}\) species to simply one index \(i\) since we are using a stacked model anyway, i.e., only rows for \(Y_{i}\) and one column (i.e., stacked species distributions). As such, the functions \(spp[i]\) and \(site[i]\) map row i onto the corresponding species and sites. \(\beta_{12}\) contains the slopes for the interactions between environment and trait. The fixed effect \(\alpha\) gives the overall average abundance of species among sites (one overall intercept), and the fixed effect \(\beta_{1}\) gives the mean response of species to the different environmental variables. Random effect \(a_{spp[i]}\) allows different species to have different overall abundance (i.e., sum of abundances across species; random intercept model across species), and random effect \(c_{spp[i]}\) allows different species to have different responses to the environmental variables (i.e., random slope model across species). \(a_{spp[i]}\) and \(c_{spp[i]}\) have means zero and variances \(\sigma_a^2\) and \(\sigma_c^2\) (referred as to hyperparameters in mixed model lingo), with \(\rho_{ac}\) denoting the correlation between \(a_{spp[i]}\) and \(c_{spp[i]}\) (i.e., species intercepts and species slopes for the environment can correlate). Finally,random effect \(e_i\) gives observation-level variance; this is necessary here to allow for overdispersion (Harisson, 2014). We can also use the negative binomial as we saw earlier. Note that we are assuming hierarchical variation in variance and not covariance (e.g., phylogenetic and spatial autocorrelation). One step at the time.

+

Let’s start by setting an appropriate data structure to run the mixed model. To make the coding more manageable we will consider here only one trait and one environment. The code can be easily generalized for multiple traits and environments. We found early a strong interaction between seed mass and snow in which species with greater seed mass tended to be found in sites with small levels of snow (i.e., a negative correlation between snow and seed mass).

+

For simplicity, let’s load the aravo data again:

+
+
library(ade4)
+data(aravo)
+E <- aravo$env[,c("Aspect","Slope","Snow")]
+E <- as.matrix(E)
+T <- as.matrix(aravo$trait)
+Dist.stacked <- as.vector(as.matrix(aravo$spe))
+n.species <- ncol(aravo$spe)
+n.communities <- nrow(aravo$spe)
+n.env.variables <- ncol(E)
+
+
+
# to code for observation-level variance:
+obs <- 1:(n.species*n.communities)
+# to code for species (as we saw earlier to plot residuals):
+species <- rep(row.names(aravo$traits),each=nrow(aravo$spe))
+sites <- rep(row.names(aravo$spe),each=ncol(aravo$spe))
+# standardizing the data:
+seed.mass <- scale(T[rep(1:n.species,each=n.communities),"Seed"])
+snow.melt.days <- scale(matrix(rep(t(E[,"Snow"]),n.species),ncol=1,byrow=TRUE))
+data.df <- data.frame(abundance=Dist.stacked,snow.melt.days,seed.mass,species,sites,obs)
+
+

Let’s see the data frame:

+
View(data.df)
+

Let’s start by fitting a glm:

+
+
glm.mod <- glm(abundance ~ snow.melt.days + snow.melt.days:seed.mass,data=data.df, family = "poisson")
+summ(glm.mod,scale = TRUE)
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Observations 6150
Dependent variable abundance
Type Generalized linear model
Family poisson
Link log
+ + + + + + + + + + + + + + + + + + + + + + +
𝛘²(2) 56.18
Pseudo-R² (Cragg-Uhler) 0.01
Pseudo-R² (McFadden) 0.01
AIC 9421.91
BIC 9442.08
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Est. S.E. z val. p
(Intercept) -1.17 0.02 -50.74 0.00
snow.melt.days -0.10 0.02 -4.20 0.00
snow.melt.days:seed.mass -0.14 0.02 -6.39 0.00
+ Standard errors: MLE; Continuous predictors are mean-centered and scaled by 1 s.d.
+
+
+

Despite the very low \(R^2=0.01\), the coefficiences are all significant and negative.

+

Let’s run the model. Below, both intercepts (coded as 1) and slopes for snow.melt.days (coded as env) are allowed to vary among species (i.e., (1 + env|species)) and we also allow

+
+
MLM1.mod <- glmer(abundance ~ snow.melt.days + snow.melt.days:seed.mass + (1 + snow.melt.days|species) + (1 | obs), family = "poisson", control=glmerControl(calc.derivs=F), nAGQ = 0, data=data.df)
+summ(MLM1.mod,scale = TRUE)
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Observations 6150
Dependent variable abundance
Type Mixed effects generalized linear model
Family poisson
Link log
+ + + + + + + + + + + + + + + + + + +
AIC 7335.48
BIC 7382.55
Pseudo-R² (fixed effects) 0.09
Pseudo-R² (total) 0.65
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Fixed Effects
Est. S.E. z val. p
(Intercept) -2.12 0.17 -12.37 0.00
snow.melt.days -0.72 0.13 -5.51 0.00
snow.melt.days:seed.mass -0.08 0.09 -0.84 0.40
+ ; Continuous predictors are mean-centered and scaled by 1 s.d.
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Random Effects
Group Parameter Std. Dev.
obs (Intercept) 0.47
species (Intercept) 1.46
species snow.melt.days 1.08
+ + + + + + + + + + + + + + + + + + + + +
Grouping Variables
Group # groups ICC
obs 6150 0.07
species 82 0.63
+
+
+

The variation among observations (residuals) is not relevant here; we used it to allow for potential overdispersion in abundance (i.e., variance of abundance much greater than the mean). Note that both the intercept and slopes contribute more or less to the same amount of variation (intercept sd=1.46 and slopes = 1.08), indicating that an intercept and slope mixed model is the most appropriate model. We could have fit the two models and tested as before we saw early in the Simpson’s paradox section. Note the huge increase in \(R^2=0.65\), demonstrating that considering a random structure is much better. The coefficient of snow.melt.days remains negative indicating that most species and their variation are negative despite the potential for some species to increase their abundances for large values of snow.melt.days. We will see this below.

+

The residual against the predicted values provide a good indication that the model is appropriate:

+
+
library(DHARMa)
+DunnSmyth.res <- simulateResiduals(fittedModel = MLM1.mod, plot = F)
+plot(DunnSmyth.res$scaledResiduals~log(fitted(MLM1.mod)),col=as.numeric(factor(species)),xlab="Fitted values [log scale]",ylab="residuals")
+
+

+
+
+

And now the Q-Q plot to assess residual normality:

+
+
plotQQunif(DunnSmyth.res)
+
+
DHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details
+
+
+

+
+
+

Note that the Kolmogorov-Smirnov (KS) provides indication that the residuals cannot be assumed to be normal. That said, the distribution of residuals looks somewhat on the expected. The KS becomes quite significant because of the large number of data points. Finally, GLMs and GLMMs tend to be quite robust even when residuals are not normal.

+

Intercepts in a poisson model are log of species abundances not explained by the predictors model, i.e., when we set them “manually” to take values of zero. Perhaps some sites are more productive than others and we did not measure trait or environmental variables that could account for the slope and intercept variation variation; but the random effects is telling us that there is something we are potentially missing to explain their variation.

+

Moreover, the random effect indicates that species slopes for the environment are strongly and positively correlated with the species intercepts (\(\rho_{ac}=0.73\)). We can plot the intercepts against slopes:

+
+
plot(coefficients(MLM1.mod)$species[,"(Intercept)"],coefficients(MLM1.mod)$species[,"snow.melt.days"],xlab="species intercepts", ylab="species environmental slopes")
+
+

+
+
+

\(\rho_{ac}\) does not appear in summ(MLM1.mod) but can be found in summary(MLM1.mod) intead or calculated directly:

+
+
summary(MLM1.mod)
+
+
Generalized linear mixed model fit by maximum likelihood (Adaptive
+  Gauss-Hermite Quadrature, nAGQ = 0) [glmerMod]
+ Family: poisson  ( log )
+Formula: abundance ~ snow.melt.days + snow.melt.days:seed.mass + (1 +  
+    snow.melt.days | species) + (1 | obs)
+   Data: data.df
+Control: glmerControl(calc.derivs = F)
+
+     AIC      BIC   logLik deviance df.resid 
+  7335.5   7382.6  -3660.7   7321.5     6143 
+
+Scaled residuals: 
+    Min      1Q  Median      3Q     Max 
+-1.6289 -0.4400 -0.2650 -0.0639  7.6016 
+
+Random effects:
+ Groups  Name           Variance Std.Dev. Corr
+ obs     (Intercept)    0.2221   0.4712       
+ species (Intercept)    2.1201   1.4560       
+         snow.melt.days 1.1671   1.0803   0.73
+Number of obs: 6150, groups:  obs, 6150; species, 82
+
+Fixed effects:
+                         Estimate Std. Error z value Pr(>|z|)    
+(Intercept)              -2.11504    0.17095 -12.372  < 2e-16 ***
+snow.melt.days           -0.71798    0.13037  -5.507 3.64e-08 ***
+snow.melt.days:seed.mass -0.07552    0.09024  -0.837    0.403    
+---
+Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+
+Correlation of Fixed Effects:
+            (Intr) snw.m.
+snw.mlt.dys 0.730        
+snw.mlt.d:. 0.010  0.015 
+
+
cor(coefficients(MLM1.mod)$species[,"(Intercept)"],coefficients(MLM1.mod)$species[,"snow.melt.days"])
+
+
[1] 0.7163168
+
+
+

Although the fixed-only effect model run earlier (glm.mod) indicated a significant correlation between snowmelt date and seed mass in driving species distributions, this effect is no longer relevant once the random effects are considered:

+
+
summary(glm.mod)
+
+

+Call:
+glm(formula = abundance ~ snow.melt.days + snow.melt.days:seed.mass, 
+    family = "poisson", data = data.df)
+
+Deviance Residuals: 
+    Min       1Q   Median       3Q      Max  
+-1.2804  -0.7946  -0.7868  -0.6822   4.3659  
+
+Coefficients:
+                         Estimate Std. Error z value Pr(>|z|)    
+(Intercept)              -1.16767    0.02301 -50.744  < 2e-16 ***
+snow.melt.days           -0.09714    0.02313  -4.199 2.68e-05 ***
+snow.melt.days:seed.mass -0.14286    0.02237  -6.387 1.70e-10 ***
+---
+Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+
+(Dispersion parameter for poisson family taken to be 1)
+
+    Null deviance: 6552.0  on 6149  degrees of freedom
+Residual deviance: 6495.8  on 6147  degrees of freedom
+AIC: 9421.9
+
+Number of Fisher Scoring iterations: 6
+
+
+

This indicates that the random variation across species can account for the initial relationship between snow.melt.days and seed mass. Note that the importance of snow.melt.days remains relevant in driving species abundances across sites, but (again) not its interaction with seed mass.

+

Let’s plot regression models per species:

+
+
intercepts <- coefficients(MLM1.mod)$species[,"(Intercept)"]
+slopes <- coefficients(MLM1.mod)$species[,"snow.melt.days"]
+lines <- data.frame(intercepts,slopes)
+lines["species"] <-  unique(data.df[,"species"])
+data.df$pred <- predict(MLM1.mod)
+ggplot(data=data.df) +
+geom_point(data=data.df,aes(x=snow.melt.days,y=pred,color=species),size=1) + 
+geom_abline(data = lines, aes(intercept=intercepts, slope=slopes, color=species),size = 2) +
+geom_abline(aes(intercept = `(Intercept)`, slope = snow.melt.days),size = 2,as.data.frame(t(fixef(MLM1.mod)))) +
+theme_classic() + 
+xlab("snow.melt.days") + ylab("log(Abundance)")
+
+

+
+
+

Finally, the GLMM has good predictive power (relative smaller confidence intervals and large \(R^2=0.51\):

+
+
# install.packages("ggeffects")
+library(ggeffects)
+plot(ggpredict(MLM1.mod, "snow.melt.days"))
+
+

+
+
+

Finally, as we discussed during the workshop, one needs to be careful while interpreting the significance of interactions between trait and environment. There are bootstrap-based developments to do that for the MLML1 model but they have been show to have inflated type I errors (Miller et al. 2019).

+

Function glmer.nb could have been used to fit the model using the negative binomial family instead.

+

Here is a good and simple introduction to mixed models for poisson regression:
+https://stats.idre.ucla.edu/r/faq/random-coefficient-poisson-models/

+
+Our second GLMM applied to the fourth corner problem treating species and sites as random effects - the MLML2 model +
+

Jamil et al. (2013) implemented a mixed model version in which in contrast to MLM1, it adds a fixed effect term for traits is included in the model (as in Brown et al. 2014) and also an additional random effect (intercepts) for site:

+
+
MLM2.mod <- glmer(abundance ~ snow.melt.days * seed.mass + (1 + snow.melt.days|species) + (1 | sites) + (1 | obs), family = "poisson", control=glmerControl(calc.derivs=F), nAGQ = 0, data=data.df)
+summary(MLM2.mod,scale = TRUE)
+
+
Warning in summary.merMod(MLM2.mod, scale = TRUE): additional arguments ignored
+
+
+
Generalized linear mixed model fit by maximum likelihood (Adaptive
+  Gauss-Hermite Quadrature, nAGQ = 0) [glmerMod]
+ Family: poisson  ( log )
+Formula: abundance ~ snow.melt.days * seed.mass + (1 + snow.melt.days |  
+    species) + (1 | sites) + (1 | obs)
+   Data: data.df
+Control: glmerControl(calc.derivs = F)
+
+     AIC      BIC   logLik deviance df.resid 
+  7264.1   7324.6  -3623.0   7246.1     6141 
+
+Scaled residuals: 
+    Min      1Q  Median      3Q     Max 
+-1.5851 -0.4284 -0.2557 -0.0732  8.9436 
+
+Random effects:
+ Groups  Name           Variance Std.Dev. Corr
+ obs     (Intercept)    0.1472   0.3837       
+ species (Intercept)    1.6523   1.2854       
+         snow.melt.days 1.0169   1.0084   0.71
+ sites   (Intercept)    0.4344   0.6591       
+Number of obs: 6150, groups:  obs, 6150; species, 82; sites, 75
+
+Fixed effects:
+                         Estimate Std. Error z value Pr(>|z|)    
+(Intercept)               -2.1239     0.1708 -12.436  < 2e-16 ***
+snow.melt.days            -0.6805     0.1228  -5.543 2.97e-08 ***
+seed.mass                 -0.2050     0.1634  -1.255    0.210    
+snow.melt.days:seed.mass  -0.1134     0.1281  -0.885    0.376    
+---
+Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+
+Correlation of Fixed Effects:
+            (Intr) snw.m. sd.mss
+snw.mlt.dys 0.630               
+seed.mass   0.022  0.029        
+snw.mlt.d:. 0.023  0.031  0.680 
+
+
+

Let’s test the fit difference between MLM1 and MLM2:

+
+
anova(MLM1.mod,MLM2.mod)
+
+
Data: data.df
+Models:
+MLM1.mod: abundance ~ snow.melt.days + snow.melt.days:seed.mass + (1 + snow.melt.days | species) + (1 | obs)
+MLM2.mod: abundance ~ snow.melt.days * seed.mass + (1 + snow.melt.days | species) + (1 | sites) + (1 | obs)
+         npar    AIC    BIC  logLik deviance  Chisq Df Pr(>Chisq)    
+MLM1.mod    7 7335.5 7382.6 -3660.7   7321.5                         
+MLM2.mod    9 7264.1 7324.6 -3623.0   7246.1 75.406  2  < 2.2e-16 ***
+---
+Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+
+
c(BIC(MLM1.mod),BIC(MLM2.mod))
+
+
[1] 7382.551 7324.594
+
+
+

We won’t diagnostics here for brevity and the code for the MLM1 can be easily adapted here.

+

Although the fixed effects for the trait (seed mass) and interaction (seed mass and snow.melt.day) were not significant, the random effect standard deviation for site is relative large (0.66) and improved the predictive power for abundances across species.

+
+Our last GLMM applied to the fourth corner problem treating species and sites as random effects - the MLML3 model +
+

ter Braak (2019) proposed yet another version that seems to work better than the previous ones.

+
+
MLM3.mod <- glmer(abundance ~ snow.melt.days * seed.mass + (1 + snow.melt.days|species) + (1 + seed.mass|sites) + (1 | obs), family = "poisson", control=glmerControl(calc.derivs=F), nAGQ = 0, data=data.df)
+
+

Let’s test the fit difference between MLM2 and MLM3:

+
+
anova(MLM2.mod,MLM3.mod)
+
+
Data: data.df
+Models:
+MLM2.mod: abundance ~ snow.melt.days * seed.mass + (1 + snow.melt.days | species) + (1 | sites) + (1 | obs)
+MLM3.mod: abundance ~ snow.melt.days * seed.mass + (1 + snow.melt.days | species) + (1 + seed.mass | sites) + (1 | obs)
+         npar    AIC    BIC  logLik deviance  Chisq Df Pr(>Chisq)
+MLM2.mod    9 7264.1 7324.6 -3623.0   7246.1                     
+MLM3.mod   11 7267.0 7341.0 -3622.5   7245.0 1.0759  2     0.5839
+
+
c(BIC(MLM2.mod),BIC(MLM3.mod))
+
+
[1] 7324.594 7340.967
+
+
+

For these data, the MLM3 does not improve the MLM2.

+

This is not the end - we will keep updating this page after the workshop
+References (still being filled):

+

AM Brown, DI Warton, NR Andrew, M Binns, G Cassis, H Gibb Methods in Ecology and Evolution 5 (4), 344-352

+

Choler, P. (2005) Consistent shifts in Alpine plant traits along a mesotopographical gradient. Arctic, Antarctic, and Alpine Research, 37,444–453.

+

Dray, S., & Legendre, P. (2008) Testing the species traits-environment relationships : The fourth-corner problem revisited. Ecology, 89, 3400–3412.

+

Dunn, KP & Smyth GK (1996) Randomized quantile residuals. Journal of Computational and Graphical Statistics, 5, 1-10.

+

Gabriel, KR. (1998) Generalised bilinear regression. Biometrika, 85, 689-700.

+

Gelman, A & Hill, J (2007). Data analysis using regression and multi-level/hierarchical models. New York, NY: Cambridge University Press.

+

Harrison, XA (2014). Using observation-level random effects to model overdispersion in count data in ecology and evolution. PeerJ, 2, e616.

+

Jamil, T., Ozinga, W. A., Kleyer, M., & ter Braak, C. J. F. (2013). Selecting traits that explain species-environment relationships: A generalized linear mixed model approach. Journal of Vegetation Science, 24, 988–1000.

+

Peres-Neto, P. R., Dray, S., & ter Braak, C. J. F. (2017). Linking trait variation to the environment: Critical issues with community-weighted mean correlation resolved by the fourth-corner approach. Ecography, 40, 806–816.

+

Pollock, L. J., Morris, W. K., & Vesk, P. A. (2012). The role of functional traits in species distributions revealed through a hierarchical model. Ecography, 35, 716–725.

+

Simpson, EH (1951). The Interpretation of Interaction in Contingency Tables. Journal of the Royal Statistical Society, Series B., 13, 238–241.

+

ter Braak, CJF, Cormont, A. & Dray, S. (2012). Improved testing of species traits–environment relationships in the fourth‐corner problem. Ecology, 93, 1525-1526.

+

ter Braak, CJF & Looman, CWN. (1986). Weighted averaging, logistic regression and the Gaussian response model. Plant Ecology, 65, 3-11.

+

useful sites for GLMs (will also expand on this later on):

+ + + + +
+ +
+ + + + \ No newline at end of file diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-1-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-1-1.png new file mode 100644 index 0000000..c896584 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-1-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-102-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-102-1.png new file mode 100644 index 0000000..ec1e014 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-102-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-103-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-103-1.png new file mode 100644 index 0000000..8a03b04 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-103-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-104-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-104-1.png new file mode 100644 index 0000000..8ec002f Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-104-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-107-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-107-1.png new file mode 100644 index 0000000..e87d28a Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-107-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-108-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-108-1.png new file mode 100644 index 0000000..4204bc6 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-108-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-12-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-12-1.png new file mode 100644 index 0000000..45e8a1d Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-12-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-15-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-15-1.png new file mode 100644 index 0000000..3a231fe Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-15-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-16-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-16-1.png new file mode 100644 index 0000000..1982b81 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-16-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-18-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-18-1.png new file mode 100644 index 0000000..39bddb4 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-18-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-20-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-20-1.png new file mode 100644 index 0000000..731405a Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-20-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-22-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-22-1.png new file mode 100644 index 0000000..535360c Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-22-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-31-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-31-1.png new file mode 100644 index 0000000..a32f970 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-31-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-4-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-4-1.png new file mode 100644 index 0000000..43ebe60 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-4-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-41-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-41-1.png new file mode 100644 index 0000000..a40942d Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-41-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-48-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-48-1.png new file mode 100644 index 0000000..eb4438f Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-48-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-49-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-49-1.png new file mode 100644 index 0000000..c9fb999 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-49-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-50-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-50-1.png new file mode 100644 index 0000000..d9ee641 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-50-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-50-2.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-50-2.png new file mode 100644 index 0000000..3e457d3 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-50-2.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-52-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-52-1.png new file mode 100644 index 0000000..27e7ae7 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-52-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-53-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-53-1.png new file mode 100644 index 0000000..bc8050f Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-53-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-54-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-54-1.png new file mode 100644 index 0000000..e81176c Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-54-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-55-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-55-1.png new file mode 100644 index 0000000..a929b6d Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-55-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-56-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-56-1.png new file mode 100644 index 0000000..a9ef2ad Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-56-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-57-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-57-1.png new file mode 100644 index 0000000..2ed95d8 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-57-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-61-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-61-1.png new file mode 100644 index 0000000..9cbf54c Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-61-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-63-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-63-1.png new file mode 100644 index 0000000..fa7dbbd Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-63-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-7-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-7-1.png new file mode 100644 index 0000000..4f43dcf Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-7-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-74-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-74-1.png new file mode 100644 index 0000000..e4bcacb Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-74-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-75-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-75-1.png new file mode 100644 index 0000000..84f058e Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-75-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-76-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-76-1.png new file mode 100644 index 0000000..ddc96ba Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-76-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-77-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-77-1.png new file mode 100644 index 0000000..73f0277 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-77-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-79-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-79-1.png new file mode 100644 index 0000000..0fad82e Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-79-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-80-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-80-1.png new file mode 100644 index 0000000..73117a4 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-80-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-88-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-88-1.png new file mode 100644 index 0000000..989f921 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-88-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-9-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-9-1.png new file mode 100644 index 0000000..1a9f5b1 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-9-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-91-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-91-1.png new file mode 100644 index 0000000..4844031 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-91-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-95-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-95-1.png new file mode 100644 index 0000000..9fb04ba Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-95-1.png differ diff --git a/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-97-1.png b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-97-1.png new file mode 100644 index 0000000..4eaedb1 Binary files /dev/null and b/docs/posts/2021-07-19-glm-community-ecology/index_files/figure-html/unnamed-chunk-97-1.png differ diff --git a/docs/search.json b/docs/search.json new file mode 100644 index 0000000..77db564 --- /dev/null +++ b/docs/search.json @@ -0,0 +1,842 @@ +[ + { + "objectID": "posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/index.html", + "href": "posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/index.html", + "title": "Sensibilisation aux réalités autochtones et recherche collaborative", + "section": "", + "text": "Améliorer notre compréhension du passé et de ses impacts sur nos relations entre le avec les Peuples Autochtones.\nDévelopper des notions et compétences afin d’agir contre les préjugés et le racisme.\n\n\n\n\n\nFaire un survol des événements historiques importants et de leurs impacts à ce jour (Loi sur les Indiens, politiques d’assimilation, les pensionnats, etc.). \nAcquérir des connaissances sur la terminologie autochtone.\nFaire un survol de certains procès et contextes légaux et voir comment ils affectent notre travail en territoire autochtone.\nDans une optique de réconciliation, faire une prise de conscience des préjugés persistants et discuter de stratégies pour améliorer nos relations avec les communautés." + }, + { + "objectID": "posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/index.html#objectifs-de-la-formation-1", + "href": "posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/index.html#objectifs-de-la-formation-1", + "title": "Sensibilisation aux réalités autochtones et recherche collaborative", + "section": "Objectifs de la formation :", + "text": "Objectifs de la formation :\n\nEntamer une réflexion collective envers nos pratiques de recherche et comment s’engager de manière significative avec les communautés autochtones.\nDévelopper une meilleure compréhension des perceptions et attentes des communautés envers la recherche et les chercheurs." + }, + { + "objectID": "posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/index.html#durant-ce-webminaire-nous-allons-1", + "href": "posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/index.html#durant-ce-webminaire-nous-allons-1", + "title": "Sensibilisation aux réalités autochtones et recherche collaborative", + "section": "Durant ce webminaire, nous allons: ", + "text": "Durant ce webminaire, nous allons: \n\nMieux comprendre la nécessité de prendre en compte les connaissances autochtones dans divers aspects de la gestion environnementale au Canada; \nDiscuter du désir des communauté d’avoir une présence accrue dans le milieu de la recherche : comment faire?\nAborder et débattre des différentes approches méthodologiques pour établir des ponts en les connaissances autochtones et scientifiques." + }, + { + "objectID": "posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/index.html#formatrice", + "href": "posts/2020-04-28-sensibilisation-aux-ralits-autochtones-et-recherche-collaborative/index.html#formatrice", + "title": "Sensibilisation aux réalités autochtones et recherche collaborative", + "section": "Formatrice :", + "text": "Formatrice :\nCatherine-Alexandra Gagnon possède une expertise dans le travail collaboratif en milieux autochtones. Elle s’intéresse particulièrement à la mise en commun des savoirs locaux, autochtones et scientifiques. Elle détient un doctorat en Sciences de l’environnement et une maîtrise en Gestion de la faune de l’Université du Québec à Rimouski, un baccalauréat en biologie faunique de l’université McGill ainsi qu’un certificat en Études autochtones de l’université de Montréal. Durant ses études, elle a travaillé sur les connaissances locales et ancestrales des Aîné(e)s et chasseurs Inuit, Inuvialuit et Gwich’in du Nunavut, des Territoires du Nord-Ouest et du Yukon." + }, + { + "objectID": "posts/2020-09-21-data-visualization/index.html", + "href": "posts/2020-09-21-data-visualization/index.html", + "title": "Data Visualization", + "section": "", + "text": "Welcome!\nThis training covers the general principles of visualization and graphic design, and techniques of tailored visualization. More specifically, the objectives of the training are:" + }, + { + "objectID": "posts/2020-09-21-data-visualization/index.html#training-material", + "href": "posts/2020-09-21-data-visualization/index.html#training-material", + "title": "Data Visualization", + "section": "Training material", + "text": "Training material\nClick on “Show code” to learn how to do each plot!\n\nInteractive examples\n\n\n\n\nStreamgraph\n\n\nShow code\n# Script to make a streamgraph of the top 10 most popular dog breeds in \n# New York City from 1999 to 2015\n\n# load libraries\nlibrary(lubridate) # dealing with dates\nlibrary(dplyr) # data manipulation\nlibrary(streamgraph) #devtools::install_github(\"hrbrmstr/streamgraph\")\nlibrary(htmlwidgets) # to save the widget!\n\n# load the dataset\n# more information about this dataset can be found here:\n# https://www.kaggle.com/smithaachar/nyc-dog-licensing-clean\nnyc_dogs <- read.csv(\"data/nyc_dogs.csv\")\n\n# convert birth year to date format (and keep only the year)\nnyc_dogs$AnimalBirthYear <- mdy_hms(nyc_dogs$AnimalBirthMonth) %>% year()\n\n# identify 10 most common dogs\ntopdogs <- nyc_dogs %>% count(BreedName) \ntopdogs <- topdogs[order(topdogs$n, decreasing = TRUE),]\n# keep 10 most common breeds (and remove last year of data which is incomplete)\ndf <- filter(nyc_dogs, BreedName %in% topdogs$BreedName[2:11] & AnimalBirthYear < 2016) %>% \n group_by(AnimalBirthYear) %>% \n count(BreedName) %>% ungroup()\n\n# get some nice colours from viridis (magma)\ncols <- viridis::viridis_pal(option = \"magma\")(length(unique(df$BreedName)))\n\n# make streamgraph!\npp <- streamgraph(df, \n key = BreedName, value = n, date = AnimalBirthYear, \n height=\"600px\", width=\"1000px\") %>%\n sg_legend(show=TRUE, label=\"names: \") %>%\n sg_fill_manual(values = cols) \n# saveWidget(pp, file=paste0(getwd(), \"/figures/dogs_streamgraph.html\"))\n\n# plot\npp\n\n\n\n\n\n\n\n\n\n\nInteractive plot\n\n\nShow code\n# Script to generate plots to demonstrate how combinations of information dimensions\n# can become overwhelming and difficult to interpret.\n\n# set-up & data manipulation ---------------------------------------------------\n\n# load packages\nlibrary(ggplot2) # for plots, built layer by layer\nlibrary(dplyr) # for data manipulation\nlibrary(magrittr) # for piping\nlibrary(plotly) # interactive plots\n\n# set ggplot theme\ntheme_set(theme_classic() +\n theme(axis.title = element_text(size = 11, face = \"bold\"),\n axis.text = element_text(size = 11),\n plot.title = element_text(size = 13, face = \"bold\"),\n legend.title = element_text(size = 11, face = \"bold\"),\n legend.text = element_text(size = 10)))\n\n# import data\n# more info on this dataset: https://github.com/rfordatascience/tidytuesday/blob/master/data/2020/2020-07-28/readme.md\npenguins <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-07-28/penguins.csv') \n\n# get some nice colours from viridis (magma)\nsp_cols <- viridis::viridis_pal(option = \"magma\")(5)[2:4]\n\n\n#### Day 1 ####\n\n# 1. Similarity\n\nggplot(penguins) +\n geom_point(aes(y = bill_length_mm, x = bill_depth_mm, col = species), size = 2.5) +\n labs(x = \"Bill depth (mm)\", y = \"Bill length (mm)\", col = \"Species\") + # labels\n scale_color_manual(values = sp_cols) # sets the colour scale we created above \n\n\n\n\n\nShow code\nggsave(\"figures/penguins_similarity.png\", width = 6, height = 3, units = \"in\")\n\n# 2. Proximity\n\ndf <- penguins %>% group_by(sex, species) %>% \n summarise(mean_mass = mean(body_mass_g, na.rm = TRUE)) %>% na.omit() \nggplot(df) +\n geom_bar(aes(y = mean_mass, x = species, fill = sex), \n position = \"dodge\", stat = \"identity\") +\n labs(x = \"Species\", y = \"Mean body mass (g)\", col = \"Sex\") + # labels\n scale_fill_manual(values = sp_cols) # sets the colour scale we created above\n\n\n\n\n\nShow code\nggsave(\"figures/penguins_proximity.png\", width = 6, height = 3, units = \"in\")\n\n# 3. Enclosure (Ellipses over a fake PCA)\nggplot(data = penguins, \n aes(y = bill_length_mm, x = bill_depth_mm)) +\n geom_point(size = 2.1, col = \"grey30\") +\n stat_ellipse(aes(col = species), lwd = .7) +\n labs(x = \"PCA1\", y = \"PCA2\", col = \"Species\") + # labels\n scale_color_manual(values = sp_cols) + # sets the colour scale we created above\n theme(axis.text = element_blank(), axis.ticks = element_blank())\n\n\n\n\n\nShow code\nggsave(\"figures/penguins_enclosure.png\", width = 6, height = 3, units = \"in\")\n\n# 4. Mismatched combination of principles\ntemp_palette <- rev(c(sp_cols, \"#1f78b4\", \"#33a02c\"))\nggplot(data = penguins, \n aes(y = bill_length_mm, x = bill_depth_mm)) +\n geom_point(aes(col = sex), size = 2.1) +\n stat_ellipse(aes(col = species), lwd = .7) +\n labs(x = \"Bill depth (mm)\", y = \"Bill length (mm)\", col = \"?\") + # labels\n scale_color_manual(values = temp_palette) # sets the colour scale we created above\n\n\n\n\n\nShow code\nggsave(\"figures/penguins_mismatchedgestalt.png\", width = 6, height = 3, units = \"in\")\n\n\n\n#### Day 2 ####\n\n# 1. Ineffective combinations: Luminance & shading -----------------------------\n\n# create the plot\nggplot(penguins) +\n geom_point(aes(y = bill_length_mm, x = bill_depth_mm, \n col = species, # hue\n alpha = log(body_mass_g)), # luminance\n size = 2.5) +\n labs(x = \"Bill depth (mm)\", y = \"Bill length (mm)\", \n col = \"Species\", alpha = \"Body mass (g)\") +\n scale_color_manual(values = sp_cols)\n\n\n\n\n\nShow code\nggsave(\"figures/penguins_incompatible1.png\", width = 6, height = 3, units = \"in\")\n\n# 2. Ineffective combinations: Sizes and shapes --------------------------------\n\nggplot(penguins) +\n geom_point(aes(y = bill_length_mm, x = bill_depth_mm, \n shape = species, # shape\n size = log(body_mass_g)), alpha = .7) + # size\n scale_size(range = c(.1, 5)) + # make sure the sizes are scaled by area and not by radius\n labs(x = \"Bill depth (mm)\", y = \"Bill length (mm)\", \n shape = \"Species\", size = \"Body mass (g)\") \n\n\n\n\n\nShow code\nggsave(\"figures/penguins_incompatible2.png\", width = 6, height = 3, units = \"in\")\n\n# 3. Cognitive overload --------------------------------------------------------\n\n# get some nice colours from viridis (magma)\nsex_cols <- viridis::viridis_pal(option = \"magma\")(8)[c(3,6)]\n\nggplot(na.omit(penguins)) +\n geom_point(aes(y = bill_length_mm, # dimension 1: position along y scale\n x = bill_depth_mm, # dimension 2: position along x scale\n shape = species, # dimension 3: shape\n size = log(body_mass_g), # dimension 4: size\n col = sex), # dimension 5: hue\n alpha = .7) + # size\n scale_size(range = c(.1, 5)) + # make sure the sizes are scaled by area and not by radius\n labs(x = \"Bill depth (mm)\", y = \"Bill length (mm)\", \n shape = \"Species\", size = \"Body mass (g)\", col = \"Sex\") +\n scale_color_manual(values = sex_cols)\n\n\n\n\n\nShow code\nggsave(\"figures/penguins_5dimensions.png\", width = 7, height = 4, units = \"in\")\n\n\n# 4. Panels -------------------------------------------------------------------\n\nggplot(na.omit(penguins)) +\n geom_point(aes(y = bill_length_mm, # dimension 1: position along y scale\n x = bill_depth_mm, # dimension 2: position along x scale\n col = log(body_mass_g)), # dimension 3: hue\n alpha = .7, size = 2) + \n facet_wrap(~ species) + # dimension 4: species!\n # this will create a separate panel for each species\n # note: this also automatically uses the same axes for all panels! If you want \n # axes to vary between panels, use the argument scales = \"free\"\n labs(x = \"Bill depth (mm)\", y = \"Bill length (mm)\", col = \"Body mass (g)\") +\n scale_color_viridis_c(option = \"magma\", end = .9, direction = -1) +\n theme_linedraw() + theme(panel.grid = element_blank()) # making the panels prettier\n\n\n\n\n\nShow code\nggsave(\"figures/penguins_dimensions_facets.png\", width = 7, height = 4, units = \"in\")\n\n\n# 5. Interactive ---------------------------------------------------------------\n\np <- na.omit(penguins) %>%\n ggplot(aes(y = bill_length_mm, \n x = bill_depth_mm, \n col = log(body_mass_g))) +\n geom_point(size = 2, alpha = .7) + \n facet_wrap(~ species) +\n labs(x = \"Bill depth (mm)\", y = \"Bill length (mm)\", col = \"Body mass (g)\") +\n scale_color_viridis_c(option = \"magma\", end = .9, direction = -1) +\n theme_linedraw() + theme(panel.grid = element_blank()) # making the panels prettier\np <- ggplotly(p)\n#setwd(\"figures\")\nhtmlwidgets::saveWidget(as_widget(p), \"figures/penguins_interactive.html\")\np\n\n\n\n\n\n\n\n\n\nExample figures\n\n\nShow code\n# Script to make animated plot of volcano eruptions over time\n\n# Load libraries:\nlibrary(dplyr) # data manipulation\nlibrary(ggplot2) # plotting\nlibrary(gganimate) # animation\nlibrary(gifski) # creating gifs\n\n# set ggplot theme\ntheme_set(theme_classic() +\n theme(axis.title = element_text(size = 11, face = \"bold\"),\n axis.text = element_text(size = 11),\n plot.title = element_text(size = 13, face = \"bold\"),\n legend.title = element_text(size = 11, face = \"bold\"),\n legend.text = element_text(size = 10)))\n\n# function to floor a year to the decade\nfloor_decade = function(value){return(value - value %% 10)}\n\n# read data \neruptions <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-05-12/eruptions.csv')\n\n# select top 5 most frequently exploding volcanoes\ntemp <- group_by(eruptions, volcano_name) %>% tally() \ntemp <- temp[order(temp$n, decreasing = TRUE),]\n\n# make a time series dataset (number of eruptions per year)\neruptions$start_decade = floor_decade(eruptions$start_year)\n\n# filter dataset to subset we want to visualize\ndf <- eruptions %>% \n filter(between(start_decade, 1900, 2019)) %>%\n filter(volcano_name %in% temp$volcano_name[1:5]) %>%\n group_by(start_decade) %>%\n count(volcano_name) %>% ungroup()\n\n# plot!\np <- ggplot(df, aes(x = start_decade, y = n, fill = volcano_name)) +\n geom_area() +\n geom_vline(aes(xintercept = start_decade)) + # line that follows the current decade\n scale_fill_viridis_d(option = \"magma\", end = .8) +\n labs(x = \"\", y = \"Number of eruptions\", fill = \"Volcano\",\n title = 'Eruptions of the top 5 most frequently erupting volcanos worldwide') +\n # gganimate part: reveals each decade\n transition_reveal(start_decade) \nanimate(p, duration = 5, fps = 20, width = 800, height = 300, renderer = gifski_renderer())\n\n\n\n\n\nShow code\n#anim_save(\"figures/volcano_eruptions.gif\")\n\n\n\n\nShow code\n# Script to generate plots with various ways of representing uncertainty, based \n# Coffee & Code dataset from https://www.kaggle.com/devready/coffee-and-code/data\n\n# set-up & data manipulation ---------------------------------------------------\n\n# load packages\nlibrary(ggplot2) # for plots, built layer by layer\nlibrary(dplyr) # for data manipulation\nlibrary(magrittr) # for piping\nlibrary(ggridges) # for density ridge plots\nlibrary(patchwork) # great package for \"patching\" plots together!\n\n# set ggplot theme\ntheme_set(theme_classic() +\n theme(axis.title = element_text(size = 11, face = \"bold\"),\n axis.text = element_text(size = 11),\n plot.title = element_text(size = 13, face = \"bold\"),\n legend.title = element_text(size = 11, face = \"bold\"),\n legend.text = element_text(size = 10)))\n\n# import data\ndf <- read.csv(\"data/coffee_code.csv\")\n\n# set labels to be used in all plots\ncoffee_labels <- labs(title = \"Does coffee help programmers code?\",\n x = \"Coffee while coding\", \n y = \"Time spent coding \\n(hours/day)\") \n\n# the variable CodingWithoutCoffee is negative, which is harder to understand\n# (i.e. \"No\" means they drink coffee...). So, let's transform it into a more \n# intuitive variable!\ndf$CodingWithCoffee <- gsub(\"No\", \"Usually\", df$CodingWithoutCoffee)\ndf$CodingWithCoffee <- gsub(\"Yes\", \"Rarely\\n or never\", df$CodingWithCoffee)\n# convert to factor and set levels so they show up in a logical order\ndf$CodingWithCoffee <- factor(df$CodingWithCoffee,\n levels = c(\"Rarely\\n or never\", \n \"Sometimes\", \n \"Usually\"))\n\n# calculate summary statistics for the variable of choice\ndf_summary <- group_by(df, CodingWithCoffee) %>%\n summarise(\n # mean\n mean_codinghours = mean(CodingHours), \n # standard deviation\n sd_codinghours = sd(CodingHours), \n # standard error\n se_codinghours = sd(CodingHours)/sqrt(length(CodingHours)))\n\n\n# 1. Error bars (standard error) -----------------------------------------------\n\nggplot(df_summary) +\n geom_errorbar(aes(x = CodingWithCoffee, \n ymin = mean_codinghours - se_codinghours,\n ymax = mean_codinghours + se_codinghours), \n width = .2) +\n geom_point(aes(x = CodingWithCoffee, y = mean_codinghours), \n size = 3) +\n coffee_labels + ylim(0,10)\n\n\n\n\n\nShow code\nggsave(\"figures/coffee_errorbars.png\", width = 5, height = 3, units = \"in\")\n\n# 2. Boxplot -------------------------------------------------------------------\n\nggplot(df) +\n geom_boxplot(aes(x = CodingWithCoffee, y = CodingHours)) +\n coffee_labels\n\n\n\n\n\nShow code\nggsave(\"figures/coffee_boxplot.png\", width = 5, height = 3, units = \"in\")\n\n\n# 3. Error bar demonstration ---------------------------------------------------\n\n# get some nice colours from viridis (magma)\nerror_cols <- viridis::viridis_pal(option = \"magma\")(5)[2:4]\n# set labels to be used in the palette\nerror_labels = c(\"standard deviation\",\"95% confidence interval\",\"standard error\")\n\nggplot(df_summary) +\n # show the raw data\n geom_jitter(data = df, aes(x = CodingWithCoffee, \n y = CodingHours),\n alpha = .5, width = .05, col = \"grey\") +\n # standard deviation\n geom_errorbar(aes(x = CodingWithCoffee, \n ymin = mean_codinghours - sd_codinghours,\n ymax = mean_codinghours + sd_codinghours,\n col = \"SD\"), width = .2, lwd = 1) +\n # 95% confidence interval\n geom_errorbar(aes(x = CodingWithCoffee, \n ymin = mean_codinghours - 1.96*se_codinghours,\n ymax = mean_codinghours + 1.96*se_codinghours, \n col = \"CI\"), width = .2, lwd = 1) +\n # standard error\n geom_errorbar(aes(x = CodingWithCoffee, \n ymin = mean_codinghours - se_codinghours,\n ymax = mean_codinghours + se_codinghours, \n col = \"SE\"), width = .2, lwd = 1) +\n geom_point(aes(x = CodingWithCoffee, y = mean_codinghours), \n size = 3) +\n coffee_labels + ylim(c(0,11)) +\n # manual palette/legend set-up!\n scale_colour_manual(name = \"Uncertainty metric\", \n values = c(SD = error_cols[1], \n CI = error_cols[2], \n SE = error_cols[3]),\n labels = error_labels) +\n theme(legend.position = \"top\")\n\n\n\n\n\nShow code\nggsave(\"figures/coffee_bars_demo.png\", width = 7, height = 5, units = \"in\")\n\n\n# 4. Jitter plot with violin ---------------------------------------------------\n\nggplot() +\n geom_jitter(data = df, aes(x = CodingWithCoffee, \n y = CodingHours),\n alpha = .5, width = .05, col = \"grey\") +\n geom_violin(data = df, aes(x = CodingWithCoffee, \n y = CodingHours), alpha = 0) +\n geom_linerange(data = df_summary,\n aes(x = CodingWithCoffee, \n ymin = mean_codinghours - se_codinghours,\n ymax = mean_codinghours + se_codinghours)) +\n geom_point(data = df_summary, \n aes(x = CodingWithCoffee, \n y = mean_codinghours), size = 3) +\n coffee_labels\n\n\n\n\n\nShow code\nggsave(\"figures/coffee_violin_jitter.png\", width = 5, height = 3, units = \"in\")\n\n\n# 5. Density ridge plot --------------------------------------------------------\n\nggplot(df) + \n aes(y = CodingWithCoffee, x = CodingHours, fill = stat(x)) +\n geom_density_ridges_gradient(scale = 1.9, size = .2, rel_min_height = 0.005) +\n # colour palette (gradient according to CodingHours)\n scale_fill_viridis_c(option = \"magma\", direction = -1) +\n # remove legend - it's not necessary here!\n theme(legend.position = \"none\") +\n labs(title = coffee_labels$title, \n x = coffee_labels$y, \n y = \"Coffee \\nwhile coding\") + \n theme(axis.title.y = element_text(angle=0, hjust = 1, vjust = .9, \n margin = margin(t = 0, r = -50, b = 0, l = 0)))\n\n\n\n\n\nShow code\nggsave(\"figures/coffee_density_ridges.png\", width = 5, height = 3, units = \"in\")\n\n# 6. Jitter vs. Rug plot ------------------------------------------------------------------\n\njitterplot <- ggplot(df, aes(x = CoffeeCupsPerDay, y = CodingHours)) +\n geom_jitter(alpha = .2) +\n geom_smooth(fill = error_cols[1], col = \"black\", method = lm, lwd = .7) +\n coffee_labels + ylim(c(0,11)) + labs(x = \"Cups of coffee (per day)\")\n\nrugplot <- ggplot(df, aes(x = CoffeeCupsPerDay, y = CodingHours)) +\n geom_smooth(fill = error_cols[1], col = \"black\", method = lm, lwd = .7) +\n geom_rug(position=\"jitter\", alpha = .7) + ylim(c(0,11)) +\n coffee_labels + labs(x = \"Cups of coffee (per day)\")\n\n# patch the two plots together\njitterplot + rugplot\n\n\n\n\n\nShow code\n#ggsave(\"figures/coffee_jitter_vs_rugplot.png\", width = 10, height = 4, units = \"in\")\n\n\n\n\nShow code\n# Script to generate 95% confidence intervals of a generated random normal distribution\n# as an example in Day 2: Visualizing uncertainty.\n\n# load library\nlibrary(ggplot2)\nlibrary(magrittr)\nlibrary(dplyr)\n\n# set ggplot theme\ntheme_set(theme_classic() +\n theme(axis.title = element_text(size = 11, face = \"bold\"),\n axis.text = element_text(size = 11),\n plot.title = element_text(size = 13, face = \"bold\"),\n legend.title = element_text(size = 11, face = \"bold\"),\n legend.text = element_text(size = 10)))\n\n# set random seed\nset.seed(22)\n\n# generate population (random normal distribution)\ndf <- data.frame(\"value\" = rnorm(50, mean = 0, sd = 1))\n\n# descriptive stats for each distribution\ndesc_stats = df %>% \n summarise(mean_val = mean(value, na.rm = TRUE),\n se_val = sqrt(var(value)/length(value)))\n\n# build density plot!\np <- ggplot(data = df, aes(x = value, y = ..count..)) +\n geom_density(alpha = .2, lwd = .3) +\n xlim(c(min(df$value-1), max(df$value+1))) \n# extract plotted values\nbase_p <- ggplot_build(p)$data[[1]]\n# shade the 95% confidence interval\np + \n geom_area(data = subset(base_p, \n between(x, \n left = (desc_stats$mean_val - 1.96*desc_stats$se_val),\n right = (desc_stats$mean_val + 1.96*desc_stats$se_val))),\n aes(x = x, y = y), fill = \"cadetblue3\", alpha = .6) +\n # add vertical line to show population mean\n geom_vline(aes(xintercept = 0), lty = 2) +\n annotate(\"text\", x = 0.9, y = 19, label = \"True mean\", fontface = \"italic\") +\n # label axis!\n labs(x = \"Variable of interest\", y = \"\") \n\n\n\n\n\nShow code\n#ggsave(\"figures/confidenceinterval_example.png\", width = 5, height = 3.5, units = \"in\")\n\n\n\n\nAnnotated resource library\nThis is an annotated library of data visualization resources we used to build the BIOS² Data Visualization Training, as well as some bonus resources we didn’t have the time to include. Feel free to save this page as a reference for your data visualization adventures!\n\n\nBooks & articles\nFundamentals of Data Visualization A primer on making informative and compelling figures. This is the website for the book “Fundamentals of Data Visualization” by Claus O. Wilke, published by O’Reilly Media, Inc.\nData Visualization: A practical introduction An accessible primer on how to create effective graphics from data using R (mainly ggplot). This book provides a hands-on introduction to the principles and practice of data visualization, explaining what makes some graphs succeed while others fail, how to make high-quality figures from data using powerful and reproducible methods, and how to think about data visualization in an honest and effective way.\nData Science Design (Chapter 6: Visualizing Data) Covers the principles that make standard plot designs work, show how they can be misleading if not properly used, and develop a sense of when graphs might be lying, and how to construct better ones.\nGraphical Perception: Theory, Experimentation, and Application to the Development of Graphical Methods Cleveland, William S., and Robert McGill. “Graphical Perception: Theory, Experimentation, and Application to the Development of Graphical Methods.” Journal of the American Statistical Association, vol. 79, no. 387, 1984, pp. 531–554. JSTOR, www.jstor.org/stable/2288400. Accessed 9 Oct. 2020.\nGraphical Perception and Graphical Methods for Analyzing Scientific Data Cleveland, William S., and Robert McGill. “Graphical perception and graphical methods for analyzing scientific data.” Science 229.4716 (1985): 828-833.\nFrom Static to Interactive: Transforming Data Visualization to Improve Transparency Weissgerber TL, Garovic VD, Savic M, Winham SJ, Milic NM (2016) designed an interactive line graph that demonstrates how dynamic alternatives to static graphics for small sample size studies allow for additional exploration of empirical datasets. This simple, free, web-based tool demonstrates the overall concept and may promote widespread use of interactive graphics.\nData visualization: ambiguity as a fellow traveler Research that is being done about how to visualize uncertainty in data visualizations. Marx, V. Nat Methods 10, 613–615 (2013). https://doi.org/10.1038/nmeth.2530\nData visualization standards Collection of guidance and resources to help create better data visualizations with less effort.\n\n\n\nDesign principles\nGestalt Principles for Data Visualization: Similarity, Proximity & Enclosure Short visual guide to the Gestalt Principles.\nWhy scientists need to be better at data visualization A great overview of principles that could improve how we visualize scientific data and results.\nA collection of graphic pitfalls A collection of short articles about common issues with data visualizations that can mislead or obscure your message.\n\n\n\nChoosing a visualization\nData Viz Project This is a great place to get inspiration and guidance about how to choose an appropriate visualization. There are many visualizations we are not used to seeing in ecology!\nFrom data to Viz | Find the graphic you need Interactive tool to choose an appropriate visualization type for your data.\n\n\n\nColour\nWhat to consider when choosing colors for data visualization A short, visual guide on things to keep in mind when using colour, such as when and how to use colour gradients, the colour grey, etc.\nColorBrewer: Color Advice for Maps Tool to generate colour palettes for visualizations with colorblind-friendly options. You can also use these palettes in R using the RColorBrewer package, and the scale_*_brewer() (for discrete palettes) or scale_*_distiller() (for continuous palettes) functions in ggplot2.\nColor.review Tool to pick or verify colour palettes with high relative contrast between colours, to ensure your information is readable for everyone.\nCoblis — Color Blindness Simulator Tool to upload an image and view it as they would appear to a colorblind person, with the option to simulate several color-vision deficiencies.\n500+ Named Colours with rgb and hex values List of named colours along with their hex values.\nCartoDB/CartoColor CARTOColors are a set of custom color palettes built on top of well-known standards for color use on maps, with next generation enhancements for the web and CARTO basemaps. Choose from a selection of sequential, diverging, or qualitative schemes for your next CARTO powered visualization using their online module.\n\n\n\nTools\n\nR\nThe R Graph Gallery A collection of charts made with the R programming language. Hundreds of charts are displayed in several sections, always with their reproducible code available. The gallery makes a focus on the tidyverse and ggplot2.\n\nBase R\nCheatsheet: Margins in base R Edit your margins in base R to accommodate axis titles, legends, captions, etc.!\nCustomizing tick marks in base R Seems like a simple thing, but it can be so frustrating! This is a great post about customizing tick marks with base plot in R.\nAnimations in R (for time series) If you want to use animations but don’t want to use ggplot2, this demo might help you!\n\n\nggplot2\nCheatsheet: ggplot2 Cheatsheet for ggplot2 in R - anything you want to do is probably covered here!\nCoding Club tutorial: Data Viz Part 1 - Beautiful and informative data visualization Great tutorial demonstrating how to customize titles, subtitles, captions, labels, colour palettes, and themes in ggplot2.\nCoding Club tutorial: Data Viz Part 2 - Customizing your figures Great tutorial demonstrating how to customize titles, subtitles, captions, labels, colour palettes, and themes in ggplot2.\nggplot flipbook A flipbook-style demonstration that builds and customizes plots line by line using ggplot in R.\ngganimate: A Grammar of Animated Graphics Package to create animated graphics in R (with ggplot2).\n\n\n\nPython\nThe Python Graph Gallery This website displays hundreds of charts, always providing the reproducible python code.\nPython Tutorial: Intro to Matplotlib Introduction to basic functionalities of the Python’s library Matplotlib covering basic plots, plot attributes, subplots and plotting the iris dataset.\nThe Art of Effective Visualization of Multi-dimensional Data Covers both univariate (one-dimension) and multivariate (multi-dimensional) data visualization strategies using the Python machine learning ecosystem.\n\n\nJulia\nJulia Plots Gallery Display of various plots with reproducible code in Julia.\nPlots in Julia Documentation for the Plots package in Julia, including demonstrations for animated plots, and links to tutorials.\nAnimations in Julia How to start making animated plots in Julia.\n\n\n\n\nCustomization\nChart Studio Web editor to create interactive plots with plotly. You can download the image as .html, or static images, without coding the figure yourself.\nPhyloPic Vector images of living organisms. This is great for ecologists who want to add silhouettes of their organisms onto their plots - search anything, and you will likely find it!\nAdd icons on your R plot Add special icons to your plot as a great way to customize it, and save space with labels!\n\n\n\nInspiration (pretty things!)\nInformation is Beautiful Collection of beautiful original visualizations about a variety of topics!\nTidyTuesday A weekly data project aimed at the R ecosystem, where people wrangle and visualize data in loads of creative ways. Browse what people have created (#TidyTuesday on Twitter is great too!), and the visualizations that have inspired each week’s theme.\nWind currents on Earth Dynamic and interactive map of wind currents on Earth.\nA Day in the Life of Americans Dynamic visualisation of how Americans spend their time in an average day.\n2019: The Year in Visual Stories and Graphics Collection of the most popular visualizations by the New York Times in 2019." + }, + { + "objectID": "posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/index.html", + "href": "posts/2020-01-14-mathematical-modeling-in-ecology-and-evolution/index.html", + "title": "Mathematical Modeling in Ecology and Evolution", + "section": "", + "text": "In this workshop, I introduce various modelling techniques, using mostly ecological and evolutionary examples, with a focus on how computer software programs can help biologists analyze such models.\n\nContent\nPart 1: Classic one-variable models in ecology and evolution\nPart 2: Equilibria and their stability\nPart 3: Beyond equilibria\nPart 4: Example of building a model from scratch\nPart 5: Extending to models with more than one variable\nPart 6: Another example of building a model from scratch\n\n\nSoftware\nIn my research, I primarily use Mathematica, which is a powerful software package to organize and conduct analytical modelling, but it is not free (at UBC, we have some licenses available). I will also show some example code and provide translation of most of what I present in a free software package called Maxima.\n\nMathematica installation\nThere is a free trial version that you can use for 15 days, if you don’t have a copy (click here to access), or you can buy a student version online. If you want to make sure that all is working, copy the code below, put your cursor over each of the following lines and press enter (on some computers, “enter” is a separate button, on others, press “shift” and “return” at the same time):\nD[x^3,x]\nListPlot[Table[x, {x,1,10}],Joined->True]\nRSolve[{x[t+1]\\[Equal]A x[t],x[0]\\[Equal]x0},x[t],t]\nPDF[NormalDistribution[0,1],x]\nYou should see (a) \\(3x^2\\), (b) a plot of a line, (c) \\({{x[t]->A^t x0}}\\), and (d) \\(\\frac{e^\\frac{-x^2}{2}}{\\sqrt{2\\pi }}\\).\n\n\nMaxima installation:\nOn a Mac, install using the instructions here. For other file systems, download here.\n\n\nMaxima testing\nWhen you first open Maxima, it will give you a choice of GUIs, chose wxMaxima. Once wxMaxima is launched type this command and hit return to see if it answers 4:\n2+2;\nIf it doesn’t, then scan the installation document for the error that you run into.\nIf it does return 4, then type in and enter these commands:\ndiff(x^3, x);\n\nwxplot2d (3*x, [x, 0, 2*%pi]);\n\nload(\"solve_rec\")$\nsolve_rec(x[t+1] = A*x[t], x[t], x[0]=x0);\n\nload(\"distrib\")$\npdf_normal(x,0,1);\nYou should see (a) \\(3x^2\\), (b) a plot of a line, (c) \\({{x[t]->A^t x0}}\\), and (d) \\(\\frac{e^\\frac{-x^2}{2}}{\\sqrt{2\\pi }}\\).\n\n\n\nMaterial\n\n\n\nMathematica\nMaxima\nPDF\n\n\n\n\nNotebook\nNotebook\nEmbeded below\n\n\nHints and solutions\nHints and solutions\n\n\n\n\n\nHomework\n\n\nHomework answers\n\nHomework answers\n\n\nGuide\nGuide\n\n\n\n\n\nFollow along PDF\nThis PDF was generated from the Mathematica notebook linked above. It doesn’t include dynamic plots, but it’s a good alternative if you want to print out or have a quick reference at hand.\n\n\n \n\n\n\nStability analysis of a recursion equation in a discrete-time model.\n\n\n\n\n\nOther resources\n\nAn Introduction to Mathematical Modeling in Ecology and Evolution (Otto and Day 2007).\nBiomathematical modeling lecture notes.\nMathematica labs UBC.\n\n\n\nThanks\nNiki Love and Gil Henriques did a great job of translating the code into wxMaxima, with limited help from me. Thanks, Niki and Gil!!\n\n\n\n\n\nReferences\n\nOtto, Sarah P, and Troy Day. 2007. A Biologist’s Guide to Mathematical Modeling in Ecology and Evolution. Vol. 13. Princeton University Press." + }, + { + "objectID": "posts/2020-06-15-science-communication/index.html", + "href": "posts/2020-06-15-science-communication/index.html", + "title": "Science Communication", + "section": "", + "text": "The objective of this training is to share and discuss the concepts and tools that contribute to effective science communication. The training is split into two sessions, which cover the basic concepts of effective science communication and how social media tools can be used to boost the signal of your research and extend your research network. Each training takes the form of a presentation interspersed with several short activity modules, where participants are invited to use the tools we will be discussing to kickstart their own science communication.\nThis training was given on June 1 and 2, 2020. You can view recordings of each session here:" + }, + { + "objectID": "posts/2020-06-15-science-communication/index.html#session-1-the-basics-of-science-communication", + "href": "posts/2020-06-15-science-communication/index.html#session-1-the-basics-of-science-communication", + "title": "Science Communication", + "section": "Session 1: The basics of science communication", + "text": "Session 1: The basics of science communication\n\nObjectives:\n\nDiscuss what science communication (or SciComm) can be, and its potential role in boosting the signal of your research\nMake an overview of basic concepts and tools that you can use in any medium (blog posts, presentations, conversations, twitter, etc.) to do effective science communication\n\nDuring this session, we:\n\nDiscuss the potential pitfalls of science communication (notably, diversity and inclusivity problems).\nCover the basic concepts of science communication, including the Golden Circle method, the creation of personas, and storytelling techniques.\nHave short activities where participants can try to use some of the techniques we will be covering, such as filling in their own Golden Circle and explaining a blog post as a storyboard." + }, + { + "objectID": "posts/2020-06-15-science-communication/index.html#session-2-social-media-as-a-science-communication-tool", + "href": "posts/2020-06-15-science-communication/index.html#session-2-social-media-as-a-science-communication-tool", + "title": "Science Communication", + "section": "Session 2: Social media as a science communication tool", + "text": "Session 2: Social media as a science communication tool\n\nObjectives:\n\nRethink the way we write about science by exploring the world of blog posts\nClarify the mechanics of Twitter and how it can be used effectively for science communication\n\nDuring this session, we:\n\nDiscuss how to create a story structure using titles and the flow of ideas in blog posts, especially when we are used to writing scientific articles\nCover the basics of how Twitter works (retweets, threads, replies, hashtags, photo captions, etc.) and how to find helpful connections\nHave short activities where participants will be invited to write their own Twitter biographies and to create a Twitter thread explaining a project of their choice." + }, + { + "objectID": "posts/2021-06-22-introduction-to-shiny-apps/index.html", + "href": "posts/2021-06-22-introduction-to-shiny-apps/index.html", + "title": "Introduction to Shiny Apps", + "section": "", + "text": "There are many reasons to consider using Shiny for a project:\n\nSharing results from a paper with your readers;\nHelping you explore a model, mathematics, simulations;\nLetting non R users use R." + }, + { + "objectID": "posts/2021-06-22-introduction-to-shiny-apps/index.html#hello-shiny", + "href": "posts/2021-06-22-introduction-to-shiny-apps/index.html#hello-shiny", + "title": "Introduction to Shiny Apps", + "section": "Hello Shiny!", + "text": "Hello Shiny!\nHere is an example of a Shiny app that RStudio generates when you open a new Shiny Web App file:\n\n# Define UI for app that draws a histogram ----\nui <- fluidPage(\n\n # App title ----\n titlePanel(\"Hello Shiny!\"),\n\n # Sidebar layout with input and output definitions ----\n sidebarLayout(\n\n # Sidebar panel for inputs ----\n sidebarPanel(\n\n # Input: Slider for the number of bins ----\n sliderInput(inputId = \"bins\",\n label = \"Number of bins:\",\n min = 1,\n max = 50,\n value = 30)\n\n ),\n\n # Main panel for displaying outputs ----\n mainPanel(\n\n # Output: Histogram ----\n plotOutput(outputId = \"distPlot\")\n\n )\n )\n)" + }, + { + "objectID": "posts/2021-06-22-introduction-to-shiny-apps/index.html#building-blocks", + "href": "posts/2021-06-22-introduction-to-shiny-apps/index.html#building-blocks", + "title": "Introduction to Shiny Apps", + "section": "Building blocks", + "text": "Building blocks\nWe’ve now seen the basic building blocks of a Shiny app:\n\nThe user interface, which determines how the app “looks”. This is how we tell Shiny where to ask for user inputs, and where to put any outputs we create.\nReactive values, which are values that change according to user inputs. These are values that affect the outputs we create in the Shiny app, such as tables or plots.\nThe server, where we use reactive values to generate some outputs.\n\n\nIDs\nThe user interface and server communicate through IDs that we assign to inputs from the user and outputs from the server.\n\nWe use an ID (in orange) to link the user input in the UI to the reactive values used in the server:\n\nWe use another ID (in blue) to link the output created in the server to the output shown in the user interface:\n\n\n\nOrganisation\nThese elements can all be placed in one script named app.R or separately in scripts named ui.R and server.R. The choice is up to you, although it becomes easier to work in separate ui.R and server.R scripts when the Shiny app becomes more complex.\nExample 1: Everything in app.R\n Example 2: Split things into ui.R and server.R" + }, + { + "objectID": "posts/2021-06-22-introduction-to-shiny-apps/index.html#plots", + "href": "posts/2021-06-22-introduction-to-shiny-apps/index.html#plots", + "title": "Introduction to Shiny Apps", + "section": "Plots", + "text": "Plots\nShiny is an excellent tool for visual exploration - it is at its most useful when a user can see something change before their eyes according to some selections. This is a great way to allow users to explore a dataset, explore the results of some analyses according to different parameters, and so on!\nLet’s now add a plot to our Shiny app, to visualize the distribution of a variable depending on user input. We’ll be adding the ggplot2 and ggridges packages in the set-up step at the top of our app.R to allow us to make a plot.\n\n# load packages\nlibrary(shiny)\nlibrary(ggridges)\nlibrary(ggplot2)\nlibrary(here)\nlibrary(readr)\n\n\nUser interface\nTo add a plot in our Shiny, we need to indicate where the plot should appear in the app. We can do this with plotOutput(), a similar function to tableOutput() in the previous section that is meant for plot outputs, as the name suggests.\n\n# Define UI for application that makes a table andplots the Volcano Explosivity \n# Index for the most eruptive volcanoes within a selected range of years\n\nui <- fluidPage(\n \n # Application title ----\n \n titlePanel(\"Exploring volcano explosivity\"),\n \n # Input interface ----\n \n sidebarLayout(\n sidebarPanel(\n \n # Sidebar with a slider range input\n sliderInput(\"years\", # the id your server needs to use the selected value\n label = h3(\"Years\"),\n min = 1900, max = 2020, # maximum range that can be selected\n value = c(2010, 2020) # this is the default slider position\n )\n )\n ),\n \n # Show the outputs from the server ---------------\n mainPanel(\n \n # Show a ridgeplot of explosivity index for selected volcanoes\n plotOutput(\"ridgePlot\"),\n \n # then, show the table we made in the previous step\n tableOutput(\"erupt_table\")\n \n )\n)\n\nNow our Shiny app knows where we want to place our plot.\n\n\nServer\nWe now need to create the plot we want to show in our app. This plot will change depending on one or several reactive values that the user can input or select in our UI.\nWe link the UI and server together with IDs that are assigned to each object. Above, we told the UI to expect a plot output with the ID \"ridgePlot\". In the server, we will create a plot and render it as a plot object using renderPlot(), and we will assign this plot output to the ID we call in the UI (as output$ridgePlot).\n\n# Define server logic required to make your output(s)\nserver <- function(input, output) {\n\n \n # prepare the data\n # ----------------------------------------------------------\n \n # read the dataset\n eruptions <- readr::read_rds(here::here(\"data\", \"eruptions.rds\"))\n \n # filter the dataset to avoid overloading the plot \n eruptions <- eruptions[which(eruptions$volcano_name %in% names(which(table(eruptions$volcano_name) > 30))),]\n # this subsets to volcanoes that have erupted more than 30 times\n \n \n # make reactive dataset\n # ----------------------------------------------------------\n \n # subset volcano data with input year range\n eruptions_filtered <- reactive({\n subset(eruptions, start_year >= input$years[1] & end_year <= input$years[2])\n })\n \n \n # create and render the outputs\n # ----------------------------------------------------------\n \n # create the table of volcanoes\n output$erupt_table <- renderTable({\n head(eruptions_filtered())\n })\n \n # render the plot output\n output$ridgePlot <- renderPlot({\n \n # create the plot\n ggplot(data = eruptions_filtered(),\n aes(x = vei,\n y = volcano_name,\n fill = volcano_name)) +\n # we are using a ridgeplot geom here, from the ggridges package\n geom_density_ridges( size = .5) + # line width\n \n # label the axes\n labs(x = \"Volcano Explosivity Index\", y = \"\") +\n \n # adjust the ggplot theme to make the plot \"prettier\"\n theme_classic() + \n theme(legend.position = \"none\",\n axis.text = element_text(size = 12, face = \"bold\"),\n axis.title = element_text(size = 14, face = \"bold\"))\n })\n}\n\n\n\nThe Shiny app\nNow, if we run the Shiny app, we have a plot above the table we made previously. They are positioned in this way because the plotOutput() comes before the tableOutput() in the UI.\n\n# Run the application\nshinyApp(ui = ui, server = server)" + }, + { + "objectID": "posts/2021-06-22-introduction-to-shiny-apps/index.html#customising-the-theme", + "href": "posts/2021-06-22-introduction-to-shiny-apps/index.html#customising-the-theme", + "title": "Introduction to Shiny Apps", + "section": "Customising the theme", + "text": "Customising the theme\nIf you’d like to go one step further, you can also customize the appearance of your Shiny app using built-in themes, or creating your own themes.\n\nUsing built-in themes\nThere are several built-in themes in Shiny, which allow you to quickly change the appearance of your app. You can browse a gallery of available themes here here, or test themes out interactively here.\nLet’s try the darkly theme on our Shiny app. To do this, we will need the shinythemes package.\n\nlibrary(shinythemes)\n\nWe can change the theme of our previous app with one line of code:\n\n# Define UI for application that makes a table andplots the Volcano Explosivity \n# Index for the most eruptive volcanoes within a selected range of years\n\nui <- fluidPage(\n \n # Application title ----\n \n titlePanel(\"Exploring volcano explosivity\"),\n \n # Input interface ----\n \n sidebarLayout(\n sidebarPanel(\n \n # Sidebar with a slider range input\n sliderInput(\"years\", # the id your server needs to use the selected value\n label = h3(\"Years\"),\n min = 1900, max = 2020, # maximum range that can be selected\n value = c(2010, 2020) # this is the default slider position\n )\n )\n ),\n \n # Show the outputs from the server ---------------\n mainPanel(\n \n # Show a ridgeplot of explosivity index for selected volcanoes\n plotOutput(\"ridgePlot\"),\n \n # then, show the table we made in the previous step\n tableOutput(\"erupt_table\")\n \n ),\n \n # Customize the theme ----------------------\n \n # Use the darkly theme\n theme = shinythemes::shinytheme(\"darkly\")\n)\n\nNow, if we run the app, it looks a little different:\n\n\n\nUsing a custom theme\nYou can also go beyond the built-in themes, and create your own custom theme with the fonts and colours of your choice. You can also apply this theme to the outputs rendered in the app, to bring all the visuals together for a more cohesive look.\n\nCustomizing a theme\nTo create a custom theme, we will be using the bs_theme() function from the bslib package.\n\nlibrary(bslib)\n\n\n# Create a custom theme \ncute_theme <- bslib::bs_theme(\n \n bg = \"#36393B\", # background colour\n fg = \"#FFD166\", # most of the text on your app\n primary = \"#F26430\", # buttons, ...\n \n # you can also choose fonts\n base_font = font_google(\"Open Sans\"),\n heading_font = font_google(\"Open Sans\")\n)\n\nTo apply this theme to our Shiny app (and the outputs), we will be using the thematic package.\n\nlibrary(thematic)\n\nThere are two essential steps to apply a custom theme to a Shiny app:\n\nActivating thematic.\nSetting the user interface’s theme to the custom theme (cute_theme).\n\n\n# Activate thematic\n# so your R outputs will be changed to match up with your chosen styling\nthematic::thematic_shiny()\n\n# Define UI for application that makes a table andplots the Volcano Explosivity \n# Index for the most eruptive volcanoes within a selected range of years\n\nui <- fluidPage(\n \n # Application title ----\n \n titlePanel(\"Exploring volcano explosivity\"),\n \n # Input interface ----\n \n sidebarLayout(\n sidebarPanel(\n \n # Sidebar with a slider range input\n sliderInput(\"years\", # the id your server needs to use the selected value\n label = h3(\"Years\"),\n min = 1900, max = 2020, # maximum range that can be selected\n value = c(2010, 2020) # this is the default slider position\n )\n )\n ),\n \n # Show the outputs from the server ---------------\n mainPanel(\n \n # Show a ridgeplot of explosivity index for selected volcanoes\n plotOutput(\"ridgePlot\"),\n \n # then, show the table we made in the previous step\n tableOutput(\"erupt_table\")\n \n ),\n \n # Customize the theme ----------------------\n \n # Use our custom theme\n theme = cute_theme\n)\n\nNow, if we run the app, the user interface and plot theme is set to the colours and fonts we set in cute_theme:\n\nHere, thematic is not changing the colours used to represent a variable in our plot, because this is an informative colour scale (unlike the colour of axis labels, lines, and the plot background). However, if we remove this colour variable in our ridgeplot in the server, thematic will change the plot colours as well. Here is a simplified example of our server to see what these changes would look like:\n\n# Define server logic required to make your output(s)\nserver <- function(input, output) {\n \n #... (all the good stuff we wrote above)\n \n # render the plot output\n output$ridgePlot <- renderPlot({\n \n # create the plot\n ggplot(data = eruptions_filtered(),\n aes(x = vei,\n y = volcano_name)) + # we are no longer setting \n # the fill argument to a variable\n \n # we are using a ridgeplot geom here, from the ggridges package\n geom_density_ridges(size = .5) + \n \n # label the axes\n labs(x = \"Volcano Explosivity Index\", y = \"\") +\n \n # remove the \"classic\" ggplot2 so it doesn't override thematic's changes\n # theme_classic() + \n theme(legend.position = \"none\",\n axis.text = element_text(size = 12, face = \"bold\"),\n axis.title = element_text(size = 14, face = \"bold\"))\n })\n }\n\nNow, our plot’s theme follows the app’s custom theme as well:" + }, + { + "objectID": "posts/2021-06-22-introduction-to-shiny-apps/index.html#taking-advantage-of-good-defaults", + "href": "posts/2021-06-22-introduction-to-shiny-apps/index.html#taking-advantage-of-good-defaults", + "title": "Introduction to Shiny Apps", + "section": "Taking advantage of good defaults", + "text": "Taking advantage of good defaults\nHere, we will use shiny extension shinyDashboards and leaflet to construct a custom Shiny App to map volcanoes of the world. First, we need a few additional packages.\nNote: All Source code for this app can be found here on the BIOS2 Github.\n\n# load packages\nlibrary(shiny)\nlibrary(shinydashboard) # dashboard layout package\nlibrary(shinyWidgets) # fancy widgets package\nlibrary(leaflet) # interactive maps package\nlibrary(dplyr)\nlibrary(ggplot2)\n\n\nUsing ShinyDashboard\nWe will create our app using defaults from the ShinyDashboard package, which always includes three main components: a header, using dashboardHeader(), a sidebar, using dashboardSidebar(), and a body, using dashboardBody(). These are then added together using the dashboardPage() function.\nBuilding these elements is less like usual R coding, and more like web design, since we are, in fact, designing a unser interface for a web app. Here, we’ll make a basic layout before populating it.\n\n# create the header of our app\nheader <- dashboardHeader(\n title = \"Exploring Volcanoes of the World\",\n titleWidth = 350 # since we have a long title, we need to extend width element in pixels\n)\n\n\n# create dashboard body - this is the major UI element\nbody <- dashboardBody(\n\n # make first row of elements (actually, this will be the only row)\n fluidRow(\n \n # make first column, 25% of page - width = 3 of 12 columns\n column(width = 3,\n \n \n # Box 1: text explaining what this app is\n #-----------------------------------------------\n box( width = NULL,\n status=\"primary\", # this line can change the automatic color of the box.\n title = NULL,\n p(\"here, we'll include some info about this app\")\n\n \n ), # end box 1\n \n \n # box 2 : input for selecting volcano type\n #-----------------------------------------------\n box(width = NULL, status = \"primary\",\n title = \"Selection Criteria\", solidHeader = T, \n \n p(\"here, we'll add a UI element for selecting volcano types\"),\n\n ), # end box 2\n \n \n \n # box 3: ggplot of selected volcanoes by continent\n #------------------------------------------------\n box(width = NULL, status = \"primary\",\n solidHeader = TRUE, collapsible = T,\n title = \"Volcanoes by Continent\",\n p(\"here, we'll add a bar plot of volcanoes in each continent\")\n ) # end box 3\n \n ), # end column 1\n \n # second column - 75% of page (9 of 12 columns)\n #--------------------------------------------------\n column(width = 9,\n # Box 4: leaflet map\n box(width = NULL, background = \"light-blue\", height = 850,\n p(\"here, we'll show volcanoes on a map\"),\n ) # end box with map\n ) # end second column\n \n ) # end fluidrow\n) # end body\n\n\n# add elements together\ndashboardPage(\n skin = \"blue\",\n header = header,\n sidebar = dashboardSidebar(disable = TRUE), # here, we only have one tab of our app, so we don't need a sidebar\n body = body\n)" + }, + { + "objectID": "posts/2021-06-22-introduction-to-shiny-apps/index.html#populating-the-layout", + "href": "posts/2021-06-22-introduction-to-shiny-apps/index.html#populating-the-layout", + "title": "Introduction to Shiny Apps", + "section": "Populating the Layout", + "text": "Populating the Layout\nNow, we are going to fill out app with elements. In this app, we will only have one user input: a selection of the volcano type to show. We will use this input (input$volcano_type), which will be used to filter data in the server (i.e. make a smaller dataset using only volcanoes of the selected types), then use this filtered dataset to create output elements (plots and maps).\nBelow, we show the necessary code to include in both the UI and the Server to create each plot element. Notice that after the reactive value selected_volcanoes is created in the selection box, this is the only object that is used to create the other elements in the app.\n\n\n\n\n\n\n\n\n\nLocation\nElement\nUI\nServer\n\n\n\n\nBox 1\nIntro Textbox\nMarkdown/HTML text code\n\n\n\nBox 2\nSelection Wigets\ncheckboxGroupButtons( inputID = \"volcano_type\")\nselected_volcanoes <- reactive({ volcano_df %>% filter(type %in% input$volcano_type)}) to create a filtered dataset that will react to user input\n\n\nBox 3\nBar Graph\nplotOutput(\"continentplot\")\noutput$continentplot <- renderPlot(...)) which will plot from the selectied_volcanoes reactive object\n\n\nBox 4\nLeaflet Map\nleafletOutput(\"volcanomap\")\noutput$volcanomap <- renderLeaflet(...) to map points from the selectied_volcanoes reactive object" + }, + { + "objectID": "posts/2021-06-22-introduction-to-shiny-apps/index.html#challenge", + "href": "posts/2021-06-22-introduction-to-shiny-apps/index.html#challenge", + "title": "Introduction to Shiny Apps", + "section": "Challenge!", + "text": "Challenge!\nUse the code provided to add your own additional user input to the Shiny App. The code (which you can access here leaves a space for an additional UI input inside box 2). Then, you’ll need to use your new input element to the reactive value in the Server, as noted in the server code.\nUse the Default Shiny Widgets or shinyWidgets extended package galleries to explore the types of elements you can add.\n\n\nSee the completed app\nSee our completed app HERE" + }, + { + "objectID": "posts/2021-05-04-building-r-packages/index.html", + "href": "posts/2021-05-04-building-r-packages/index.html", + "title": "Building R packages", + "section": "", + "text": "via GIPHY\nR packages! they are kind of like cookies:\nBut most of all: cookies are delicious for what they contain: chocolate chunks, candy, oats, cocoa. However, all cookies share some fundamental ingredients and nearly identical structure. Flour, saturated with fat and sugar hydrated only with an egg, flavoured with vanilla and salt. The basic formula is invariant and admits only slight deviation – otherwise, it becomes something other than a cookie.\nThis workshop is devoted to the study of cookie dough." + }, + { + "objectID": "posts/2021-05-04-building-r-packages/index.html#the-structure-flour-and-sugar", + "href": "posts/2021-05-04-building-r-packages/index.html#the-structure-flour-and-sugar", + "title": "Building R packages", + "section": "The structure: flour and sugar", + "text": "The structure: flour and sugar\n\nNo cookies without carbs\n\nAn R package is essentially a folder on your computer with specific structure. We will begin by creating an empty R package and taking a tour!\nOpen your R code editor, and find out where you are:\ngetwd()\nThis is to prepare for the next step, where we will choose a location for our R package folder. Please be intentional about where you place your R package! Do not place it in the same space as another package, Rstudio project or other project. Create a new and isolated location for it.\nI am working from an existing R project in my typical R Projects folder, so I go up one level:\nusethis::create_package(\"../netwerk\")\n\nwe are sticking with usethis because we want to keep this general. All of these steps can be manual, and indeed for many years they were!\n\n\nLet’s run R CMD CHECK right away. We will do this MANY TIMES.\ndevtools::check()\nWe should see some warnings! let’s keep these in mind as we continue our tour.\n\nThe DESCRIPTION file\nThe most important file to notice is the DESCRIPTION. This gives general information about the entire package. It is written in a specific file format\nPackage: netwerk\nTitle: Werks with Networks\nVersion: 0.0.0.9000\nAuthors@R: \n person(given = \"Andrew\",\n family = \"MacDonald\",\n role = c(\"aut\", \"cre\"),\n email = \"\")\nDescription: it does networks.\nLicense: MIT + file LICENSE\nEncoding: UTF-8\nLazyData: true\nRoxygen: list(markdown = TRUE)\nRoxygenNote: 7.1.1\nSuggests: \n testthat (>= 3.0.0)\nConfig/testthat/edition: 3\nHere are some things to edit manually in DESCRIPTION:\n\npackage name [tk naming of R packages] – make it short and convenient if you can!\nTitle: write this part In Title Case. Don’t end the title with a period.\nDescription: Describe the package in a short block of text. This should end with a period.\nAuthors: Add your name here and the name of anyone building the package with you. usethis will have done the first step for you, and filled in the structure. Only “aut” (author) and “cre” (creator) are essential. but many others are possible\n\nAdd your name here.\nAdd a license\nusethis::use_mit_license(copyright_holder = \"\")\nnote about the different roles taht R package authors can have. Funny ones. but creator and maintainer are the key ones.\nNote the R folder. We’ll get much more into that later\n\nRbuildignore" + }, + { + "objectID": "posts/2021-05-04-building-r-packages/index.html#keeping-notes", + "href": "posts/2021-05-04-building-r-packages/index.html#keeping-notes", + "title": "Building R packages", + "section": "Keeping notes", + "text": "Keeping notes\ncreate an R file\nusethis::use_build_ignore(\"dev.R\")\nthe docs folder\nhere we have a very minimal version of an R packages we’re going to be adding to it as the course progresses.\nOne thing we can do right away is build and check the R package\nWhat exactly is happining here? slide from R package tutorial.\nLots of checkpoints and progress confrimations along the way.\nOK so what is that all about? we have compiled the R package and it has gone to where the R packages on our computer go.\nThere is a natural cycle to how the different steps in an R package workflow proceed – see the documentation for this lesson – we will be following this process (TK another pictures?\nOk so now that we ahve the basic structure, let’s talk about some content for the R package. I received the donation of a little R function already that we can use to create this workflow in a nice way\nThis R function (explain what the function does)\nOK so let’s focus on just one part of this function.\nload all – shortcut\n\nhow do we do this in VScode?\n\n\nhow to add something to the .Rbuildignore? it would be nice to have a little .dev script as a space to create all the ohter dependencies that are involved in making an R package.\n\n\n\n✔ Setting active project to '/Users/katherine/Documents/GitHub/bios2.github.io-quarto'\n✔ Adding '^development\\\\.R$' to 'posts/2021-05-04-building-r-packages/.Rbuildignore'" + }, + { + "objectID": "posts/2021-05-04-building-r-packages/index.html#useful-links", + "href": "posts/2021-05-04-building-r-packages/index.html#useful-links", + "title": "Building R packages", + "section": "Useful links", + "text": "Useful links\nThis workshop borrows heavily from some excellent sources:\n\nthe R packages book especially the “Whole Game” chapter!\nrOpenSci Packages: Development, Maintenance, and Peer Review\n\nhttps://builder.r-hub.io/about.html" + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "", + "text": "Version en français à la suite." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#course-outline", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#course-outline", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Course outline", + "text": "Course outline\n\n\n\nDay\nTopics (EN)\n\n\n\n\n1\n• Introduction to spatial statistics • Point pattern analysis\n\n\n2\n• Spatial correlation • Geostatistical models\n\n\n3\n• Areal data • Moran’s I • Spatial autoregression models • Analysis of areal data in R\n\n\n4\n• GLMM with spatial Gaussian process • GLMM with spatial autoregression" + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#types-of-spatial-analyses", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#types-of-spatial-analyses", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Types of spatial analyses", + "text": "Types of spatial analyses\nIn this training, we will discuss three types of spatial analyses: point pattern analysis, geostatistical models and models for areal data.\nIn point pattern analysis, we have point data representing the position of individuals or events in a study area and we assume that all individuals or events have been identified in that area. That analysis focuses on the distribution of the positions of the points themselves. Here are some typical questions for the analysis of point patterns:\n\nAre the points randomly arranged or clustered?\nAre two types of points arranged independently?\n\nGeostatistical models represent the spatial distribution of continuous variables that are measured at certain sampling points. They assume that measurements of those variables at different points are correlated as a function of the distance between the points. Applications of geostatistical models include the smoothing of spatial data (e.g., producing a map of a variable over an entire region based on point measurements) and the prediction of those variables for non-sampled points.\nAreal data are measurements taken not at points, but for regions of space represented by polygons (e.g. administrative divisions, grid cells). Models representing these types of data define a network linking each region to its neighbours and include correlations in the variable of interest between neighbouring regions." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#stationarity-and-isotropy", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#stationarity-and-isotropy", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Stationarity and isotropy", + "text": "Stationarity and isotropy\nSeveral spatial analyses assume that the variables are stationary in space. As with stationarity in the time domain, this property means that summary statistics (mean, variance and correlations between measures of a variable) do not vary with translation in space. For example, the spatial correlation between two points may depend on the distance between them, but not on their absolute position.\nIn particular, there cannot be a large-scale trend (often called gradient in a spatial context), or this trend must be taken into account before modelling the spatial correlation of residuals.\nIn the case of point pattern analysis, stationarity (also called homogeneity) means that point density does not follow a large-scale trend.\nIn a isotropic statistical model, the spatial correlations between measurements at two points depend only on the distance between the points, not on the direction. In this case, the summary statistics do not change under a spatial rotation of the data." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#georeferenced-data", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#georeferenced-data", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Georeferenced data", + "text": "Georeferenced data\nEnvironmental studies increasingly use data from geospatial data sources, i.e. variables measured over a large part of the globe (e.g. climate, remote sensing). The processing of these data requires concepts related to Geographic Information Systems (GIS), which are not covered in this workshop, where we focus on the statistical aspects of spatially varying data.\nThe use of geospatial data does not necessarily mean that spatial statistics are required. For example, we will often extract values of geographic variables at study points to explain a biological response observed in the field. In this case, the use of spatial statistics is only necessary when there is a spatial correlation in the residuals, after controlling for the effect of the predictors." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#point-pattern-and-point-process", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#point-pattern-and-point-process", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Point pattern and point process", + "text": "Point pattern and point process\nA point pattern describes the spatial position (most often in 2D) of individuals or events, represented by points, in a given study area, often called the observation “window”.\nIt is assumed that each point has a negligible spatial extent relative to the distances between the points. More complex methods exist to deal with spatial patterns of objects that have a non-negligible width, but this topic is beyond the scope of this workshop.\nA point process is a statistical model that can be used to simulate point patterns or explain an observed point pattern." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#complete-spatial-randomness", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#complete-spatial-randomness", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Complete spatial randomness", + "text": "Complete spatial randomness\nComplete spatial randomness (CSR) is one of the simplest point patterns, which serves as a null model for evaluating the characteristics of real point patterns. In this pattern, the presence of a point at a given position is independent of the presence of points in a neighbourhood.\nThe process creating this pattern is a homogeneous Poisson process. According to this model, the number of points in any area \\(A\\) follows a Poisson distribution: \\(N(A) \\sim \\text{Pois}(\\lambda A)\\), where \\(\\lambda\\) is the intensity of the process (i.e. the density of points per unit area). \\(N\\) is independent between two disjoint regions, no matter how those regions are defined.\nIn the graph below, only the pattern on the right is completely random. The pattern on the left shows point aggregation (higher probability of observing a point close to another point), while the pattern in the center shows repulsion (low probability of observing a point very close to another)." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#exploratory-or-inferential-analysis-for-a-point-pattern", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#exploratory-or-inferential-analysis-for-a-point-pattern", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Exploratory or inferential analysis for a point pattern", + "text": "Exploratory or inferential analysis for a point pattern\nSeveral summary statistics are used to describe the characteristics of a point pattern. The simplest is the intensity \\(\\lambda\\), which as mentioned above represents the density of points per unit area. If the point pattern is heterogeneous, the intensity is not constant, but depends on the position: \\(\\lambda(x, y)\\).\nCompared to intensity, which is a first-order statistic, second-order statistics describe how the probability of the presence of a point in a region depends on the presence of other points. The Ripley’s \\(K\\) function presented in the next section is an example of a second-order summary statistic.\nStatistical inferences on point patterns usually consist of testing the hypothesis that the point pattern corresponds to a given null model, such as CSR or a more complex null model. Even for the simplest null models, we rarely know the theoretical distribution for a summary statistic of the point pattern under the null model. Hypothesis tests on point patterns are therefore performed by simulation: a large number of point patterns are simulated from the null model and the distribution of the summary statistics of interest for these simulations is compared to their values for the observed point pattern." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#ripleys-k-function", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#ripleys-k-function", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Ripley’s K function", + "text": "Ripley’s K function\nRipley’s K function \\(K(r)\\) is defined as the mean number of points within a circle of radius \\(r\\) around a point in the pattern, standardized by the intensity \\(\\lambda\\).\nUnder the CSR null model, the mean number of points in any circle of radius \\(r\\) is \\(\\lambda \\pi r^2\\), thus in theory \\(K(r) = \\pi r^2\\) for that model. A higher value of \\(K(r)\\) means that there is an aggregation of points at the scale \\(r\\), whereas a lower value means that there is repulsion.\nIn practice, \\(K(r)\\) is estimated for a specific point pattern by the equation:\n\\[ K(r) = \\frac{A}{n(n-1)} \\sum_i \\sum_{j > i} I \\left( d_{ij} \\le r \\right) w_{ij}\\]\nwhere \\(A\\) is the area of the observation window and \\(n\\) is the number of points in the pattern, so \\(n(n-1)\\) is the number of distinct pairs of points. We take the sum for all pairs of points of the indicator function \\(I\\), which takes a value of 1 if the distance between points \\(i\\) and \\(j\\) is less than or equal to \\(r\\). Finally, the term \\(w_{ij}\\) is used to give extra weight to certain pairs of points to account for edge effects, as discussed in the next section.\nFor example, the graphs below show the estimated \\(K(r)\\) function for the patterns shown above, for values of \\(r\\) up to 1/4 of the window width. The red dashed curve shows the theoretical value for CSR and the gray area is an “envelope” produced by 99 simulations of that null pattern. The aggregated pattern shows an excess of neighbours up to \\(r = 0.25\\) and the pattern with repulsion shows a significant deficit of neighbours for small values of \\(r\\).\n\n\n\n\n\nIn addition to \\(K\\), there are other statistics to describe the second-order properties of point patterns, such as the mean distance between a point and its nearest \\(N\\) neighbours. You can refer to the Wiegand and Moloney (2013) textbook in the references to learn more about different summary statistics for point patterns." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#edge-effects", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#edge-effects", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Edge effects", + "text": "Edge effects\nIn the context of point pattern analysis, edge effects are due to the fact that we have incomplete knowledge of the neighbourhood of points near the edge of the observation window, which can induce a bias in the calculation of statistics such as Ripley’s \\(K\\).\nDifferent methods have been developed to correct the bias due to edge effects. In Ripley’s edge correction method, the contribution of a neighbour \\(j\\) located at a distance \\(r\\) from a point \\(i\\) receives a weight \\(w_{ij} = 1/\\phi_i(r)\\), where \\(\\phi_i(r)\\) is the fraction of the circle of radius \\(r\\) around \\(i\\) contained in the observation window. For example, if 2/3 of the circle is in the window, this neighbour counts as 3/2 neighbours in the calculation of a statistic like \\(K\\).\n\nRipley’s method is one of the simplest to correct for edge effects, but is not necessarily the most efficient; in particular, larger weights given to certain pairs of points tend to increase the variance of the calculated statistic. Other correction methods are presented in specialized textbooks, such as Wiegand and Moloney (2013)." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#example", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#example", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Example", + "text": "Example\nFor this example, we use the dataset semis_xy.csv, which represents the \\((x, y)\\) coordinates for seedlings of two species (sp, B = birch and P = poplar) in a 15 x 15 m plot.\n\nsemis <- read.csv(\"data/semis_xy.csv\")\nhead(semis)\n\n x y sp\n1 14.73 0.05 P\n2 14.72 1.71 P\n3 14.31 2.06 P\n4 14.16 2.64 P\n5 14.12 4.15 B\n6 9.88 4.08 B\n\n\nThe spatstat package provides tools for point pattern analysis in R. The first step consists in transforming our data frame into a ppp object (point pattern) with the function of the same name. In this function, we specify which columns contain the coordinates x and y as well as the marks, which here will be the species codes. We also need to specify an observation window (window) using the owin function, where we provide the plot limits in x and y.\n\nlibrary(spatstat)\n\nsemis <- ppp(x = semis$x, y = semis$y, marks = as.factor(semis$sp),\n window = owin(xrange = c(0, 15), yrange = c(0, 15)))\nsemis\n\nMarked planar point pattern: 281 points\nMultitype, with levels = B, P \nwindow: rectangle = [0, 15] x [0, 15] units\n\n\nMarks can be numeric or categorical. Note that for categorical marks as is the case here, the variable must be explicitly converted to a factor.\nThe plot function applied to a point pattern shows a diagram of the pattern.\n\nplot(semis)\n\n\n\n\nThe intensity function calculates the density of points of each species by unit area (here, by \\(m^2\\)).\n\nintensity(semis)\n\n B P \n0.6666667 0.5822222 \n\n\nTo first analyze the distribution of each species separately, we split the pattern with split. Since the pattern contains categorical marks, it is automatically split according to the values of those marks. The result is a list of two point patterns.\n\nsemis_split <- split(semis)\nplot(semis_split)\n\n\n\n\nThe Kest function calculates Ripley’s \\(K\\) for a series of distances up to (by default) 1/4 of the width of the window. Here we apply it to the first pattern (birch) by choosing semis_split[[1]]. Note that double square brackets are necessary to choose an item from a list in R.\nThe argument correction = \"iso\" tells the function to apply Ripley’s correction for edge effects.\n\nk <- Kest(semis_split[[1]], correction = \"iso\")\nplot(k)\n\n\n\n\nAccording to this graph, there seems to be an excess of neighbours for distances of 1 m and above. To check if this is a significant difference, we produce a simulation envelope with the envelope function. The first argument of envelope is a point pattern to which the simulations will be compared, the second one is a function to be computed (here, Kest) for each simulated pattern, then we add the arguments of the Kest function (here, only correction).\n\nplot(envelope(semis_split[[1]], Kest, correction = \"iso\"))\n\nGenerating 99 simulations of CSR ...\n1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,\n81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99.\n\nDone.\n\n\n\n\n\nAs indicated by the message, by default the function performs 99 simulations of the null model corresponding to complete spatial randomness (CSR).\nThe observed curve falls outside the envelope of the 99 simulations near \\(r = 2\\). We must be careful not to interpret too quickly a result that is outside the envelope. Although there is about a 1% probability of obtaining a more extreme result under the null hypothesis at a given distance, the envelope is calculated for a large number of values of \\(r\\) and is not corrected for multiple comparisons. Thus, a significant difference for a very small range of values of \\(r\\) may be simply due to chance.\n\nExercise 1\nLooking at the graph of the second point pattern (poplar seedlings), can you predict where Ripley’s \\(K\\) will be in relation to the null hypothesis of complete spatial randomness? Verify your prediction by calculating Ripley’s \\(K\\) for this point pattern in R." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#effect-of-heterogeneity", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#effect-of-heterogeneity", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Effect of heterogeneity", + "text": "Effect of heterogeneity\nThe graph below illustrates a heterogeneous point pattern, i.e. it shows an density gradient (more points on the left than on the right).\n\n\n\n\n\nA density gradient can be confused with an aggregation of points, as can be seen on the graph of the corresponding Ripley’s \\(K\\). In theory, these are two different processes:\n\nHeterogeneity: The density of points varies in the study area, for example due to the fact that certain local conditions are more favorable to the presence of the species of interest.\nAggregation: The mean density of points is homogeneous, but the presence of one point increases the presence of other points in its vicinity, for example due to positive interactions between individuals.\n\nHowever, it may be difficult to differentiate between the two in practice, especially since some patterns may be both heterogeneous and aggregated.\nLet’s take the example of the poplar seedlings from the previous exercise. The density function applied to a point pattern performs a kernel density estimation of the density of the seedlings across the plot. By default, this function uses a Gaussian kernel with a standard deviation sigma specified in the function, which determines the scale at which density fluctuations are “smoothed”. Here, we use a value of 2 m for sigma and we first represent the estimated density with plot, before overlaying the points (add = TRUE means that the points are added to the existing plot rather than creating a new plot).\n\ndens_p <- density(semis_split[[2]], sigma = 2)\nplot(dens_p)\nplot(semis_split[[2]], add = TRUE)\n\n\n\n\nTo measure the aggregation or repulsion of points in a heterogeneous pattern, we must use the inhomogeneous version of the \\(K\\) statistic (Kinhom in spatstat). This statistic is still equal to the mean number of neighbours within a radius \\(r\\) of a point in the pattern, but rather than standardizing this number by the overall intensity of the pattern, it is standardized by the local estimated density. As above, we specify sigma = 2 to control the level of smoothing for the varying density estimate.\n\nplot(Kinhom(semis_split[[2]], sigma = 2, correction = \"iso\"))\n\n\n\n\nTaking into account the heterogeneity of the pattern at a scale sigma of 2 m, there seems to be a deficit of neighbours starting at a radius of about 1.5 m. We can now check whether this deviation is significant.\nAs before, we use envelope to simulate the Kinhom statistic under the null model. However, the null model here is not a homogeneous Poisson process (CSR). It is instead a heterogeneous Poisson process simulated by the function rpoispp(dens_p), i.e. the points are independent of each other, but their density is heterogeneous and given by dens_p. The simulate argument of the envelope function specifies the function used for simulations under the null model; this function must have one argument, here x, even if it is not used.\nFinally, in addition to the arguments needed for Kinhom, i.e. sigma and correction, we also specify nsim = 199 to perform 199 simulations and nrank = 5 to eliminate the 5 most extreme results on each side of the envelope, i.e. the 10 most extreme results out of 199, to achieve an interval containing about 95% of the probability under the null hypothesis.\n\nkhet_p <- envelope(semis_split[[2]], Kinhom, sigma = 2, correction = \"iso\",\n nsim = 199, nrank = 5, simulate = function(x) rpoispp(dens_p))\n\nGenerating 199 simulations by evaluating function ...\n1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40\n.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80\n.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120\n.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160\n.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.\n\nDone.\n\nplot(khet_p)\n\n\n\n\nNote: For a hypothesis test based on simulations of a null hypothesis, the \\(p\\)-value is estimated by \\((m + 1)/(n + 1)\\), where \\(n\\) is the number of simulations and \\(m\\) is the number of simulations where the value of the statistic is more extreme than that of the observed data. This is why the number of simulations is often chosen to be 99, 199, etc.\n\nExercise 2\nRepeat the heterogeneous density estimation and Kinhom calculation with a standard deviation sigma of 5 rather than 2. How does the smoothing level for the density estimation influence the conclusions?\nTo differentiate between a variation in the density of points from an interaction (aggregation or repulsion) between these points with this type of analysis, it is generally assumed that the two processes operate at different scales. Typically, we can test whether the points are aggregated at a small scale after accounting for a variation in density at a larger scale." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#relationship-between-two-point-patterns", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#relationship-between-two-point-patterns", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Relationship between two point patterns", + "text": "Relationship between two point patterns\nLet’s consider a case where we have two point patterns, for example the position of trees of two species in a plot (orange and green points in the graph below). Each of the two patterns may or may not present an aggregation of points.\n\n\n\n\n\nRegardless of whether points are aggregated at the species level, we want to determine whether the two species are arranged independently. In other words, does the probability of observing a tree of one species depend on the presence of a tree of the other species at a given distance?\nThe bivariate version of Ripley’s \\(K\\) allows us to answer this question. For two patterns noted 1 and 2, the function \\(K_{12}(r)\\) calculates the mean number of points in pattern 2 within a radius \\(r\\) from a point in pattern 1, standardized by the density of pattern 2.\nIn theory, this function is symmetrical, so \\(K_{12}(r) = K_{21}(r)\\) and the result would be the same whether the points of pattern 1 or 2 are chosen as “focal” points for the analysis. However, the estimation of the two quantities for an observed pattern may differ, in particular because of edge effects. The variance of \\(K_{12}\\) and \\(K_{21}\\) between simulations of a null model may also differ, so the null hypothesis test may have more or less power depending on the choice of the focal species.\nThe choice of an appropriate null model is important here. In order to determine whether there is a significant attraction or repulsion between the two patterns, the position of one of the patterns must be randomly moved relative to that of the other pattern, while keeping the spatial structure of each pattern taken in isolation.\nOne way to do this randomization is to shift one of the two patterns horizontally and/or vertically by a random distance. The part of the pattern that “comes out” on one side of the window is attached to the other side. This method is called a toroidal shift, because by connecting the top and bottom as well as the left and right of a rectangular surface, we obtain the shape of a torus (a three-dimensional “donut”).\n\n\n\n\n\nThe graph above shows a translation of the green pattern to the right, while the orange pattern remains in the same place. The green points in the shaded area are brought back on the other side. Note that while this method generally preserves the structure of each pattern while randomizing their relative position, it can have some drawbacks, such as dividing point clusters that are near the cutoff point.\nLet’s now check whether the position of the two species (birch and poplar) is independent in our plot. The function Kcross calculates the bivariate \\(K_{ij}\\), we must specify which type of point (mark) is considered as the focal species \\(i\\) and the neighbouring species \\(j\\).\n\nplot(Kcross(semis, i = \"P\", j = \"B\", correction = \"iso\"))\n\n\n\n\nHere, the observed \\(K\\) is lower than the theoretical value, indicating a possible repulsion between the two patterns.\nTo determine the envelope of the \\(K\\) under the null hypothesis of independence of the two patterns, we must specify that the simulations are based on a translation of the patterns. We indicate that the simulations use the function rshift (random translation) with the argument simulate = function(x) rshift(x, which = \"B\"); here, the x argument in simulate corresponds to the original point pattern and the which argument indicates which of the patterns is translated. As in the previous case, the arguments needed for Kcross, i.e. i, j and correction, must be repeated in the envelope function.\n\nplot(envelope(semis, Kcross, i = \"P\", j = \"B\", correction = \"iso\", \n nsim = 199, nrank = 5, simulate = function(x) rshift(x, which = \"B\")))\n\nGenerating 199 simulations by evaluating function ...\n1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40\n.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80\n.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120\n.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160\n.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.\n\nDone.\n\n\n\n\n\nHere, the observed curve is totally within the envelope, so we do not reject the null hypothesis of independence of the two patterns.\n\nQuestions\n\nWhat would be one reason for our choice to translate the points of the birch rather than poplar?\nWould the simulations generated by random translation be a good null model if the two patterns were heterogeneous?" + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#marked-point-patterns", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#marked-point-patterns", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Marked point patterns", + "text": "Marked point patterns\nThe fir.csv dataset contains the \\((x, y)\\) coordinates of 822 fir trees in a 1 hectare plot and their status (A = alive, D = dead) following a spruce budworm outbreak.\n\nfir <- read.csv(\"data/fir.csv\")\nhead(fir)\n\n x y status\n1 31.50 1.00 A\n2 85.25 30.75 D\n3 83.50 38.50 A\n4 84.00 37.75 A\n5 83.00 33.25 A\n6 33.25 0.25 A\n\n\n\nfir <- ppp(x = fir$x, y = fir$y, marks = as.factor(fir$status),\n window = owin(xrange = c(0, 100), yrange = c(0, 100)))\nplot(fir)\n\n\n\n\nSuppose that we want to check whether fir mortality is independent or correlated between neighbouring trees. How does this question differ from the previous example, where we wanted to know if the position of the points of two species was independent?\nIn the previous example, the independence or interaction between the species referred to the formation of the pattern itself (whether or not seedlings of one species establish near those of the other species). Here, the characteristic of interest (survival) occurs after the establishment of the pattern, assuming that all those trees were alive at first and that some died as a result of the outbreak. So we take the position of the trees as fixed and we want to know whether the distribution of status (dead, alive) among those trees is random or shows a spatial pattern.\nIn Wiegand and Moloney’s textbook, the first situation (establishment of seedlings of two species) is called a bivariate pattern, so it is really two interacting patterns, while the second is a single pattern with a qualitative mark. The spatstat package in R does not differentiate between the two in terms of pattern definition (types of points are always represented by the marks argument), but the analysis methods applied to the two questions differ.\nIn the case of a pattern with a qualitative mark, we can define a mark connection function \\(p_{ij}(r)\\). For two points separated by a distance \\(r\\), this function gives the probability that the first point has the mark \\(i\\) and the second the mark \\(j\\). Under the null hypothesis where the marks are independent, this probability is equal to the product of the proportions of each mark in the entire pattern, \\(p_{ij}(r) = p_i p_j\\) independently of \\(r\\).\nIn spatstat, the mark connection function is computed with the markconnect function, where the marks \\(i\\) and \\(j\\) and the type of edge correction must be specified. In our example, we see that two closely spaced points are less likely to have a different status (A and D) than expected under the assumption of random and independent distribution of marks (red dotted line).\n\nplot(markconnect(fir, i = \"A\", j = \"D\", correction = \"iso\"))\n\n\n\n\nIn this graph, the fluctuations in the function are due to the estimation error of a continuous \\(r\\) function from a limited number of discrete point pairs.\nTo simulate the null model in this case, we use the rlabel function, which randomly reassigns the marks among the points of the pattern, keeping the points’ positions fixed.\n\nplot(envelope(fir, markconnect, i = \"A\", j = \"D\", correction = \"iso\", \n nsim = 199, nrank = 5, simulate = rlabel))\n\nGenerating 199 simulations by evaluating function ...\n1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40\n.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80\n.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120\n.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160\n.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.\n\nDone.\n\n\n\n\n\nNote that since the rlabel function has only one required argument corresponding to the original point pattern, it was not necessary to specify: simulate = function(x) rlabel(x).\nHere are the results for tree pairs of the same status A or D:\n\npar(mfrow = c(1, 2))\nplot(envelope(fir, markconnect, i = \"A\", j = \"A\", correction = \"iso\", \n nsim = 199, nrank = 5, simulate = rlabel))\n\nGenerating 199 simulations by evaluating function ...\n1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40\n.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80\n.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120\n.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160\n.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.\n\nDone.\n\nplot(envelope(fir, markconnect, i = \"D\", j = \"D\", correction = \"iso\", \n nsim = 199, nrank = 5, simulate = rlabel))\n\nGenerating 199 simulations by evaluating function ...\n1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40\n.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80\n.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120\n.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160\n.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.\n\nDone.\n\n\n\n\n\nIt therefore appears that fir mortality due to this outbreak is spatially aggregated, since trees located in close proximity to each other have a greater probability of sharing the same status than predicted by the null hypothesis." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#references", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#references", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "References", + "text": "References\nFortin, M.-J. and Dale, M.R.T. (2005) Spatial Analysis: A Guide for Ecologists. Cambridge University Press: Cambridge, UK.\nWiegand, T. and Moloney, K.A. (2013) Handbook of Spatial Point-Pattern Analysis in Ecology, CRC Press.\nThe dataset in the last example is a subet of the Lake Duparquet Research and Teaching Forest (LDRTF) data, available on Dryad here." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#intrinsic-or-induced-dependence", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#intrinsic-or-induced-dependence", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Intrinsic or induced dependence", + "text": "Intrinsic or induced dependence\nThere are two basic types of spatial dependence on a measured variable \\(y\\): an intrinsic dependence on \\(y\\), or a dependence induced by external variables influencing \\(y\\), which are themselves spatially correlated.\nFor example, suppose that the abundance of a species is correlated between two sites located near each other:\n\nthis spatial dependence can be induced if it is due to a spatial correlation of habitat factors that are favorable or unfavorable to the species;\nor it can be intrinsic if it is due to the dispersion of individuals to nearby sites.\n\nIn many cases, both types of dependence affect a given variable.\nIf the dependence is simply induced and the external variables that cause it are included in the model explaining \\(y\\), then the model residuals will be independent and we can use all the methods already seen that ignore spatial correlation.\nHowever, if the dependence is intrinsic or due to unmeasured external factors, then the spatial correlation of the residuals in the model will have to be taken into account." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#different-ways-to-model-spatial-effects", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#different-ways-to-model-spatial-effects", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Different ways to model spatial effects", + "text": "Different ways to model spatial effects\nIn this training, we will directly model the spatial correlations of our data. It is useful to compare this approach to other ways of including spatial aspects in a statistical model.\nFirst, we could include predictors in the model that represent position (e.g., longitude, latitude). Such predictors may be useful for detecting a systematic large-scale trend or gradient, whether or not the trend is linear (e.g., with a generalized additive model).\nIn contrast to this approach, the models we will see now serve to model a spatial correlation in the random fluctuations of a variable (i.e., in the residuals after removing any systematic effect).\nMixed models use random effects to represent the non-independence of data on the basis of their grouping, i.e., after accounting for systematic fixed effects, data from the same group are more similar (their residual variation is correlated) than data from different groups. These groups were sometimes defined according to spatial criteria (observations grouped into sites).\nHowever, in the context of a random group effect, all groups are as different from each other, e.g., two sites within 100 km of each other are no more or less similar than two sites 2 km apart.\nThe methods we will see here and in the next parts of the training therefore allow us to model non-independence on a continuous scale (closer = more correlated) rather than just discrete (hierarchy of groups)." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#variogram", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#variogram", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Variogram", + "text": "Variogram\nA central aspect of geostatistics is the estimation of the variogram \\(\\gamma_z\\) . The variogram is equal to half the mean square difference between the values of \\(z\\) for two points \\((x_i, y_i)\\) and \\((x_j, y_j)\\) separated by a distance \\(h\\).\n\\[\\gamma_z(h) = \\frac{1}{2} \\text{E} \\left[ \\left( z(x_i, y_i) - z(x_j, y_j) \\right)^2 \\right]_{d_{ij} = h}\\]\nIn this equation, the \\(\\text{E}\\) function with the index \\(d_{ij}=h\\) designates the statistical expectation (i.e., the mean) of the squared deviation between the values of \\(z\\) for points separated by a distance \\(h\\).\nIf we want instead to express the autocorrelation \\(\\rho_z(h)\\) between measures of \\(z\\) separated by a distance \\(h\\), it is related to the variogram by the equation:\n\\[\\gamma_z = \\sigma_z^2(1 - \\rho_z)\\] ,\nwhere \\(\\sigma_z^2\\) is the global variance of \\(z\\).\nNote that \\(\\gamma_z = \\sigma_z^2\\) when we reach a distance where the measurements of \\(z\\) are independent, so \\(\\rho_z = 0\\). In this case, we can see that \\(\\gamma_z\\) is similar to a variance, although it is sometimes called “semivariogram” or “semivariance” because of the 1/2 factor in the above equation." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#theoretical-models-for-the-variogram", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#theoretical-models-for-the-variogram", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Theoretical models for the variogram", + "text": "Theoretical models for the variogram\nSeveral parametric models have been proposed to represent the spatial correlation as a function of the distance between sampling points. Let us first consider a correlation that decreases exponentially:\n\\[\\rho_z(h) = e^{-h/r}\\]\nHere, \\(\\rho_z = 1\\) for \\(h = 0\\) and the correlation is multiplied by \\(1/e \\approx 0.37\\) each time the distance increases by \\(r\\). In this context, \\(r\\) is called the range of the correlation.\nFrom the above equation, we can calculate the corresponding variogram.\n\\[\\gamma_z(h) = \\sigma_z^2 (1 - e^{-h/r})\\]\nHere is a graphical representation of this variogram.\n\n\n\n\n\nBecause of the exponential function, the value of \\(\\gamma\\) at large distances approaches the global variance \\(\\sigma_z^2\\) without exactly reaching it. This asymptote is called a sill in the geostatistical context and is represented by the symbol \\(s\\).\nFinally, it is sometimes unrealistic to assume a perfect correlation when the distance tends towards 0, because of a possible variation of \\(z\\) at a very small scale. A nugget effect, denoted \\(n\\), can be added to the model so that \\(\\gamma\\) approaches \\(n\\) (rather than 0) if \\(h\\) tends towards 0. The term nugget comes from the mining origin of these techniques, where a nugget could be the source of a sudden small-scale variation in the concentration of a mineral.\nBy adding the nugget effect, the remainder of the variogram is “compressed” to keep the same sill, resulting in the following equation.\n\\[\\gamma_z(h) = n + (s - n) (1 - e^{-h/r})\\]\nIn the gstat package that we use below, the term \\((s-n)\\) is called a partial sill or psill for the exponential portion of the variogram.\n\n\n\n\n\nIn addition to the exponential model, two other common theoretical models for the variogram are the Gaussian model (where the correlation follows a half-normal curve), and the spherical model (where the variogram increases linearly at the start and then curves and reaches the plateau at a distance equal to its range \\(r\\)). The spherical model thus allows the correlation to be exactly 0 at large distances, rather than gradually approaching zero in the case of the other models.\n\n\n\n\n\n\n\n\nModel\n\\(\\rho(h)\\)\n\\(\\gamma(h)\\)\n\n\n\n\nExponential\n\\(\\exp\\left(-\\frac{h}{r}\\right)\\)\n\\(s \\left(1 - \\exp\\left(-\\frac{h}{r}\\right)\\right)\\)\n\n\nGaussian\n\\(\\exp\\left(-\\frac{h^2}{r^2}\\right)\\)\n\\(s \\left(1 - \\exp\\left(-\\frac{h^2}{r^2}\\right)\\right)\\)\n\n\nSpherical \\((h < r)\\) *\n\\(1 - \\frac{3}{2}\\frac{h}{r} + \\frac{1}{2}\\frac{h^3}{r^3}\\)\n\\(s \\left(\\frac{3}{2}\\frac{h}{r} - \\frac{1}{2}\\frac{h^3}{r^3} \\right)\\)\n\n\n\n* For the spherical model, \\(\\rho = 0\\) and \\(\\gamma = s\\) if \\(h \\ge r\\)." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#empirical-variogram", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#empirical-variogram", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Empirical variogram", + "text": "Empirical variogram\nTo estimate \\(\\gamma_z(h)\\) from empirical data, we need to define distance classes, thus grouping different distances within a margin of \\(\\pm \\delta\\) around a distance \\(h\\), then calculating the mean square deviation for the pairs of points in that distance class.\n\\[\\hat{\\gamma_z}(h) = \\frac{1}{2 N_{\\text{paires}}} \\sum \\left[ \\left( z(x_i, y_i) - z(x_j, y_j) \\right)^2 \\right]_{d_{ij} = h \\pm \\delta}\\]\nWe will see in the next section how to estimate a variogram in R." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#regression-model-with-spatial-correlation", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#regression-model-with-spatial-correlation", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Regression model with spatial correlation", + "text": "Regression model with spatial correlation\nThe following equation represents a multiple linear regression including residual spatial correlation:\n\\[v = \\beta_0 + \\sum_i \\beta_i u_i + z + \\epsilon\\]\nHere, \\(v\\) designates the response variable and \\(u\\) the predictors, to avoid confusion with the spatial coordinates \\(x\\) and \\(y\\).\nIn addition to the residual \\(\\epsilon\\) that is independent between observations, the model includes a term \\(z\\) that represents the spatially correlated portion of the residual variance.\nHere are suggested steps to apply this type of model:\n\nFit the regression model without spatial correlation.\nVerify the presence of spatial correlation from the empirical variogram of the residuals.\nFit one or more regression models with spatial correlation and select the one that shows the best fit to the data." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#regression-with-spatial-correlation", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#regression-with-spatial-correlation", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Regression with spatial correlation", + "text": "Regression with spatial correlation\nWe have seen above that the gstat package allows us to estimate the variogram of the residuals of a linear model. In our example, the magnesium concentration was modeled as a function of pH, with spatially correlated residuals.\nAnother tool to fit this same type of model is the gls function of the nlme package, which is included with the installation of R.\nThis function applies the generalized least squares method to fit linear regression models when the residuals are not independent or when the residual variance is not the same for all observations. Since the estimates of the coefficients depend on the estimated correlations between the residuals and the residuals themselves depend on the coefficients, the model is fitted by an iterative algorithm:\n\nA classical linear regression model (without correlation) is fitted to obtain residuals.\nThe spatial correlation model (variogram) is fitted with those residuals.\nThe regression coefficients are re-estimated, now taking into account the correlations.\n\nSteps 2 and 3 are repeated until the estimates are stable at a desired precision.\nHere is the application of this method to the same model for the magnesium concentration in the oxford dataset. In the correlation argument of gls, we specify an exponential correlation model as a function of our spatial coordinates and we include a possible nugget effect.\nIn addition to the exponential correlation corExp, the gls function can also estimate a Gaussian (corGaus) or spherical (corSpher) model.\n\nlibrary(nlme)\ngls_mg <- gls(MG1 ~ PH1, oxford, \n correlation = corExp(form = ~ XCOORD + YCOORD, nugget = TRUE))\nsummary(gls_mg)\n\nGeneralized least squares fit by REML\n Model: MG1 ~ PH1 \n Data: oxford \n AIC BIC logLik\n 1278.65 1292.751 -634.325\n\nCorrelation Structure: Exponential spatial correlation\n Formula: ~XCOORD + YCOORD \n Parameter estimate(s):\n range nugget \n478.0322964 0.2944753 \n\nCoefficients:\n Value Std.Error t-value p-value\n(Intercept) 391.1387 50.42343 7.757084 0\nPH1 -41.0836 6.15662 -6.673079 0\n\n Correlation: \n (Intr)\nPH1 -0.891\n\nStandardized residuals:\n Min Q1 Med Q3 Max \n-2.1846957 -0.6684520 -0.3687813 0.4627580 3.1918604 \n\nResidual standard error: 53.8233 \nDegrees of freedom: 126 total; 124 residual\n\n\nTo compare this result with the adjusted variogram above, the parameters given by gls must be transformed. The range has the same meaning in both cases and corresponds to 478 m for the result of gls. The global variance of the residuals is the square of Residual standard error. The nugget effect here (0.294) is expressed as a fraction of that variance. Finally, to obtain the partial sill of the exponential part, the nugget effect must be subtracted from the total variance.\nAfter performing these calculations, we can give these parameters to the vgm function of gstat to superimpose this variogram estimated by gls on our variogram of the residuals of the classical linear model.\n\ngls_range <- 478\ngls_var <- 53.823^2\ngls_nugget <- 0.294 * gls_var\ngls_psill <- gls_var - gls_nugget\n\ngls_vgm <- vgm(\"Exp\", psill = gls_psill, range = gls_range, nugget = gls_nugget)\n\nplot(var_mg, gls_vgm, col = \"black\", ylim = c(0, 4000))\n\n\n\n\nDoes the model fit the data less well here? In fact, this empirical variogram represented by the points was obtained from the residuals of the linear model ignoring the spatial correlation, so it is a biased estimate of the actual spatial correlations. The method is still adequate to quickly check if spatial correlations are present. However, to simultaneously fit the regression coefficients and the spatial correlation parameters, the generalized least squares (GLS) approach is preferable and will produce more accurate estimates.\nFinally, note that the result of the gls model also gives the AIC, which we can use to compare the fit of different models (with different predictors or different forms of spatial correlation)." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#exercise", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#exercise", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Exercise", + "text": "Exercise\nThe bryo_belg.csv dataset is adapted from the data of this study:\n\nNeyens, T., Diggle, P.J., Faes, C., Beenaerts, N., Artois, T. et Giorgi, E. (2019) Mapping species richness using opportunistic samples: a case study on ground-floor bryophyte species richness in the Belgian province of Limburg. Scientific Reports 9, 19122. https://doi.org/10.1038/s41598-019-55593-x\n\nThis data frame shows the specific richness of ground bryophytes (richness) for different sampling points in the Belgian province of Limburg, with their position (x, y) in km, in addition to information on the proportion of forest (forest) and wetlands (wetland) in a 1 km^2$ cell containing the sampling point.\n\nbryo_belg <- read.csv(\"data/bryo_belg.csv\")\nhead(bryo_belg)\n\n richness forest wetland x y\n1 9 0.2556721 0.5036614 228.9516 220.8869\n2 6 0.6449114 0.1172068 227.6714 219.8613\n3 5 0.5039905 0.6327003 228.8252 220.1073\n4 3 0.5987329 0.2432942 229.2775 218.9035\n5 2 0.7600775 0.1163538 209.2435 215.2414\n6 10 0.6865434 0.0000000 210.4142 216.5579\n\n\nFor this exercise, we will use the square root of the specific richness as the response variable. The square root transformation often allows to homogenize the variance of the count data in order to apply a linear regression.\n\nFit a linear model of the transformed species richness to the proportion of forest and wetlands, without taking into account spatial correlations. What is the effect of the two predictors in this model?\nCalculate the empirical variogram of the model residuals in (a). Does there appear to be a spatial correlation between the points?\n\nNote: The cutoff argument to the variogram function specifies the maximum distance at which the variogram is calculated. You can manually adjust this value to get a good view of the sill.\n\nRe-fit the linear model in (a) with the gls function in the nlme package, trying different types of spatial correlations (exponential, Gaussian, spherical). Compare the models (including the one without spatial correlation) with the AIC.\nWhat is the effect of the proportion of forests and wetlands according to the model in (c)? Explain the differences between the conclusions of this model and the model in (a)." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#conditional-autoregressive-car-model", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#conditional-autoregressive-car-model", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Conditional autoregressive (CAR) model", + "text": "Conditional autoregressive (CAR) model\nIn the conditional autoregressive model, the value of \\(z_i\\) for the region \\(i\\) follows a normal distribution: its mean depends on the value \\(z_j\\) of neighbouring regions, multiplied by the weight \\(w_{ij}\\) and a correlation coefficient \\(\\rho\\); its standard deviation \\(\\sigma_{z_i}\\) may vary from one region to another.\n\\[z_i \\sim \\text{N}\\left(\\sum_j \\rho w_{ij} z_j,\\sigma_{z_i} \\right)\\]\nIn this model, if \\(w_{ij}\\) is a binary matrix (0 for non-neighbours, 1 for neighbours), then \\(\\rho\\) is the coefficient of partial correlation between neighbouring regions. This is similar to a first-order autoregressive model in the context of time series, where the autoregression coefficient indicates the partial correlation." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#simultaneous-autoregressive-sar-model", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#simultaneous-autoregressive-sar-model", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Simultaneous autoregressive (SAR) model", + "text": "Simultaneous autoregressive (SAR) model\nIn the simultaneous autoregressive model, the value of \\(z_i\\) is given directly by the sum of contributions from neighbouring values \\(z_j\\), multiplied by \\(\\rho w_{ij}\\), with an independent residual \\(\\nu_i\\) of standard deviation \\(\\sigma_z\\).\n\\[z_i = \\sum_j \\rho w_{ij} z_j + \\nu_i\\]\nAt first glance, this looks like a temporal autoregressive model. However, there is an important conceptual difference. For temporal models, the causal influence is directed in only one direction: \\(v(t-2)\\) affects \\(v(t-1)\\) which then affects \\(v(t)\\). For a spatial model, each \\(z_j\\) that affects \\(z_i\\) depends in turn on \\(z_i\\). Thus, to determine the joint distribution of \\(z\\), a system of equations must be solved simultaneously (hence the name of the model).\nFor this reason, although this model resembles the formula of CAR model, the solutions of the two models differ and in the case of SAR, the coefficient \\(\\rho\\) is not directly equal to the partial correlation due to each neighbouring region.\nFor more details on the mathematical aspects of these models, see the article by Ver Hoef et al. (2018) suggested in reference.\nFor the moment, we will consider SAR and CAR as two types of possible models to represent a spatial correlation on a network. We can always fit several models and compare them with the AIC to choose the best form of correlation or the best weight matrix.\nThe CAR and SAR models share an advantage over geostatistical models in terms of efficiency. In a geostatistical model, spatial correlations are defined between each pair of points, although they become negligible as distance increases. For a CAR or SAR model, only neighbouring regions contribute and most weights are equal to 0, making these models faster to fit than a geostatistical model when the data are massive." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#definition-of-the-neighbourhood-network", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#definition-of-the-neighbourhood-network", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Definition of the neighbourhood network", + "text": "Definition of the neighbourhood network\nThe poly2nb function of the spdep package defines a neighbourhood network from polygons. The result vois is a list of 125 elements where each element contains the indices of the neighbouring (bordering) polygons of a given polygon.\n\nvois <- poly2nb(elect2018)\nvois[[1]]\n\n[1] 2 37 63 88 101 117\n\n\nThus, the first riding (Abitibi-Est) has 6 neighbouring ridings, for which the names can be found as follows:\n\nelect2018$circ[vois[[1]]]\n\n[1] \"Abitibi-Ouest\" \"Gatineau\" \n[3] \"Laviolette-Saint-Maurice\" \"Pontiac\" \n[5] \"Rouyn-Noranda-Témiscamingue\" \"Ungava\" \n\n\nWe can illustrate this network by extracting the coordinates of the center of each district, creating a blank map with plot(elect2018[\"geometry\"]), then adding the network as an additional layer with plot(vois, add = TRUE, coords = coords).\n\ncoords <- st_centroid(elect2018) %>%\n st_coordinates()\nplot(elect2018[\"geometry\"])\nplot(vois, add = TRUE, col = \"red\", coords = coords)\n\n\n\n\nWe can “zoom” on southern Québec by choosing the limits xlim and ylim.\n\nplot(elect2018[\"geometry\"], \n xlim = c(400000, 800000), ylim = c(100000, 500000))\nplot(vois, add = TRUE, col = \"red\", coords = coords)\n\n\n\n\nWe still have to add weights to each network link with the nb2listw function. The style of weights “B” corresponds to binary weights, i.e. 1 for the presence of link and 0 for the absence of link between two ridings.\nOnce these weights are defined, we can verify with Moran’s test whether there is a significant autocorrelation of votes obtained by the CAQ between neighbouring ridings.\n\npoids <- nb2listw(vois, style = \"B\")\n\nmoran.test(elect2018$propCAQ, poids)\n\n\n Moran I test under randomisation\n\ndata: elect2018$propCAQ \nweights: poids \n\nMoran I statistic standard deviate = 13.148, p-value < 2.2e-16\nalternative hypothesis: greater\nsample estimates:\nMoran I statistic Expectation Variance \n 0.680607768 -0.008064516 0.002743472 \n\n\nThe value \\(I = 0.68\\) is very significant judging by the \\(p\\)-value of the test.\nLet’s verify if the spatial correlation persists after taking into account the four characteristics of the population, therefore by inspecting the residuals of a linear model including these four predictors.\n\nelect_lm <- lm(propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, data = elect2018)\nsummary(elect_lm)\n\n\nCall:\nlm(formula = propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, \n data = elect2018)\n\nResiduals:\n Min 1Q Median 3Q Max \n-30.9890 -4.4878 0.0562 6.2653 25.8146 \n\nCoefficients:\n Estimate Std. Error t value Pr(>|t|) \n(Intercept) 1.354e+01 1.836e+01 0.737 0.463 \nage_moy -9.170e-01 3.855e-01 -2.378 0.019 * \npct_frn 4.588e+01 5.202e+00 8.820 1.09e-14 ***\npct_prp 3.582e+01 6.527e+00 5.488 2.31e-07 ***\nrev_med -2.624e-05 2.465e-04 -0.106 0.915 \n---\nSignif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n\nResidual standard error: 9.409 on 120 degrees of freedom\nMultiple R-squared: 0.6096, Adjusted R-squared: 0.5965 \nF-statistic: 46.84 on 4 and 120 DF, p-value: < 2.2e-16\n\nmoran.test(residuals(elect_lm), poids)\n\n\n Moran I test under randomisation\n\ndata: residuals(elect_lm) \nweights: poids \n\nMoran I statistic standard deviate = 6.7047, p-value = 1.009e-11\nalternative hypothesis: greater\nsample estimates:\nMoran I statistic Expectation Variance \n 0.340083290 -0.008064516 0.002696300 \n\n\nMoran’s \\(I\\) has decreased but remains significant, so some of the previous correlation was induced by these predictors, but there remains a spatial correlation due to other factors." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#spatial-autoregression-models", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#spatial-autoregression-models", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Spatial autoregression models", + "text": "Spatial autoregression models\nFinally, we fit SAR and CAR models to these data with the spautolm (spatial autoregressive linear model) function of spatialreg. Here is the code for a SAR model including the effect of the same four predictors.\n\nelect_sar <- spautolm(propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, \n data = elect2018, listw = poids)\nsummary(elect_sar)\n\n\nCall: spautolm(formula = propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, \n data = elect2018, listw = poids)\n\nResiduals:\n Min 1Q Median 3Q Max \n-23.08342 -4.10573 0.24274 4.29941 23.08245 \n\nCoefficients: \n Estimate Std. Error z value Pr(>|z|)\n(Intercept) 15.09421119 16.52357745 0.9135 0.36098\nage_moy -0.70481703 0.32204139 -2.1886 0.02863\npct_frn 39.09375061 5.43653962 7.1909 6.435e-13\npct_prp 14.32329345 6.96492611 2.0565 0.03974\nrev_med 0.00016730 0.00023209 0.7208 0.47101\n\nLambda: 0.12887 LR test value: 42.274 p-value: 7.9339e-11 \nNumerical Hessian standard error of lambda: 0.012069 \n\nLog likelihood: -433.8862 \nML residual variance (sigma squared): 53.028, (sigma: 7.282)\nNumber of observations: 125 \nNumber of parameters estimated: 7 \nAIC: 881.77\n\n\nThe value given by Lambda in the summary corresponds to the coefficient \\(\\rho\\) in our description of the model. The likelihood-ratio test (LR test) confirms that this residual spatial correlation (after controlling for the effect of predictors) is significant.\nThe estimated effects for the predictors are similar to those of the linear model without spatial correlation. The effects of mean age, fraction of francophones and fraction of homeowners remain significant, although their magnitude has decreased somewhat.\nTo fit a CAR rather than SAR model, we must specify family = \"CAR\".\n\nelect_car <- spautolm(propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, \n data = elect2018, listw = poids, family = \"CAR\")\nsummary(elect_car)\n\n\nCall: spautolm(formula = propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, \n data = elect2018, listw = poids, family = \"CAR\")\n\nResiduals:\n Min 1Q Median 3Q Max \n-21.73315 -4.24623 -0.24369 3.44228 23.43749 \n\nCoefficients: \n Estimate Std. Error z value Pr(>|z|)\n(Intercept) 16.57164696 16.84155327 0.9840 0.325128\nage_moy -0.79072151 0.32972225 -2.3981 0.016478\npct_frn 38.99116707 5.43667482 7.1719 7.399e-13\npct_prp 17.98557474 6.80333470 2.6436 0.008202\nrev_med 0.00012639 0.00023106 0.5470 0.584364\n\nLambda: 0.15517 LR test value: 40.532 p-value: 1.9344e-10 \nNumerical Hessian standard error of lambda: 0.0026868 \n\nLog likelihood: -434.7573 \nML residual variance (sigma squared): 53.9, (sigma: 7.3416)\nNumber of observations: 125 \nNumber of parameters estimated: 7 \nAIC: 883.51\n\n\nFor a CAR model with binary weights, the value of Lambda (which we called \\(\\rho\\)) directly gives the partial correlation coefficient between neighbouring districts. Note that the AIC here is slightly higher than the SAR model, so the latter gave a better fit." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#exercise-3", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#exercise-3", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Exercise", + "text": "Exercise\nThe rls_covid dataset, in shapefile format, contains data on detected COVID-19 cases (cas), number of cases per 1000 people (taux_1k) and the population density (dens_pop) in each of Quebec’s local health service networks (RLS) (Source: Data downloaded from the Institut national de santé publique du Québec as of January 17, 2021).\n\nrls_covid <- read_sf(\"data/rls_covid.shp\")\nhead(rls_covid)\n\nSimple feature collection with 6 features and 5 fields\nGeometry type: MULTIPOLYGON\nDimension: XY\nBounding box: xmin: 785111.2 ymin: 341057.8 xmax: 979941.5 ymax: 541112.7\nProjected CRS: Conique_conforme_de_Lambert_du_MTQ_utilis_e_pour_Adresse_Qu_be\n# A tibble: 6 × 6\n RLS_code RLS_nom cas taux_1k dens_…¹ geometry\n \n1 0111 RLS de Kamouraska 152 7.34 6.76 (((827028.3 412772.4, 82…\n2 0112 RLS de Rivière-du-Lo… 256 7.34 19.6 (((855905 452116.9, 8557…\n3 0113 RLS de Témiscouata 81 4.26 4.69 (((911829.4 441311.2, 91…\n4 0114 RLS des Basques 28 3.3 5.35 (((879249.6 471975.6, 87…\n5 0115 RLS de Rimouski 576 9.96 15.5 (((917748.1 503148.7, 91…\n6 0116 RLS de La Mitis 76 4.24 5.53 (((951316 523499.3, 9525…\n# … with abbreviated variable name ¹​dens_pop\n\n\nFit a linear model of the number of cases per 1000 as a function of population density (it is suggested to apply a logarithmic transform to the latter). Check whether the model residuals are correlated between bordering RLS with a Moran’s test and then model the same data with a conditional autoregressive model." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#reference", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#reference", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Reference", + "text": "Reference\nVer Hoef, J.M., Peterson, E.E., Hooten, M.B., Hanks, E.M. and Fortin, M.-J. (2018) Spatial autoregressive models for statistical inference from ecological data. Ecological Monographs 88: 36-59." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#data", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#data", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Data", + "text": "Data\nThe gambia dataset found in the geoR package presents the results of a study of malaria prevalence among children of 65 villages in The Gambia. We will use a slightly transformed version of the data found in the file gambia.csv.\n\nlibrary(geoR)\n\ngambia <- read.csv(\"data/gambia.csv\")\nhead(gambia)\n\n id_village x y pos age netuse treated green phc\n1 1 349.6313 1458.055 1 1783 0 0 40.85 1\n2 1 349.6313 1458.055 0 404 1 0 40.85 1\n3 1 349.6313 1458.055 0 452 1 0 40.85 1\n4 1 349.6313 1458.055 1 566 1 0 40.85 1\n5 1 349.6313 1458.055 0 598 1 0 40.85 1\n6 1 349.6313 1458.055 1 590 1 0 40.85 1\n\n\nHere are the fields in that dataset:\n\nid_village: Identifier of the village.\nx and y: Spatial coordinates of the village (in kilometers, based on UTM coordinates).\npos: Binary response, whether the child tested positive for malaria.\nage: Age of the child in days.\nnetuse: Whether or not the child sleeps under a bed net.\ntreated: Whether or not the bed net is treated.\ngreen: Remote sensing based measure of greenness of vegetation (measured at the village level).\nphc: Presence or absence of a public health centre for the village.\n\nWe can count the number of positive cases and total children tested by village to map the fraction of positive cases (or prevalence, prev).\n\n# Create village-level dataset\ngambia_agg <- group_by(gambia, id_village, x, y, green, phc) %>%\n summarize(pos = sum(pos), total = n()) %>%\n mutate(prev = pos / total) %>%\n ungroup()\n\n`summarise()` has grouped output by 'id_village', 'x', 'y', 'green'. You can\noverride using the `.groups` argument.\n\nhead(gambia_agg)\n\n# A tibble: 6 × 8\n id_village x y green phc pos total prev\n \n1 1 350. 1458. 40.8 1 17 33 0.515\n2 2 359. 1460. 40.8 1 19 63 0.302\n3 3 360. 1460. 40.1 0 7 17 0.412\n4 4 364. 1497. 40.8 0 8 24 0.333\n5 5 366. 1460. 40.8 0 10 26 0.385\n6 6 367. 1463. 40.8 0 7 18 0.389\n\n\n\nggplot(gambia_agg, aes(x = x, y = y)) +\n geom_point(aes(color = prev)) +\n geom_path(data = gambia.borders, aes(x = x / 1000, y = y / 1000)) +\n coord_fixed() +\n theme_minimal() +\n scale_color_viridis_c()\n\n\n\n\nWe use the gambia.borders dataset from the geoR package to trace the country boundaries with geom_path. Since those boundaries are in meters, we divide by 1000 to get the same scale as our points. We also use coord_fixed to ensure a 1:1 aspect ratio between the axes and use the viridis color scale, which makes it easier to visualize a continuous variable compared with the default gradient scale in ggplot2.\nBased on this map, there seems to be spatial correlation in malaria prevalence, with the eastern cluster of villages showing more high prevalence values (yellow-green) and the middle cluster showing more low prevalence values (purple)." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#non-spatial-glmm", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#non-spatial-glmm", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Non-spatial GLMM", + "text": "Non-spatial GLMM\nFor this first example, we will ignore the spatial aspect of the data and model the presence of malaria (pos) as a function of the use of a bed net (netuse) and the presence of a public health centre (phc). Since we have a binary response, we need to use a logistic regression model (a GLM). Since we have predictors at both the individual and village level, and we expect that children of the same village have more similar probabilities of having malaria even after accounting for those predictors, we need to add a random effect of the village. The result is a GLMM that we fit using the glmer function in the lme4 package.\n\nlibrary(lme4)\n\nmod_glmm <- glmer(pos ~ netuse + phc + (1 | id_village), \n data = gambia, family = binomial)\nsummary(mod_glmm)\n\nGeneralized linear mixed model fit by maximum likelihood (Laplace\n Approximation) [glmerMod]\n Family: binomial ( logit )\nFormula: pos ~ netuse + phc + (1 | id_village)\n Data: gambia\n\n AIC BIC logLik deviance df.resid \n 2428.0 2450.5 -1210.0 2420.0 2031 \n\nScaled residuals: \n Min 1Q Median 3Q Max \n-2.1286 -0.7120 -0.4142 0.8474 3.3434 \n\nRandom effects:\n Groups Name Variance Std.Dev.\n id_village (Intercept) 0.8149 0.9027 \nNumber of obs: 2035, groups: id_village, 65\n\nFixed effects:\n Estimate Std. Error z value Pr(>|z|) \n(Intercept) 0.1491 0.2297 0.649 0.5164 \nnetuse -0.6044 0.1442 -4.190 2.79e-05 ***\nphc -0.4985 0.2604 -1.914 0.0556 . \n---\nSignif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n\nCorrelation of Fixed Effects:\n (Intr) netuse\nnetuse -0.422 \nphc -0.715 -0.025\n\n\nAccording to these results, both netuse and phc result in a decrease of malaria prevalence, although the effect of phc is not significant at a threshold \\(\\alpha = 0.05\\). The intercept (0.149) is the logit of the probability of malaria presence for a child with no bednet and no public health centre, but it is the mean intercept across all villages, and there is a lot of variation between villages, based on the random effect standard deviation of 0.90. We can get the estimated intercept for each village with the function coef:\n\nhead(coef(mod_glmm)$id_village)\n\n (Intercept) netuse phc\n1 0.93727515 -0.6043602 -0.4984835\n2 0.09204843 -0.6043602 -0.4984835\n3 0.22500620 -0.6043602 -0.4984835\n4 -0.46271089 -0.6043602 -0.4984835\n5 0.13680037 -0.6043602 -0.4984835\n6 -0.03723346 -0.6043602 -0.4984835\n\n\nSo for example, the intercept for village 1 is around 0.94, equivalent to a probability of 72%:\n\nplogis(0.937)\n\n[1] 0.7184933\n\n\nwhile the intercept in village 2 is equivalent to a probability of 52%:\n\nplogis(0.092)\n\n[1] 0.5229838\n\n\nThe DHARMa package provides a general method for checking whether the residuals of a GLMM are distributed according to the specified model and whether there is any residual trend. The package works by simulating replicates of each observation according to the fitted model and then determining a “standardized residual”, which is the relative position of the observed value with respect to the simulated values, e.g. 0 if the observation is smaller than all the simulations, 0.5 if it is in the middle, etc. If the model represents the data well, each value of the standardized residual between 0 and 1 should be equally likely, so the standardized residuals should produce a uniform distribution between 0 and 1.\nThe simulateResiduals function performs the calculation of the standardized residuals, then the plot function plots the diagnostic graphs with the results of certain tests.\n\nlibrary(DHARMa)\nres_glmm <- simulateResiduals(mod_glmm)\nplot(res_glmm)\n\n\n\n\nThe graph on the left is a quantile-quantile plot of standardized residuals. The results of three statistical tests also also shown: a Kolmogorov-Smirnov (KS) test which checks whether there is a deviation from the theoretical distribution, a dispersion test that checks whether there is underdispersion or overdispersion, and an outlier test based on the number of residuals that are more extreme than all the simulations. Here, we get a significant result for the outliers, though the message indicates that this result might have an inflated type I error rate in this case.\nOn the right, we generally get a graph of standardized residuals (in y) as a function of the rank of the predicted values, in order to check for any leftover trend in the residual. Here, the predictions are binned by quartile, so it might be better to instead aggregate the predictions and residuals by village, which we can do with the recalculateResiduals function.\n\nplot(recalculateResiduals(res_glmm, group = gambia$id_village))\n\nDHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details\n\n\n\n\n\nThe plot to the right now shows individual points, along with a quantile regression for the 1st quartile, the median and the 3rd quartile. In theory, these three curves should be horizontal straight lines (no leftover trend in the residuals vs. predictions). The curve for the 3rd quartile (in red) is significantly different from a horizontal line, which could indicate some systematic effect that is missing from the model." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#spatial-glmm-with-spamm", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#spatial-glmm-with-spamm", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Spatial GLMM with spaMM", + "text": "Spatial GLMM with spaMM\nThe spaMM (spatial mixed models) package is a relatively new R package that can perform approximate maximum likelihood estimation of parameters for GLMM with spatial dependence, modelled either as a Gaussian process or with a CAR (we will see the latter in the last section). The package implements different algorithms, but there is a single fitme function that chooses the appropriate algorithm for each model type. For example, here is the same (non-spatial) model as above fit with spaMM.\n\nlibrary(spaMM)\n\nmod_spamm_glmm <- fitme(pos ~ netuse + phc + (1 | id_village),\n data = gambia, family = binomial)\nsummary(mod_spamm_glmm)\n\nformula: pos ~ netuse + phc + (1 | id_village)\nEstimation of lambda by ML (p_v approximation of logL).\nEstimation of fixed effects by ML (p_v approximation of logL).\nfamily: binomial( link = logit ) \n ------------ Fixed effects (beta) ------------\n Estimate Cond. SE t-value\n(Intercept) 0.1491 0.2287 0.6519\nnetuse -0.6045 0.1420 -4.2567\nphc -0.4986 0.2593 -1.9231\n --------------- Random effects ---------------\nFamily: gaussian( link = identity ) \n --- Variance parameters ('lambda'):\nlambda = var(u) for u ~ Gaussian; \n id_village : 0.8151 \n --- Coefficients for log(lambda):\n Group Term Estimate Cond.SE\n id_village (Intercept) -0.2045 0.2008\n# of obs: 2035; # of groups: id_village, 65 \n ------------- Likelihood values -------------\n logLik\nlogL (p_v(h)): -1210.016\n\n\nNote that the estimates of the fixed effects as well as the variance of random effects are nearly identical to those obtained by glmer above.\nWe can now use spaMM to fit the same model with the addition of spatial correlations between villages. In the formula of the model, this is represented as a random effect Matern(1 | x + y), which means that the intercepts are spatially correlated between villages following a Matérn correlation function of coordinates (x, y). The Matérn function is a flexible function for spatial correlation that includes a shape parameter \\(\\nu\\) (nu), so that when \\(\\nu = 0.5\\) it is equivalent to the exponential correlation but as \\(\\nu\\) grows to large values, it approaches a Gaussian correlation. We could let the function estimate \\(\\nu\\), but here we will fix it to 0.5 with the fixed argument of fitme.\n\nmod_spamm <- fitme(pos ~ netuse + phc + Matern(1 | x + y) + (1 | id_village),\n data = gambia, family = binomial, fixed = list(nu = 0.5))\n\nIncrease spaMM.options(separation_max=<.>) to at least 21 if you want to check separation (see 'help(separation)').\n\nsummary(mod_spamm)\n\nformula: pos ~ netuse + phc + Matern(1 | x + y) + (1 | id_village)\nEstimation of corrPars and lambda by ML (p_v approximation of logL).\nEstimation of fixed effects by ML (p_v approximation of logL).\nEstimation of lambda by 'outer' ML, maximizing logL.\nfamily: binomial( link = logit ) \n ------------ Fixed effects (beta) ------------\n Estimate Cond. SE t-value\n(Intercept) 0.06861 0.3352 0.2047\nnetuse -0.51719 0.1407 -3.6757\nphc -0.44416 0.2052 -2.1648\n --------------- Random effects ---------------\nFamily: gaussian( link = identity ) \n --- Correlation parameters:\n 1.nu 1.rho \n0.50000000 0.05128692 \n --- Variance parameters ('lambda'):\nlambda = var(u) for u ~ Gaussian; \n x + y : 0.6421 \n id_village : 0.1978 \n# of obs: 2035; # of groups: x + y, 65; id_village, 65 \n ------------- Likelihood values -------------\n logLik\nlogL (p_v(h)): -1197.968\n\n\nLet’s first check the random effects of the model. The spatial correlation function has a parameter rho equal to 0.0513. This parameter in spaMM is the inverse of the range, so here the range of exponential correlation is 1/0.0513 or around 19.5 km. There are now two variance prameters, the one identified as x + y is the long-range variance (i.e. sill) for the exponential correlation model whereas the one identified as id_village shows the non-spatially correlated portion of the variation between villages.\nIn fact, while we left the random effects (1 | id_village) in the formula to represent the non-spatial portion of variation between villages, we could also represent this with a nugget effect in the geostatistical model. In both cases, it would represent the idea that even two villages very close to each other would have different baseline prevalences in the model.\nBy default, the Matern function has no nugget effect, but we can add one by specifying a non-zero Nugget in the initial parameter list init.\n\nmod_spamm2 <- fitme(pos ~ netuse + phc + Matern(1 | x + y),\n data = gambia, family = binomial, fixed = list(nu = 0.5),\n init = list(Nugget = 0.1))\n\nIncrease spaMM.options(separation_max=<.>) to at least 21 if you want to check separation (see 'help(separation)').\n\nsummary(mod_spamm2)\n\nformula: pos ~ netuse + phc + Matern(1 | x + y)\nEstimation of corrPars and lambda by ML (p_v approximation of logL).\nEstimation of fixed effects by ML (p_v approximation of logL).\nEstimation of lambda by 'outer' ML, maximizing logL.\nfamily: binomial( link = logit ) \n ------------ Fixed effects (beta) ------------\n Estimate Cond. SE t-value\n(Intercept) 0.06861 0.3352 0.2047\nnetuse -0.51719 0.1407 -3.6757\nphc -0.44416 0.2052 -2.1648\n --------------- Random effects ---------------\nFamily: gaussian( link = identity ) \n --- Correlation parameters:\n 1.nu 1.Nugget 1.rho \n0.50000000 0.23551027 0.05128692 \n --- Variance parameters ('lambda'):\nlambda = var(u) for u ~ Gaussian; \n x + y : 0.8399 \n# of obs: 2035; # of groups: x + y, 65 \n ------------- Likelihood values -------------\n logLik\nlogL (p_v(h)): -1197.968\n\n\nAs you can see, all estimates are the same, except that the variance of the spatial portion (sill) is now 0.84 and the nugget is equal to a fraction 0.235 of that sill, so a variance of 0.197, which is the same as the id_village random effect in the version above. Thus the two formulations are equivalent.\nNow, recall the coefficients we obtained for the non-spatial GLMM:\n\nsummary(mod_glmm)$coefficients\n\n Estimate Std. Error z value Pr(>|z|)\n(Intercept) 0.1490596 0.2296971 0.6489399 5.163772e-01\nnetuse -0.6043602 0.1442448 -4.1898243 2.791706e-05\nphc -0.4984835 0.2604083 -1.9142382 5.558973e-02\n\n\nIn the spatial version, both fixed effects have moved slightly towards zero, but the standard error of the effect of phc has decreased. It is interesting that the inclusion of spatial dependence has allowed us to estimate more precisely the effect of having a public health centre in the village. This would not always be the case: for a predictor that is also strongly correlated in space, spatial correlation in the response makes it harder to estimate the effect of this predictor, since it is confounded with the spatial effect. However, for a predictor that is not correlated in space, including the spatial effect reduces the residual (non-spatial) variance and may thus increase the precision of the predictor’s effect.\nThe spaMM package is also compatible with DHARMa for residual diagnostics. (You can in fact ignore the warning that it is not in the class of supported models, this is due to using the fitme function rather than a specific algorithm function in spaMM.)\n\nres_spamm <- simulateResiduals(mod_spamm2)\nplot(res_spamm)\n\nDHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details\n\n\n\n\nplot(recalculateResiduals(res_spamm, group = gambia$id_village))\n\nDHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details\n\n\n\n\n\nFinally, while we will show how to make and visualize spatial predictions below, we can produce a quick map of the estimated spatial effects in a spaMM model with the filled.mapMM function.\n\nfilled.mapMM(mod_spamm2)" + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#gaussian-process-models-vs.-smoothing-splines", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#gaussian-process-models-vs.-smoothing-splines", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Gaussian process models vs. smoothing splines", + "text": "Gaussian process models vs. smoothing splines\nIf you are familiar with generalized additive models (GAM), you might think that the spatial variation in malaria prevalence (as shown in the map above) could be represented by a 2D smoothing spline (as a function of \\(x\\) and \\(y\\)) within a GAM.\nThe code below fits the GAM equivalent of our Gaussian process GLMM above with the gam function in the mgcv package. The spatial effect is represented by the 2D spline s(x, y) whereas the non-spatial random effect of village is represented by s(id_village, bs = \"re\"), which is the same as (1 | id_village) in the previous models. Note that for the gam function, categorical variables must be explicitly converted to factors.\n\nlibrary(mgcv)\ngambia$id_village <- as.factor(gambia$id_village)\nmod_gam <- gam(pos ~ netuse + phc + s(id_village, bs = \"re\") + s(x, y), \n data = gambia, family = binomial)\n\nTo visualize the 2D spline, we will use the gratia package.\n\nlibrary(gratia)\ndraw(mod_gam)\n\n\n\n\nNote that the plot of the spline s(x, y) (top right) does not extend too far from the locations of the data (other areas are blank). In this graph, we can also see that the village random effects follow the expected Gaussian distribution (top left).\nNext, we will use both the spatial GLMM from the previous section and this GAMM to predict the mean prevalence on a spatial grid of points contained in the file gambia_pred.csv. The graph below adds those prediction points (in black) on the previous map of the data points.\n\ngambia_pred <- read.csv(\"data/gambia_pred.csv\")\n\nggplot(gambia_agg, aes(x = x, y = y)) +\n geom_point(data = gambia_pred) +\n geom_point(aes(color = prev)) +\n geom_path(data = gambia.borders, aes(x = x / 1000, y = y / 1000)) +\n coord_fixed() +\n theme_minimal() +\n scale_color_viridis_c()\n\n\n\n\nTo make predictions from the GAMM model at those points, the code below goes through the following steps:\n\nAll predictors in the model must be in the prediction data frame, so we add constant values of netuse and phc (both equal to 1) for all points. Thus, we will make predictions of malaria prevalence in the case where a net is used and a public health centre is present. We also add a constant id_village, although it will not be used in predictions (see below).\nWe call the predict function on the output of gam to produce predictions at the new data points (argument newdata), including standard errors (se.fit = TRUE) and excluding the village random effects, so the prediction is made for an “average village”. The resulting object gam_pred will have columns fit (mean prediction) and se.fit (standard error). Those predictions and standard errors are on the link (logit) scale.\nWe add the original prediction data frame to gam_pred with cbind.\nWe add columns for the mean prediction and 50% confidence interval boundaries (mean \\(\\pm\\) 0.674 standard error), converted from the logit scale to the probability scale with plogis. We choose a 50% interval since a 95% interval may be too wide here to contrast the different predictions on the map at the end of this section.\n\n\ngambia_pred <- mutate(gambia_pred, netuse = 1, phc = 1, id_village = 1)\n\ngam_pred <- predict(mod_gam, newdata = gambia_pred, se.fit = TRUE, \n exclude = \"s(id_village)\")\ngam_pred <- cbind(gambia_pred, as.data.frame(gam_pred))\ngam_pred <- mutate(gam_pred, pred = plogis(fit), \n lo = plogis(fit - 0.674 * se.fit), # 50% CI\n hi = plogis(fit + 0.674 * se.fit))\n\nNote: The reason we do not make predictions directly on the probability (response) scale is that the normal formula for confidence intervals applies more accurately on the logit scale. Adding a certain number of standard errors around the mean on the probability scale would lead to less accurate intervals and maybe even confidence intervals outside the possible range (0, 1) for a probability.\nWe apply the same strategy to make predictions from the spaMM spatial GLMM model. There are a few differences in the predict method compared with the GAMM case.\n\nThe argument binding = \"fit\" means that mean predictions (fit column) will be attached to the prediction dataset and returned as spamm_pred.\nThe variances = list(linPred = TRUE) tells predict to calculate the variance of the linear predictor (so the square of the standard error). However, it appears as an attribute predVar in the output data frame rather than a se.fit column, so we move it to a column on the next line.\n\n\nspamm_pred <- predict(mod_spamm, newdata = gambia_pred, type = \"link\",\n binding = \"fit\", variances = list(linPred = TRUE))\nspamm_pred$se.fit <- sqrt(attr(spamm_pred, \"predVar\"))\nspamm_pred <- mutate(spamm_pred, pred = plogis(fit), \n lo = plogis(fit - 0.674 * se.fit),\n hi = plogis(fit + 0.674 * se.fit))\n\nFinally, we combine both sets of predictions as different rows of a pred_all dataset with bind_rows. The name of the dataset each prediction originates from (gam or spamm) will appear in the “model” column (argument .id). To simplify production of the next plot, we then use pivot_longer in the tidyr package to change the three columns “pred”, “lo” and “hi” to two columns, “stat” and “value” (pred_tall has thus three rows for every row in pred_all).\n\npred_all <- bind_rows(gam = gam_pred, spamm = spamm_pred, .id = \"model\")\n\nlibrary(tidyr)\npred_tall <- pivot_longer(pred_all, c(pred, lo, hi), names_to = \"stat\",\n values_to = \"value\")\n\nHaving done these steps, we can finally look at the prediction maps (mean, lower and upper bounds of the 50% confidence interval) with ggplot. The original data points are shown in red.\n\nggplot(pred_tall, aes(x = x, y = y)) +\n geom_point(aes(color = value)) +\n geom_point(data = gambia_agg, color = \"red\", size = 0) +\n coord_fixed() +\n facet_grid(stat~model) +\n scale_color_viridis_c() +\n theme_minimal()\n\n\n\n\nWhile both models agree that there is a higher prevalence near the eastern cluster of villages, the GAMM also estimates a higher prevalence at a few points (western edge and around the center) where there is no data. This is an artifact of the shape of the spline fit around the data points, since a spline is meant to fit a global, although nonlinear, trend. In contrast, the geostatistical model represents the spatial effect as local correlations and reverts to the overall mean prevalence when far from any data points, which is a safer assumption. This is one reason to choose a geostatistical / Gaussian process model in this case." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#bayesian-methods-for-glmms-with-gaussian-processes", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#bayesian-methods-for-glmms-with-gaussian-processes", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Bayesian methods for GLMMs with Gaussian processes", + "text": "Bayesian methods for GLMMs with Gaussian processes\nBayesian models provide a flexible framework to express models with complex dependence structure among the data, including spatial dependence. However, fitting a Gaussian process model with a fully Bayesian approach can be slow, due the need to compute a spatial covariance matrix between all point pairs at each iteration.\nThe INLA (integrated nested Laplace approximation) method performs an approximate calculation of the Bayesian posterior distribution, which makes it suitable for spatial regression problems. We do not cover it in this course, but I recommend the textbook by Paula Moraga (in the references section below) that provides worked examples of using INLA for various geostatistical and areal data models, in the context of epidemiology, including models with both space and time dependence. The book presents the same Gambia malaria data as an example of a geostatistical dataset, which inspired its use in this course." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#reference-1", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#reference-1", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Reference", + "text": "Reference\nMoraga, Paula (2019) Geospatial Health Data: Modeling and Visualization with R-INLA and Shiny. Chapman & Hall/CRC Biostatistics Series. Available online at https://www.paulamoraga.com/book-geospatial/." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#plan-du-cours", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#plan-du-cours", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Plan du cours", + "text": "Plan du cours\n\n\n\nJour\nSujets\n\n\n\n\n1\n• Introduction aux statistiques spatiales • Analyse des patrons de points \n\n\n2\n• Corrélation spatiale d’une variable • Modèles géostatistiques\n\n\n3\n• Données aréales • Indice de Moran • Modèles d’autorégression spatiale • Analyse des données aréales dans R\n\n\n4\n• GLMM avec processus spatial gaussien • GLMM avec autorégression spatiale" + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#types-danalyses-spatiales", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#types-danalyses-spatiales", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Types d’analyses spatiales", + "text": "Types d’analyses spatiales\nDans le cadre de cette formation, nous discuterons de trois types d’analyses spatiales: l’analyse des patrons de points, les modèles géostatistiques et les modèles de données aréales.\nDans l’analyse des patrons de points, nous avons des données ponctuelles représentant la position d’individus ou d’événements dans une région d’étude et nous supposons que tous les individus ou événements ont été recensés dans cette région. Cette analyse s’intéresse à la distribution des positions des points eux-mêmes. Voici quelques questions typiques de l’analyse des patrons de points:\n\nLes points sont-ils disposés aléatoirement ou agglomérés?\nDeux types de points sont-ils disposés indépendamment?\n\nLes modèles géostatistiques visent à représenter la distribution spatiale de variables continues qui sont mesurés à certains points d’échantillonnage. Ils supposent que les mesures de ces variables à différents points sont corrélées en fonction de la distance entre ces points. Parmi les applications des modèles géostatistiques, notons le lissage des données spatiales (ex.: produire une carte d’une variable sur l’ensemble d’une région en fonction des mesures ponctuelles) et la prédiction de ces variables pour des points non-échantillonnés.\nLes données aréales sont des mesures prises non pas à des points, mais pour des régions de l’espace représentées par des polygones (ex.: divisions du territoire, cellules d’une grille). Les modèles représentant ces types de données définissent un réseau de voisinage reliant les régions et incluent une corrélation spatiale entre régions voisines." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#stationnarité-et-isotropie", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#stationnarité-et-isotropie", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Stationnarité et isotropie", + "text": "Stationnarité et isotropie\nPlusieurs analyses spatiales supposent que les variables sont stationnaires dans l’espace. Comme pour la stationnarité dans le domaine temporel, cette propriété signifie que les statistiques sommaires (moyenne, variance et corrélations entre mesures d’une variable) ne varient pas avec une translation dans l’espace. Par exemple, la corrélation spatiale entre deux points peut dépendre de la distance les séparant, mais pas de leur position absolue.\nEn particulier, il ne peut pas y avoir de tendance à grande échelle (souvent appelée gradient dans un contexte spatial), ou bien cette tendance doit être prise en compte afin de modéliser la corrélation spatiale des résidus.\nDans le cas de l’analyse des patrons de points, la stationnarité (aussi appelée homogénéité dans ce contexte) signifie que la densité des points ne suit pas de tendance à grande échelle.\nDans un modèle statistique isotropique, les corrélations spatiales entre les mesures à deux points dépendent seulement de la distance entre ces points, pas de la direction. Dans ce cas, les statistiques sommaires ne varient pas si on effectue une rotation dans l’espace." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#données-géoréférencées", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#données-géoréférencées", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Données géoréférencées", + "text": "Données géoréférencées\nLes études environnementales utilisent de plus en plus de données provenant de sources de données géospatiales, c’est-à-dire des variables mesurées sur une grande partie du globe (ex.: climat, télédétection). Le traitement de ces données requiert des concepts liés aux systèmes d’information géographique (SIG), qui ne sont pas couverts dans cet atelier, alors que nous nous concentrons sur les aspects statistiques de données variant dans l’espace.\nL’utilisation de données géospatiales ne signifie pas nécessairement qu’il faut avoir recours à des statistiques spatiales. Par exemple, il est courant d’extraire les valeurs de ces variables géographiques à des points d’étude pour expliquer une réponse biologique observée sur le terrain. Dans ce cas, l’utilisation de statistiques spatiales est seulement nécessaire en présence d’une corrélation spatiale dans les résidus, après avoir tenu compte de l’effet des prédicteurs." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#patron-de-points-et-processus-ponctuel", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#patron-de-points-et-processus-ponctuel", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Patron de points et processus ponctuel", + "text": "Patron de points et processus ponctuel\nUn patron de points (point pattern) décrit la position spatiale (le plus souvent en 2D) d’individus ou d’événements, représentés par des points, dans une aire d’étude donnée, souvent appelée la fenêtre d’observation.\nOn suppose que chaque point a une étendue spatiale négligeable par rapport aux distances entre les points. Des méthodes plus complexes existent pour traiter des patrons spatiaux d’objets qui ont une largeur non-néligeable, mais ce sujet dépasse la portée de cet atelier.\nUn processus ponctuel (point process) est un modèle statistique qui peut être utilisé pour simuler des patrons de points ou expliquer un patron de points observé." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#structure-spatiale-totalement-aléatoire", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#structure-spatiale-totalement-aléatoire", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Structure spatiale totalement aléatoire", + "text": "Structure spatiale totalement aléatoire\nUne structure spatiale totalement aléatoire (complete spatial randomness) est un des patrons les plus simples, qui sert de modèle nul pour évaluer les caractéristiques de patrons de points réels. Dans ce patron, la présence d’un point à une position donnée est indépendante de la présence de points dans un voisinage.\nLe processus créant ce patron est un processus de Poisson homogène. Selon ce modèle, le nombre de points dans toute région de superficie \\(A\\) suit une distribution de Poisson: \\(N(A) \\sim \\text{Pois}(\\lambda A)\\), où \\(\\lambda\\) est l’intensité du processus (i.e. la densité de points). \\(N\\) est indépendant entre deux régions disjointes, peu importe comment ces régions sont définies.\nDans le graphique ci-dessous, seul le patron à droite est totalement aléatoire. Le patron à gauche montre une agrégation des points (probabilité plus grande d’observer un point si on est à proximité d’un autre point), tandis que le patron du centre montre une répulsion (faible probabilité d’observer un point très près d’un autre)." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#analyse-exploratoire-ou-inférentielle-pour-un-patron-de-points", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#analyse-exploratoire-ou-inférentielle-pour-un-patron-de-points", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Analyse exploratoire ou inférentielle pour un patron de points", + "text": "Analyse exploratoire ou inférentielle pour un patron de points\nPlusieurs statistiques sommaires sont utilisées pour décrire les caractéristiques un patron de points. La plus simple est l’intensité \\(\\lambda\\), qui comme mentionné plus haut représente la densité de points par unité de surface. Si le patron de points est hétérogène, l’intensité n’est pas constante, mais dépend de la position: \\(\\lambda(x, y)\\).\nPar rapport à l’intensité qui est une statistique dite de premier ordre, les statistiques de second ordre décrivent comment la probabilité de présence d’un point dans une région dépend de la présence d’autres points. L’indice \\(K\\) de Ripley présenté dans la prochaine section est un exemple de statistique sommaire de second ordre.\nLes inférences statistiques réalisées sur des patrons de points consistent habituellement à tester l’hypothèse que le patron de points correspond à un modèle nul donné, par exemple une structure spatiale totalement aléatoire, ou un modèle nul plus complexe. Même pour les modèles nuls les plus simples, nous connaissons rarement la distribution théorique pour une statistique sommaire du patron de points sous le modèle nul. Les tests d’hypothèses sur les patrons de points sont donc réalisés par simulation: on simule un grand nombre de patrons de points à partir du modèle nul et on compare la distribution des statistiques sommaires qui nous intéressent pour ces simulations à la valeur des statistiques pour le patron de points observé." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#indice-k-de-ripley", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#indice-k-de-ripley", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Indice \\(K\\) de Ripley", + "text": "Indice \\(K\\) de Ripley\nL’indice de Ripley \\(K(r)\\) est défini comme le nombre moyen de points se trouvant dans un cercle de rayon \\(r\\) donné autour d’un point du patron, normalisé par l’intensité \\(\\lambda\\).\nPour un patron totalement aléatoire, le nombre moyen de points dans un cercle de rayon \\(r\\) est \\(\\lambda \\pi r^2\\), donc en théorie \\(K(r) = \\pi r^2\\) pour ce modèle nul. Une valeur de \\(K(r)\\) supérieure signifie qu’il y a agrégation des points à l’échelle \\(r\\), tandis qu’une valeur inférieure signifie qu’il y a une répulsion.\nEn pratique, \\(K(r)\\) est estimé pour un patron de points donné par l’équation:\n\\[ K(r) = \\frac{A}{n(n-1)} \\sum_i \\sum_{j > i} I \\left( d_{ij} \\le r \\right) w_{ij}\\]\noù \\(A\\) est l’aire de la fenêtre d’observation et \\(n\\) est le nombre de points du patron, donc \\(n(n-1)\\) est le nombre de paires de points distinctes. On fait la somme pour toutes les paires de points de la fonction indicatrice \\(I\\), qui prend une valeur de 1 si la distance entre les points \\(i\\) et \\(j\\) est inférieure ou égale à \\(r\\). Finalement, le terme \\(w_{ij}\\) permet de donner un poids supplémentaire à certaines paires de points pour tenir compte des effets de bordure, tel que discuté dans la section suivante.\nPar exemple, les graphiques ci-dessous présentent la fonction estimée \\(K(r)\\) pour les patrons illustrés ci-dessus, pour des valeurs de \\(r\\) allant jusqu’à 1/4 de la largeur de la fenêtre. La courbe pointillée rouge indique la valeur théorique pour une structure spatiale totalement aléatoire et la zone grise est une “enveloppe” produite par 99 simulations de ce modèle nul. Le patron agrégé montre un excès de voisins jusqu’à \\(r = 0.25\\) et le patron avec répulsion montre un déficit significatif de voisins pour les petites valeurs de \\(r\\).\n\n\n\n\n\nOutre le \\(K\\), il existe d’autres statistiques pour décrire les propriétés de second ordre du patron, par exemple la distance moyenne entre un point et ses \\(N\\) plus proches voisins. Vous pouvez consulter le manuel de Wiegand et Moloney (2013) suggéré en référence pour en apprendre plus sur différentes statistiques sommaires des patrons de points." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#effets-de-bordure", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#effets-de-bordure", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Effets de bordure", + "text": "Effets de bordure\nDans le contexte de l’analyse de patrons de points, l’effet de bordure (“edge effect”) est dû au fait que nous avons une connaissance incomplète du voisinage des points près du bord de la fenêtre d’observation, ce qui peut induire un biais dans le calcul des statistiques comme le \\(K\\) de Ripley.\nDifférentes méthodes ont été développées pour corriger le biais dû aux effets de bordure. Selon la méthode de Ripley, la contribution d’un voisin \\(j\\) situé à une distance \\(r\\) d’un point \\(i\\) reçoit un poids \\(w_{ij} = 1/\\phi_i(r)\\), où \\(\\phi_i(r)\\) est la fraction du cercle de rayon \\(r\\) autour de \\(i\\) contenu dans la fenêtre d’observation. Par exemple, si 2/3 du cercle se trouve dans la fenêtre, ce voisin compte pour 3/2 voisins dans le calcul d’une statistique comme \\(K\\).\n\nLa méthode de Ripley est une des plus simples pour corriger les effets de bordure, mais n’est pas nécessairement la plus efficace; notamment, les poids plus grands donnés à certaines paires de points tend à accroître la variance du calcul de la statistique. D’autres méthodes de correction sont présentées dans les manuels spécialisés, comme celui de Wiegand et Moloney (2013) en référence." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#exemple", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#exemple", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Exemple", + "text": "Exemple\nPour cet exemple, nous utilisons le jeu de données semis_xy.csv, qui représente les coordonnées \\((x, y)\\) de semis de deux espèces (sp, B = bouleau et P = peuplier) dans une placette de 15 x 15 m.\n\nsemis <- read.csv(\"data/semis_xy.csv\")\nhead(semis)\n\n x y sp\n1 14.73 0.05 P\n2 14.72 1.71 P\n3 14.31 2.06 P\n4 14.16 2.64 P\n5 14.12 4.15 B\n6 9.88 4.08 B\n\n\nLe package spatstat permet d’effectuer des analyses de patrons de point dans R. La première étape consiste à transformer notre tableau de données en objet ppp (patron de points) avec la fonction du même nom. Dans cette fonction, nous spécifions quelles colonnes contiennent les coordonnées x et y ainsi que les marques (marks), qui seront ici les codes d’espèce. Il faut aussi spécifier une fenêtre d’observation (window) à l’aide de la fonction owin, à laquelle nous indiquons les limites de la placette en x et y.\n\nlibrary(spatstat)\n\nsemis <- ppp(x = semis$x, y = semis$y, marks = as.factor(semis$sp),\n window = owin(xrange = c(0, 15), yrange = c(0, 15)))\nsemis\n\nMarked planar point pattern: 281 points\nMultitype, with levels = B, P \nwindow: rectangle = [0, 15] x [0, 15] units\n\n\nLes marques peuvent être numériques ou catégorielles. Notez que pour des marques catégorielles comme c’est le cas ici, il faut convertir explicitement la variable en facteur.\nLa fonction plot appliquée à un patron de points montre un diagramme du patron.\n\nplot(semis)\n\n\n\n\nLa fonction intensity calcule la densité des points de chaque espèce par unité de surface, ici en \\(m^2\\).\n\nintensity(semis)\n\n B P \n0.6666667 0.5822222 \n\n\nPour analyser d’abord séparément la distribution de chaque espèce, nous séparons le patron avec split. Puisque le patron contient des marques catégorielles, la séparation se fait automatiquement en fonction de la valeur des marques. Le résultat est une liste de deux patrons de points.\n\nsemis_split <- split(semis)\nplot(semis_split)\n\n\n\n\nLa fonction Kest calcule le \\(K\\) de Ripley pour une série de distances allant (par défaut) jusqu’à 1/4 de la largeur de la fenêtre. Ici, nous l’appliquons au premier patron (bouleau) en choisissant semis_split[[1]]. Notez que les doubles crochets sont nécessaires pour choisir un élément d’une liste dans R.\nL’argument correction = \"iso\" indique d’appliquer la méthode de Ripley pour corriger les effets de bordure.\n\nk <- Kest(semis_split[[1]], correction = \"iso\")\nplot(k)\n\n\n\n\nSelon ce graphique, il semble y avoir une excès de voisins à partir d’un rayon de 1 m. Pour vérifier s’il s’agit d’un écart significatif, nous produisons une enveloppe de simulation avec la fonction envelope. Le permier argument d’envelope est un patron de point auquel les simulations seront comparées, le deuxième une fonction à calculer (ici, Kest) pour chaque patron simulé, puis on y ajoute les arguments de la fonction Kest (ici, seulement correction).\n\nplot(envelope(semis_split[[1]], Kest, correction = \"iso\"))\n\nGenerating 99 simulations of CSR ...\n1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,\n81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99.\n\nDone.\n\n\n\n\n\nTel qu’indiqué par le message, cette fonction effectue par défaut 99 simulations de l’hypothèse nulle correspondant à une structure spatiale totalement aléatoire (CSR, pour complete spatial randomness).\nLa courbe observée sort de l’enveloppe des 99 simulations près de \\(r = 2\\). Il faut être prudent de ne pas interpréter trop rapidement un résultat sortant de l’enveloppe. Même s’il y a environ une probabilité de 1% d’obtenir un résultat plus extrême selon l’hypothèse nulle à une distance donnée, l’enveloppe est calculée pour un grand nombre de valeurs de la distance et nous n’effectuons pas de correction pour les comparaisons multiples. Ainsi, un écart significatif pour une très petite plage de valeurs de \\(r\\) peut être simplement dû au hasard.\n\nExercice 1\nEn regardant le graphique du deuxième patron de points (semis de peuplier), pouvez-vous prédire où se situera le \\(K\\) de Ripley par rapport à l’hypothèse nulle d’une structure spatiale totalement aléatoire? Vérifiez votre prédiction en calculant le \\(K\\) de Ripley pour ce patron de points dans R." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#effet-de-lhétérogénéité", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#effet-de-lhétérogénéité", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Effet de l’hétérogénéité", + "text": "Effet de l’hétérogénéité\nLe graphique ci-dessous illustre un patron de points hétérogène, c’est-à-dire qu’il présente un gradient d’intensité (plus de points à gauche qu’à droite).\n\n\n\n\n\nUn gradient de densité peut être confondu avec une agrégation des points, comme on peut voir sur le graphique du \\(K\\) de Ripley correspondant. En théorie, il s’agit de deux processus différents:\n\nHétérogénéité: La densité de points varie dans la région d’étude, par exemple dû au fait que certaines conditions locales sont plus propices à la présence de l’espèce étudiée.\nAgrégation: La densité moyenne des points est homogène, mais la présence d’un point augmente la présence d’autre points dans son voisinage, par exemple en raison d’interactions positives entre les individus.\n\nCependant, il peut être difficile de différencier les deux en pratique, surtout que certains patrons peuvent être à la fois hétérogènes et agrégés.\nPrenons l’exemple des semis de peuplier de l’exercice précédent. La fonction density appliquée à un patron de points effectue une estimation par noyau (kernel density estimation) de la densité des semis à travers la placette. Par défaut, cette fonction utilise un noyau gaussien avec un écart-type sigma spécifié dans la fonction, qui détermine l’échelle à laquelle les fluctuations de densité sont “lissées”. Ici, nous utilisons une valeur de 2 m pour sigma et nous représentons d’abord la densité estimée avec plot, avant d’y superposer les points (add = TRUE signifie que les points sont ajoutés au graphique existant plutôt que de créer un nouveau graphique).\n\ndens_p <- density(semis_split[[2]], sigma = 2)\nplot(dens_p)\nplot(semis_split[[2]], add = TRUE)\n\n\n\n\nPour mesurer l’agrégation ou la répulsion des points d’un patron hétérogène, nous devons utilisé la version non-homogène de la statistique \\(K\\) (Kinhom dans spatstat). Cette statistique est toujours égale au nombre moyen de voisins dans un rayon \\(r\\) d’un point du patron, mais plutôt que de normaliser ce nombre par l’intensité globale du patron, il est normalisé par l’estimation locale de la densité de points. Comme ci-dessus, nous spécifions sigma = 2 pour contrôler le niveau de lissage de l’estimation de la densité variable.\n\nplot(Kinhom(semis_split[[2]], sigma = 2, correction = \"iso\"))\n\n\n\n\nEn tenant compte de l’hétérogénéité du patron à une échelle sigma de 2 m, il semble donc y avoir un déficit de voisins à partir d’environ 1.5 m des points du patron. Il reste à voir si cette déviation est significative.\nComme précédemment, nous utilisons envelope pour simuler la statistique Kinhom sous le modèle nul. Cependant, ici le modèle nul n’est pas un processus de Poisson homogène (structure spatiale totalement aléatoire). Il s’agit plutôt d’un processus de Poisson hétérogène simulé par la fonction rpoispp(dens_p), c’est-à-dire que les points sont indépendants les uns des autres, mais leur densité est hétérogène et donnée par dens_p. L’argument simulate de la fonction envelope permet de spécifier une fonction utilisée pour les simulations sous le modèle nul; cette fonction doit avoir un argument, ici x, même s’il n’est pas utilisé.\nFinalement, en plus des arguments nécessaires pour Kinhom, soit sigma et correction, nous spécifions aussi nsim = 199 pour réaliser 199 simulations et nrank = 5 pour éliminer les 5 résultats les plus extrêmes de chaque côté de l’enveloppe, donc les 10 plus extrêmes sur 199, pour réaliser un intervalle contenant environ 95% de la probabilité sous l’hypothèse nulle.\n\nkhet_p <- envelope(semis_split[[2]], Kinhom, sigma = 2, correction = \"iso\",\n nsim = 199, nrank = 5, simulate = function(x) rpoispp(dens_p))\n\nGenerating 199 simulations by evaluating function ...\n1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40\n.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80\n.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120\n.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160\n.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.\n\nDone.\n\nplot(khet_p)\n\n\n\n\nNote: Pour un test d’hypothèse basé sur des simulations d’une hypothèse nulle, la valeur \\(p\\) est estimée par \\((m + 1)/(n + 1)\\), où \\(n\\) est le nombre de simulations et \\(m\\) est le nombre de simulations où la valeur de la statistique est plus extrême que celle des données observées. C’est pour cette raison qu’on choisit un nombre de simulations comme 99, 199, etc.\n\nExercice 2\nRépétez l’estimation de la densité hétérogène et le calcul de Kinhom avec un écart-type sigma de 5 plutôt que 2. Comment le niveau de lissage pour la densité influence-t-il les conclusions?\nPour différencier une variation de densité des points et d’une interaction (agrégation ou répulsion) entre ces points avec ce type d’analyse, il faut généralement supposer que les deux processus opèrent à différentes échelles. Typiquement, nous pouvons tester si les points sont agrégés à petite échelle après avoir tenu compte d’une variation de la densité à une échelle plus grande." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#relation-entre-deux-patrons-de-points", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#relation-entre-deux-patrons-de-points", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Relation entre deux patrons de points", + "text": "Relation entre deux patrons de points\nConsidérons un cas où nous avons deux patrons de points, par exemple la position des arbres de deux espèces dans une parcelle (points oranges et verts dans le graphique ci-dessous). Chacun des deux patrons peut présenter ou non des agrégations de points.\n\n\n\n\n\nSans égard à cette agrégation au niveau de l’espèce, nous voulons déterminer si les deux espèces sont disposées indépendamment. Autrement dit, la probabilité d’observer un arbre d’une espèce dépend-elle de la présence d’un arbre de l’autre espèce à une distance donnée?\nLa version bivariée du \\(K\\) de Ripley permet de répondre à cette question. Pour deux patrons désignés 1 et 2, l’indice \\(K_{12}(r)\\) calcule le nombre moyen de points du patron 2 dans un rayon \\(r\\) autour d’un point du patron 1, normalisé par la densité du patron 2.\nEn théorie, cet indice est symétrique, donc \\(K_{12}(r) = K_{21}(r)\\) et le résultat serait le même si on choisit les points du patron 1 ou 2 comme points “focaux” pour l’analyse. Cependant, l’estimation des deux quantités pour un patron observé peut différer, notamment en raison des effets de bord. La variabilité peut aussi être différente pour \\(K_{12}\\) et \\(K_{21}\\) entre les simulations d’un modèle nul, donc le test de l’hypothèse nulle peut avoir une puissance différente selon le choix de l’espèce focale.\nLe choix d’un modèle nul approprié est important ici. Afin de déterminer s’il existe une attraction ou une répulsion significative entre les deux patrons, il faut déplacer aléatoirement la position d’un des patrons relative à celle de l’autre patron, tout en conservant la structure spatiale de chaque patron pris isolément.\nUne des façons d’effectuer cette randomisation consiste à décaler l’un des deux patrons horizontalement et/ou verticalement d’une distance aléatoire. La partie du patron qui “sort” d’un côté de la fenêtre est rattachée de l’autre côté. Cette méthode s’appelle une translation toroïdale (toroidal shift), car en connectant le haut et le bas ainsi que la gauche et la droite d’une surface rectangulaire, on obtient la forme d’un tore (un “beigne” en trois dimensions).\n\n\n\n\n\nLe graphique ci-dessus illustre une translation du patron vert vers la droite, tandis que le patron orange reste au même endroit. Les points verts dans la zone ombragée sont ramenés de l’autre côté. Notez que si cette méthode préserve de façon générale la structure de chaque patron tout en randomisant leur position relative, elle peut comporter certains inconvénients, comme de diviser des amas de points qui se trouvent près du point de coupure.\nVérifions maintenant s’il y a une dépendance entre la position des deux espèces (bouleau et peuplier) dans notre placette. La fonction Kcross calcule l’indice bivarié \\(K_{ij}\\), il faut spécifier quel type de point est considéré comme l’espèce focale \\(i\\) et l’espèce voisine \\(j\\).\n\nplot(Kcross(semis, i = \"P\", j = \"B\", correction = \"iso\"))\n\n\n\n\nIci, le \\(K\\) observé est inférieur à la valeur théorique, indiquant une répulsion possible des deux patrons.\nPour déterminer l’enveloppe du \\(K\\) selon l’hypothèse nulle d’indépendance des deux patrons, nous devons spécifier que les simulations doivent être basées sur une translation des patrons. Nous indiquons que les simulations doivent utiliser la fonction rshift (translation aléatoire) avec l’argument simulate = function(x) rshift(x, which = \"B\"); ici, l’argument x de simulate correspond au patron de points original et l’argument which indique quel type de points subit la translation. Comme pour le cas précédent, il faut répéter dans la fonction envelope les arguments nécessaires pour Kcross, soit i, j et correction.\n\nplot(envelope(semis, Kcross, i = \"P\", j = \"B\", correction = \"iso\", \n nsim = 199, nrank = 5, simulate = function(x) rshift(x, which = \"B\")))\n\nGenerating 199 simulations by evaluating function ...\n1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40\n.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80\n.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120\n.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160\n.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.\n\nDone.\n\n\n\n\n\nIci, la courbe observée se situe totalement dans l’enveloppe, donc nous ne rejetons pas l’hypothèse nulle d’indépendance des deux patrons.\n\nQuestions\n\nQuelle raison pourrait justifier ici notre choix d’effectuer la translation des points du bouleau plutôt que du peuplier?\nEst-ce que les simulations générées par translation aléatoire constitueraient un bon modèle nul si les deux patrons étaient hétérogènes?" + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#patrons-de-points-marqués", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#patrons-de-points-marqués", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Patrons de points marqués", + "text": "Patrons de points marqués\nLe jeu de données fir.csv contient les coordonnées \\((x, y)\\) de 822 sapins dans une placette d’un hectare et leur statut (A = vivant, D = mort) suivant une épidémie de tordeuse des bourgeons de l’épinette.\n\nfir <- read.csv(\"data/fir.csv\")\nhead(fir)\n\n x y status\n1 31.50 1.00 A\n2 85.25 30.75 D\n3 83.50 38.50 A\n4 84.00 37.75 A\n5 83.00 33.25 A\n6 33.25 0.25 A\n\n\n\nfir <- ppp(x = fir$x, y = fir$y, marks = as.factor(fir$status),\n window = owin(xrange = c(0, 100), yrange = c(0, 100)))\nplot(fir)\n\n\n\n\nSupposons que nous voulons vérifier si la mortalité des sapins est indépendante ou corrélée entre arbres rapprochés. En quoi cette question diffère-t-elle de l’exemple précédent où nous voulions savoir si la position des points de deux espèces était indépendante?\nDans l’exemple précédent, l’indépendance ou l’interaction entre les espèces référait à la formation du patron lui-même (que des semis d’une espèce s’établissent ou non à proximité de ceux de l’autre espèce). Ici, la caractéristique qui nous intéresse (survie des sapins) est postérieure à l’établissement du patron, en supposant que tous ces arbres étaient vivants d’abord et que certains sont morts suite à l’épidémie. Donc nous prenons la position des arbres comme fixe et nous voulons savoir si la distribution des statuts (mort, vivant) entre ces arbres est aléatoire ou présente un patron spatial.\nDans le manuel de Wiegand et Moloney, la première situation (établissement de semis de deux espèces) est appelé patron bivarié, donc il s’agit vraiment de deux patrons qui interagissent, tandis que la deuxième est un seul patron avec une marque qualitative. Le package spatstat dans R ne fait pas de différences entre les deux au niveau de la définition du patron (les types de points sont toujours représentés par l’argument marks), mais les méthodes d’analyse appliquées aux deux questions diffèrent.\nDans le cas d’un patron avec une marque qualitative, nous pouvons définir une fonction de connexion de marques (mark connection function) \\(p_{ij}(r)\\). Pour deux points séparés par une distance \\(r\\), cette fonction donne la probabilité que le premier point porte la marque \\(i\\) et le deuxième la marque \\(j\\). Selon l’hypothèse nulle où les marques sont indépendantes, cette probabilité est égale au produit des proportions de chaque marque dans le patron entier, \\(p_{ij}(r) = p_i p_j\\) indépendamment de \\(r\\).\nDans spatstat, la fonction de connexion de marques est calculée avec la fonction markconnect, où il faut spécifier les marques \\(i\\) et \\(j\\) ainsi que le type de correction des effets de bord. Dans notre exemple, nous voyons que deux points rapprochés ont moins de chance d’avoir une statut différent (A et D) que prévu selon l’hypothèse de distribution aléatoire et indépendante des marques (ligne rouge pointillée).\n\nplot(markconnect(fir, i = \"A\", j = \"D\", correction = \"iso\"))\n\n\n\n\nDans ce graphique, les ondulations dans la fonction sont dues à l’erreur d’estimation d’une fonction continue de \\(r\\) à partir d’un nombre limité de paires de points discrètes.\nPour simuler le modèle nul dans ce cas-ci, nous utilisons la fonction rlabel qui réassigne aléatoirement les marques parmi les points du patron, en maintenant la position des points.\n\nplot(envelope(fir, markconnect, i = \"A\", j = \"D\", correction = \"iso\", \n nsim = 199, nrank = 5, simulate = rlabel))\n\nGenerating 199 simulations by evaluating function ...\n1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40\n.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80\n.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120\n.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160\n.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.\n\nDone.\n\n\n\n\n\nNotez que puisque la fonction rlabel a un seul argument obligatoire correspondant au patron de points original, il n’était pas nécessaire de spécifier au long: simulate = function(x) rlabel(x).\nVoici les résultats pour les paires d’arbres du même statut A ou D:\n\npar(mfrow = c(1, 2))\nplot(envelope(fir, markconnect, i = \"A\", j = \"A\", correction = \"iso\", \n nsim = 199, nrank = 5, simulate = rlabel))\n\nGenerating 199 simulations by evaluating function ...\n1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40\n.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80\n.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120\n.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160\n.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.\n\nDone.\n\nplot(envelope(fir, markconnect, i = \"D\", j = \"D\", correction = \"iso\", \n nsim = 199, nrank = 5, simulate = rlabel))\n\nGenerating 199 simulations by evaluating function ...\n1, 2, 3, 4.6.8.10.12.14.16.18.20.22.24.26.28.30.32.34.36.38.40\n.42.44.46.48.50.52.54.56.58.60.62.64.66.68.70.72.74.76.78.80\n.82.84.86.88.90.92.94.96.98.100.102.104.106.108.110.112.114.116.118.120\n.122.124.126.128.130.132.134.136.138.140.142.144.146.148.150.152.154.156.158.160\n.162.164.166.168.170.172.174.176.178.180.182.184.186.188.190.192.194.196.198 199.\n\nDone.\n\n\n\n\n\nIl semble donc que la mortalité des sapins due à cette épidémie est agrégée spatialement, puisque les arbres situés à proximité l’un de l’autre ont une plus grande probabilité de partager le même statut que prévu par l’hypothèse nulle." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#références", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#références", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Références", + "text": "Références\nFortin, M.-J. et Dale, M.R.T. (2005) Spatial Analysis: A Guide for Ecologists. Cambridge University Press: Cambridge, UK.\nWiegand, T. et Moloney, K.A. (2013) Handbook of Spatial Point-Pattern Analysis in Ecology, CRC Press.\nLe jeu de données du dernier exemple est tiré des données de la Forêt d’enseignement et de recherche du Lac Duparquet (FERLD), disponibles sur Dryad en suivant ce lien." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#dépendance-intrinsèque-ou-induite", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#dépendance-intrinsèque-ou-induite", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Dépendance intrinsèque ou induite", + "text": "Dépendance intrinsèque ou induite\nIl existe deux types fondamentaux de dépendance spatiale sur une variable mesurée \\(y\\): une dépendance intrinsèque à \\(y\\), ou une dépendance induite par des variables externes influençant \\(y\\), qui sont elles-mêmes corrélées dans l’espace.\nPar exemple, supposons que l’abondance d’une espèce soit corrélée entre deux sites rapprochés:\n\ncette dépendance spatiale peut être induite si elle est due à une corrélation spatiale des facteurs d’habitat qui favorisent ou défavorisent l’espèce;\nou elle peut être intrinsèque si elle est due à la dispersion d’individus entre sites rapprochés.\n\nDans plusieurs cas, les deux types de dépendance affectent une variable donnée.\nSi la dépendance est simplement induite et que les variables externes qui en sont la cause sont incluses dans le modèle expliquant \\(y\\), alors les résidus du modèle seront indépendants et nous pouvons utiliser toutes les méthodes déjà vues qui ignorent la dépendance spatiale.\nCependant, si la dépendance est intrinsèque ou due à des influences externes non-mesurées, alors il faudra tenir compte de la dépendance spatiale des résidus dans le modèle." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#différentes-façons-de-modéliser-les-effets-spatiaux", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#différentes-façons-de-modéliser-les-effets-spatiaux", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Différentes façons de modéliser les effets spatiaux", + "text": "Différentes façons de modéliser les effets spatiaux\nDans cette formation, nous modéliserons directement les corrélations spatiales de nos données. Il est utile de comparer cette approche à d’autres façons d’inclure des aspects spatiaux dans un modèle statistique.\nD’abord, nous pourrions inclure des prédicteurs dans le modèle qui représentent la position (ex.: longitude, latitude). De tels prédicteurs peuvent être utiles pour détecter une tendance ou un gradient systématique à grande échelle, que cette tendance soit linéaire ou non (par exemple, avec un modèle additif généralisé).\nEn contraste à cette approche, les modèles que nous verrons maintenant servent à modéliser une corrélation spatiale dans les fluctuations aléatoires d’une variable (i.e., dans les résidus après avoir enlevé tout effet systématique).\nLes modèles mixtes utilisent des effets aléatoires pour représenter la non-indépendance de données sur la base de leur groupement, c’est-à-dire qu’après avoir tenu compte des effets fixes systématiques, les données d’un même groupe sont plus semblables (leur variation résiduelle est corrélée) par rapport aux données de groupes différents. Ces groupes étaient parfois définis selon des critères spatiaux (observations regroupées en sites).\nCependant, dans un contexte d’effet aléatoire de groupe, tous les groupes sont aussi différents les uns des autres, ex.: deux sites à 100 km l’un de l’autre ne sont pas plus ou moins semblables que deux sites distants de 2 km.\nLes méthodes que nous verrons ici et dans les prochains parties de la formation nous permettent donc ce modéliser la non-indépendance sur une échelle continue (plus proche = plus corrélé) plutôt que seulement discrète (hiérarchie de groupements)." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#variogramme", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#variogramme", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Variogramme", + "text": "Variogramme\nUn aspect central de la géostatistique est l’estimation du variogramme \\(\\gamma_z\\) de la variable \\(z\\). Le variogramme est égal à la moitié de l’écart carré moyen entre les valeurs de \\(z\\) pour deux points \\((x_i, y_i)\\) et \\((x_j, y_j)\\) séparés par une distance \\(h\\).\n\\[\\gamma_z(h) = \\frac{1}{2} \\text{E} \\left[ \\left( z(x_i, y_i) - z(x_j, y_j) \\right)^2 \\right]_{d_{ij} = h}\\]\nDans cette équation, la fonction \\(\\text{E}\\) avec l’indice \\(d_{ij}=h\\) désigne l’espérance statistique (autrement dit, la moyenne) de l’écart au carré entre les valeurs de \\(z\\) pour les points séparés par une distance \\(h\\).\nSi on préfère exprimer l’autocorrélation \\(\\rho_z(h)\\) entre mesures de \\(z\\) séparées par une distance \\(h\\), celle-ci est reliée au variogramme par l’équation:\n\\[\\gamma_z = \\sigma_z^2(1 - \\rho_z)\\] ,\noù \\(\\sigma_z^2\\) est la variance globale de \\(z\\).\nNotez que \\(\\gamma_z = \\sigma_z^2\\) si nous sommes à une distance où les mesures de \\(z\\) sont indépendantes, donc \\(\\rho_z = 0\\). Dans ce cas, on voit bien que \\(\\gamma_z\\) s’apparente à une variance, même s’il est parfois appelé “semivariogramme” ou “semivariance” en raison du facteur 1/2 dans l’équation ci-dessus." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#modèles-théoriques-du-variogramme", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#modèles-théoriques-du-variogramme", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Modèles théoriques du variogramme", + "text": "Modèles théoriques du variogramme\nPlusieurs modèles paramétriques ont été proposés pour représenter la corrélation spatiale en fonction de la distance entre points d’échantillonnage. Considérons d’abord une corrélation qui diminue de façon exponentielle:\n\\[\\rho_z(h) = e^{-h/r}\\]\nIci, \\(\\rho_z = 1\\) pour \\(h = 0\\) et la corréaltion est multipliée par \\(1/e \\approx 0.37\\) pour chaque augmentation de \\(r\\) de la distance. Dans ce contexte, \\(r\\) se nomme la portée (range) de la corrélation.\nÀ partir de l’équation ci-dessus, nous pouvons calculer le variogramme correspondant.\n\\[\\gamma_z(h) = \\sigma_z^2 (1 - e^{-h/r})\\]\nVoici une représentation graphique de ce variogramme.\n\n\n\n\n\nEn raison de la fonction exponentielle, la valeur de \\(\\gamma\\) à des grandes distances s’approche de la variance globale \\(\\sigma_z^2\\) sans exactement l’atteindre. Cette asymptote est appelée palier (sill) dans le contexte géostatistique et représentée par le symbole \\(s\\).\nFinalement, il n’est parfois pas réaliste de supposer une corrélation parfaite lorsque la distance tend vers 0, en raison d’une variation possible de \\(z\\) à très petite échelle. On peut ajouter au modèle un effet de pépite (nugget), noté \\(n\\), pour que \\(\\gamma\\) s’approche de \\(n\\) (plutôt que 0) si \\(h\\) tend vers 0. Le terme pépite provient de l’origine minière de ces techniques, où une pépite d’un minerai pourrait être la source d’une variation abrupte de la concentration à petite échelle.\nEn ajoutant l’effet de pépite, le reste du variogramme est “compressé” pour conserver le même palier, ce qui résulte en l’équation suivante.\n\\[\\gamma_z(h) = n + (s - n) (1 - e^{-h/r})\\]\nDans le package gstat que nous utiliserons ci-dessous, le terme \\((s - n)\\) est le palier partiel (partial sill, ou psill) pour la partie exponentielle.\n\n\n\n\n\nEn plus du modèle exponentiel, deux autres modèles théoriques courants pour le variogramme sont le modèle gaussien (où la corrélation suit une courbe demi-normale), ainsi que le modèle sphérique (où le variogramme augmente de façon linéaire au départ pour ensuite courber et atteindre le palier à une distance égale à sa portée \\(r\\)). Le modèle sphérique permet donc à la corrélation d’être exactement 0 à grande distance, plutôt que de s’approcher graduellement de zéro dans le cas des autres modèles.\n\n\n\n\n\n\n\n\nModèle\n\\(\\rho(h)\\)\n\\(\\gamma(h)\\)\n\n\n\n\nExponentiel\n\\(\\exp\\left(-\\frac{h}{r}\\right)\\)\n\\(s \\left(1 - \\exp\\left(-\\frac{h}{r}\\right)\\right)\\)\n\n\nGaussien\n\\(\\exp\\left(-\\frac{h^2}{r^2}\\right)\\)\n\\(s \\left(1 - \\exp\\left(-\\frac{h^2}{r^2}\\right)\\right)\\)\n\n\nSphérique \\((h < r)\\) *\n\\(1 - \\frac{3}{2}\\frac{h}{r} + \\frac{1}{2}\\frac{h^3}{r^3}\\)\n\\(s \\left(\\frac{3}{2}\\frac{h}{r} - \\frac{1}{2}\\frac{h^3}{r^3} \\right)\\)\n\n\n\n* Pour le modèle sphérique, \\(\\rho = 0\\) et \\(\\gamma = s\\) si \\(h \\ge r\\)." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#variogramme-empirique", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#variogramme-empirique", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Variogramme empirique", + "text": "Variogramme empirique\nPour estimer \\(\\gamma_z(h)\\) à partir de données empiriques, nous devons définir des classes de distance, donc grouper différentes distances dans une marge \\(\\pm \\delta\\) autour d’une distance \\(h\\), puis calculer l’écart-carré moyen pour les paires de points dans cette classe de distance.\n\\[\\hat{\\gamma_z}(h) = \\frac{1}{2 N_{\\text{paires}}} \\sum \\left[ \\left( z(x_i, y_i) - z(x_j, y_j) \\right)^2 \\right]_{d_{ij} = h \\pm \\delta}\\]\nNous verrons dans la partie suivante comment estimer un variogramme dans R." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#modèle-de-régression-avec-corrélation-spatiale", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#modèle-de-régression-avec-corrélation-spatiale", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Modèle de régression avec corrélation spatiale", + "text": "Modèle de régression avec corrélation spatiale\nL’équation suivante représente une régression linéaire multiple incluant une corrélation spatiale résiduelle:\n\\[v = \\beta_0 + \\sum_i \\beta_i u_i + z + \\epsilon\\]\nIci, \\(v\\) désigne la variable réponse et \\(u\\) les prédicteurs, pour ne pas confondre avec les coordonnées spatiales \\(x\\) et \\(y\\).\nEn plus du résidu \\(\\epsilon\\) qui est indépendant entre les observations, le modèle inclut un terme \\(z\\) qui représente la portion spatialement corrélée de la variance résiduelle.\nVoici une suggestions d’étapes à suivre pour appliquer ce type de modèle:\n\nAjuster le modèle de régression sans corrélation spatiale.\nVérifier la présence de corrélation spatiale à partir du variogramme empirique des résidus.\nAjuster un ou plusieurs modèles de régression avec corrélation spatiale et choisir celui qui montre le meilleur ajustement aux données." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#régression-avec-corrélation-spatiale", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#régression-avec-corrélation-spatiale", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Régression avec corrélation spatiale", + "text": "Régression avec corrélation spatiale\nNous avons vu ci-dessus que le package gstat permet d’estimer le variogramme des résidus d’un modèle linéaire. Dans notre exemple, la concentration de magnésium était modélisée en fonction du pH, avec des résidus spatialement corrélés.\nUn autre outil pour ajuster ce même type de modèle est la fonction gls du package nlme, qui est inclus avec l’installation de R.\nCette fonction applique la méthode des moindres carrés généralisés (generalized least squares) pour ajuster des modèles de régression linéaire lorsque les résidus ne sont pas indépendants ou lorsque la variance résiduelle n’est pas la même pour toutes les observations. Comme les estimés des coefficients dépendent de l’estimé des corrélations entre les résidus et que ces derniers dépendent eux-mêmes des coefficients, le modèle est ajusté par un algorithme itératif:\n\nOn ajuste un modèle de régression linéaire classique (sans corrélation) pour obtenir des résidus.\nOn ajuste le modèle de corrélation spatiale (variogramme) avec ses résidus.\nOn ré-estime les coefficients de la régression en tenant compte maintenant des corrélations.\n\nLes étapes 2 et 3 sont répétées jusqu’à ce que les estimés soient stables à une précision voulue.\nVoici l’application de cette méthode au même modèle pour la concentration de magnésium dans le jeu de données oxford. Dans l’argument correlation de gls, nous spécifions un modèle de corrélation exponentielle en fonction de nos coordonnées spatiales et indiquons que nous voulons aussi estimer un effet de pépite.\nEn plus de la corrélation exponentielle corExp, la fonction gls peut aussi estimer un modèle gaussien (corGaus) ou sphérique (corSpher).\n\nlibrary(nlme)\ngls_mg <- gls(MG1 ~ PH1, oxford, \n correlation = corExp(form = ~ XCOORD + YCOORD, nugget = TRUE))\nsummary(gls_mg)\n\nGeneralized least squares fit by REML\n Model: MG1 ~ PH1 \n Data: oxford \n AIC BIC logLik\n 1278.65 1292.751 -634.325\n\nCorrelation Structure: Exponential spatial correlation\n Formula: ~XCOORD + YCOORD \n Parameter estimate(s):\n range nugget \n478.0322964 0.2944753 \n\nCoefficients:\n Value Std.Error t-value p-value\n(Intercept) 391.1387 50.42343 7.757084 0\nPH1 -41.0836 6.15662 -6.673079 0\n\n Correlation: \n (Intr)\nPH1 -0.891\n\nStandardized residuals:\n Min Q1 Med Q3 Max \n-2.1846957 -0.6684520 -0.3687813 0.4627580 3.1918604 \n\nResidual standard error: 53.8233 \nDegrees of freedom: 126 total; 124 residual\n\n\nPour comparer ce résultat au variogramme ajusté ci-dessus, il faut transformer les paramètres donnés par gls. La portée (range) a le même sens dans les deux cas et correspond à 478 m pour le résultat de gls. La variance globale des résidus est le carré de Residual standard error. L’effet de pépite ici (0.294) est exprimé comme fraction de cette variance. Finalement, pour obtenir le palier partiel de la partie exponentielle, il faut soustraire l’effet de pépite de la variance totale.\nAprès avoir réalisé ces calculs, nous pouvons donner ces paramètres à la fonction vgm de gstat pour superposer ce variogramme estimé par gls à notre variogramme des résidus du modèle linéaire classique.\n\ngls_range <- 478\ngls_var <- 53.823^2\ngls_nugget <- 0.294 * gls_var\ngls_psill <- gls_var - gls_nugget\n\ngls_vgm <- vgm(\"Exp\", psill = gls_psill, range = gls_range, nugget = gls_nugget)\n\nplot(var_mg, gls_vgm, col = \"black\", ylim = c(0, 4000))\n\n\n\n\nEst-ce que le modèle est moins bien ajusté aux données ici? En fait, ce variogramme empirique représenté par les points avait été obtenu à partir des résidus du modèle linéaire ignorant la corrélation spatiale, donc c’est un estimé biaisé des corrélations spatiales réelles. La méthode est quand même adéquate pour vérifier rapidement s’il y a présence de corrélations spatiales. Toutefois, pour ajuster simultanément les coefficients de la régression et les paramètres de corrélation spatiale, l’approche des moindres carrés généralisés (GLS) est préférable et produira des estimés plus justes.\nFinalement, notez que le résultat du modèle gls donne aussi l’AIC, que nous pouvons utiliser pour comparer l’ajustement de différents modèles (avec différents prédicteurs ou différentes formes de corrélation spatiale)." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#exercice", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#exercice", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Exercice", + "text": "Exercice\nLe fichier bryo_belg.csv est adapté des données de l’étude:\n\nNeyens, T., Diggle, P.J., Faes, C., Beenaerts, N., Artois, T. et Giorgi, E. (2019) Mapping species richness using opportunistic samples: a case study on ground-floor bryophyte species richness in the Belgian province of Limburg. Scientific Reports 9, 19122. https://doi.org/10.1038/s41598-019-55593-x\n\nCe tableau de données indique la richesse spécifique des bryophytes au sol (richness) pour différents points d’échantillonnage de la province belge de Limbourg, avec leur position (x, y) en km, en plus de l’information sur la proportion de forêts (forest) et de milieux humides (wetland) dans une cellule de 1 km\\(^2\\) contenant le point d’échantillonnage.\n\nbryo_belg <- read.csv(\"data/bryo_belg.csv\")\nhead(bryo_belg)\n\n richness forest wetland x y\n1 9 0.2556721 0.5036614 228.9516 220.8869\n2 6 0.6449114 0.1172068 227.6714 219.8613\n3 5 0.5039905 0.6327003 228.8252 220.1073\n4 3 0.5987329 0.2432942 229.2775 218.9035\n5 2 0.7600775 0.1163538 209.2435 215.2414\n6 10 0.6865434 0.0000000 210.4142 216.5579\n\n\nPour cet exercice, nous utiliserons la racine carrée de la richesse spécifique comme variable réponse. La transformation racine carrée permet souvent d’homogénéiser la variance des données de comptage afin d’y appliquer une régression linéaire.\n\nAjustez un modèle linéaire de la richesse spécifique transformée en fonction de la fraction de forêt et de milieux humides, sans tenir compte des corrélations spatiales. Quel est l’effet des deux prédicteurs selon ce modèle?\nCalculez le variogramme empirique des résidus du modèle en (a). Semble-t-il y avoir une corrélation spatiale entre les points?\n\nNote: L’argument cutoff de la fonction variogram spécifie la distance maximale à laquelle le variogramme est calculé. Vous pouvez ajuster manuellement cette valeur pour bien voir le palier.\n\nRé-ajustez le modèle linéaire en (a) avec la fonction gls du package nlme, en essayant différents types de corrélations spatiales (exponentielle, gaussienne, sphérique). Comparez les modèles (incluant celui sans corrélation spatiale) avec l’AIC.\nQuel est l’effet de la fraction de forêts et de milieux humides selon le modèle en (c)? Expliquez les différences entre les conclusions de ce modèle et du modèle en (a)." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#autorégression-conditionnelle-car", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#autorégression-conditionnelle-car", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Autorégression conditionnelle (CAR)", + "text": "Autorégression conditionnelle (CAR)\nDans le modèle d’autorégression conditionnelle, la valeur de \\(z_i\\) pour la région \\(i\\) suit une distribution normale: sa moyenne dépend de la valeur \\(z_j\\) des régions voisines, multipliée par le poids \\(w_{ij}\\) et un coefficient de corrélation \\(\\rho\\); son écart-type \\(\\sigma_{z_i}\\) peut varier d’une région à l’autre.\n\\[z_i \\sim \\text{N}\\left(\\sum_j \\rho w_{ij} z_j,\\sigma_{z_i} \\right)\\]\nDans ce modèle, si \\(w_{ij}\\) est une matrice binaire (0 pour les non-voisins, 1 pour les voisins), alors \\(\\rho\\) est le coefficient de corrélation partielle entre régions voisines. Cela est semblable à un modèle autorégressif d’ordre 1 dans le contexte de séries temporelles, où le coefficient d’autorégression indique la corrélation partielle." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#autorégression-simultanée-sar", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#autorégression-simultanée-sar", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Autorégression simultanée (SAR)", + "text": "Autorégression simultanée (SAR)\nDans le modèle d’autorégression simultanée, la valeur de \\(z_i\\) est donnée directement par la somme de contributions des valeurs voisines \\(z_j\\), multipliées par \\(\\rho w_{ij}\\), avec un résidu indépendant \\(\\nu_i\\) d’écart-type \\(\\sigma_z\\).\n\\[z_i = \\sum_j \\rho w_{ij} z_j + \\nu_i\\]\nÀ première vue, cela ressemble à un modèle autorégressif temporel. Il existe cependant une différence conceptuelle importante. Pour les modèles temporels, l’influence causale est dirigée dans une seule direction: \\(v(t-2)\\) affecte \\(v(t-1)\\) qui affecte ensuite \\(v(t)\\). Pour un modèle spatial, chaque \\(z_j\\) qui affecte \\(z_i\\) dépend à son tour de \\(z_i\\). Ainsi, pour déterminer la distribution conjointe des \\(z\\), il faut résoudre simultanément (d’où le nom du modèle) un système d’équations.\nPour cette raison, même si ce modèle ressemble à la formule du modèle conditionnel (CAR), les solutions des deux modèles diffèrent et dans le cas du SAR, le coefficient \\(\\rho\\) n’est pas directement égal à la corrélation partielle due à chaque région voisine.\nPour plus de détails sur les aspects mathématiques de ces modèles, vous pouvez consulter l’article de Ver Hoef et al. (2018) suggéré en référence.\nPour l’instant, nous considérerons les SAR et les CAR comme deux types de modèles possibles pour représenter une corrélation spatiale sur un réseau. Nous pouvons toujours ajuster plusieurs modèles et les comparer avec l’AIC pour choisir la meilleure forme de la corrélation ou la meilleure matrice de poids.\nLes modèles CAR et SAR partagent un avantage sur les modèles géostatistiques au niveau de l’efficacité. Dans un modèle géostatistique, les corrélations spatiales sont définies entre chaque paire de points, même si elles deviennent négligeables lorsque la distance augmente. Pour un modèle CAR ou SAR, seules les régions voisines contribuent et la plupart des poids sont égaux à 0, ce qui rend ces modèles plus rapides à ajuster qu’un modèle géostatistique lorsque les données sont massives." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#définition-du-réseau-de-voisinage", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#définition-du-réseau-de-voisinage", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Définition du réseau de voisinage", + "text": "Définition du réseau de voisinage\nLa fonction poly2nb du package spdep définit un réseau de voisinage à partir de polygones. Le résultat vois est une liste de 125 éléments où chaque élément contient les indices des polygones voisins (limitrophes) d’un polygone donné.\n\nvois <- poly2nb(elect2018)\nvois[[1]]\n\n[1] 2 37 63 88 101 117\n\n\nAinsi, la première circonscription (Abitibi-Est) a 6 circonscriptions voisines, dont on peut trouver les noms ainsi:\n\nelect2018$circ[vois[[1]]]\n\n[1] \"Abitibi-Ouest\" \"Gatineau\" \n[3] \"Laviolette-Saint-Maurice\" \"Pontiac\" \n[5] \"Rouyn-Noranda-Témiscamingue\" \"Ungava\" \n\n\nNous pouvons illustrer ce réseau en faisant l’extraction des coordonnées du centre de chaque circonscription, en créant une carte muette avec plot(elect2018[\"geometry\"]), puis en ajoutant le réseau comme couche additionnelle avec plot(vois, add = TRUE, coords = coords).\n\ncoords <- st_centroid(elect2018) %>%\n st_coordinates()\nplot(elect2018[\"geometry\"])\nplot(vois, add = TRUE, col = \"red\", coords = coords)\n\n\n\n\nOn peut faire un “zoom” sur le sud du Québec en choisissant les limites xlim et ylim appropriées.\n\nplot(elect2018[\"geometry\"], \n xlim = c(400000, 800000), ylim = c(100000, 500000))\nplot(vois, add = TRUE, col = \"red\", coords = coords)\n\n\n\n\nIl nous reste à ajouter des poids à chaque lien du réseau avec la fonction nb2listw. Le style de poids “B” correspond aux poids binaires, soit 1 pour la présence de lien et 0 pour l’absence de lien entre deux circonscriptions.\nUne fois ces poids définis, nous pouvons vérifier avec le test de Moran s’il y a une autocorrélation significative des votes obtenus par la CAQ entre circonscriptions voisines.\n\npoids <- nb2listw(vois, style = \"B\")\n\nmoran.test(elect2018$propCAQ, poids)\n\n\n Moran I test under randomisation\n\ndata: elect2018$propCAQ \nweights: poids \n\nMoran I statistic standard deviate = 13.148, p-value < 2.2e-16\nalternative hypothesis: greater\nsample estimates:\nMoran I statistic Expectation Variance \n 0.680607768 -0.008064516 0.002743472 \n\n\nLa valeur de \\(I = 0.68\\) est très significative à en juger par la valeur \\(p\\) du test.\nVérifions si la corrélation spatiale persiste après avoir tenu compte des quatre caractéristiques de la population, donc en inspectant les résidus d’un modèle linéaire incluant ces quatre prédicteurs.\n\nelect_lm <- lm(propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, data = elect2018)\nsummary(elect_lm)\n\n\nCall:\nlm(formula = propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, \n data = elect2018)\n\nResiduals:\n Min 1Q Median 3Q Max \n-30.9890 -4.4878 0.0562 6.2653 25.8146 \n\nCoefficients:\n Estimate Std. Error t value Pr(>|t|) \n(Intercept) 1.354e+01 1.836e+01 0.737 0.463 \nage_moy -9.170e-01 3.855e-01 -2.378 0.019 * \npct_frn 4.588e+01 5.202e+00 8.820 1.09e-14 ***\npct_prp 3.582e+01 6.527e+00 5.488 2.31e-07 ***\nrev_med -2.624e-05 2.465e-04 -0.106 0.915 \n---\nSignif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n\nResidual standard error: 9.409 on 120 degrees of freedom\nMultiple R-squared: 0.6096, Adjusted R-squared: 0.5965 \nF-statistic: 46.84 on 4 and 120 DF, p-value: < 2.2e-16\n\nmoran.test(residuals(elect_lm), poids)\n\n\n Moran I test under randomisation\n\ndata: residuals(elect_lm) \nweights: poids \n\nMoran I statistic standard deviate = 6.7047, p-value = 1.009e-11\nalternative hypothesis: greater\nsample estimates:\nMoran I statistic Expectation Variance \n 0.340083290 -0.008064516 0.002696300 \n\n\nL’indice de Moran a diminué mais demeure significatif, donc une partie de la corrélation précédente était induite par ces prédicteurs, mais il reste une corrélation spatiale due à d’autres facteurs." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#modèles-dautorégression-spatiale", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#modèles-dautorégression-spatiale", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Modèles d’autorégression spatiale", + "text": "Modèles d’autorégression spatiale\nFinalement, nous ajustons des modèles SAR et CAR à ces données avec la fonction spautolm (spatial autoregressive linear model) de spatialreg. Voici le code pour un modèle SAR incluant l’effet des même quatre prédicteurs.\n\nelect_sar <- spautolm(propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, \n data = elect2018, listw = poids)\nsummary(elect_sar)\n\n\nCall: spautolm(formula = propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, \n data = elect2018, listw = poids)\n\nResiduals:\n Min 1Q Median 3Q Max \n-23.08342 -4.10573 0.24274 4.29941 23.08245 \n\nCoefficients: \n Estimate Std. Error z value Pr(>|z|)\n(Intercept) 15.09421119 16.52357745 0.9135 0.36098\nage_moy -0.70481703 0.32204139 -2.1886 0.02863\npct_frn 39.09375061 5.43653962 7.1909 6.435e-13\npct_prp 14.32329345 6.96492611 2.0565 0.03974\nrev_med 0.00016730 0.00023209 0.7208 0.47101\n\nLambda: 0.12887 LR test value: 42.274 p-value: 7.9339e-11 \nNumerical Hessian standard error of lambda: 0.012069 \n\nLog likelihood: -433.8862 \nML residual variance (sigma squared): 53.028, (sigma: 7.282)\nNumber of observations: 125 \nNumber of parameters estimated: 7 \nAIC: 881.77\n\n\nLa valeur donnée par Lambda dans le sommaire correspond au coefficient \\(\\rho\\) dans notre description du modèle. Le test du rapport de vraisemblance (LR test) confirme que cette corrélation spatiale résiduelle (après avoir tenu compte de l’effet des prédicteurs) est significative.\nLes effets estimés pour les prédicteurs sont semblables à ceux du modèle linéaire sans corrélation spatiale. Les effets de l’âge moyen, de la fraction de francophones et la fraction de propriétaires demeurent significatifs, bien que leur magnitude ait un peu diminué.\nPour évaluer un modèle CAR plutôt que SAR, nous devons spécifier family = \"CAR\".\n\nelect_car <- spautolm(propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, \n data = elect2018, listw = poids, family = \"CAR\")\nsummary(elect_car)\n\n\nCall: spautolm(formula = propCAQ ~ age_moy + pct_frn + pct_prp + rev_med, \n data = elect2018, listw = poids, family = \"CAR\")\n\nResiduals:\n Min 1Q Median 3Q Max \n-21.73315 -4.24623 -0.24369 3.44228 23.43749 \n\nCoefficients: \n Estimate Std. Error z value Pr(>|z|)\n(Intercept) 16.57164696 16.84155327 0.9840 0.325128\nage_moy -0.79072151 0.32972225 -2.3981 0.016478\npct_frn 38.99116707 5.43667482 7.1719 7.399e-13\npct_prp 17.98557474 6.80333470 2.6436 0.008202\nrev_med 0.00012639 0.00023106 0.5470 0.584364\n\nLambda: 0.15517 LR test value: 40.532 p-value: 1.9344e-10 \nNumerical Hessian standard error of lambda: 0.0026868 \n\nLog likelihood: -434.7573 \nML residual variance (sigma squared): 53.9, (sigma: 7.3416)\nNumber of observations: 125 \nNumber of parameters estimated: 7 \nAIC: 883.51\n\n\nPour un modèle CAR avec des poids binaires, la valeur de Lambda (que nous avions appelé \\(\\rho\\)) donne directement le coefficient de corrélation partielle entre circonscriptions voisines. Notez que l’AIC ici est légèrement supérieur au modèle SAR, donc ce dernier donnait un meilleur ajustement." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#exercice-3", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#exercice-3", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Exercice", + "text": "Exercice\nLe jeu de données rls_covid, en format shapefile, contient des données sur les cas de COVID-19 détectés, le nombre de cas par 1000 personnes (taux_1k) et la densité de population (dens_pop) dans chacun des réseaux locaux de service de santé (RLS) du Québec. (Source: Données téléchargées de l’Institut national de santé publique du Québec en date du 17 janvier 2021.)\n\nrls_covid <- read_sf(\"data/rls_covid.shp\")\nhead(rls_covid)\n\nSimple feature collection with 6 features and 5 fields\nGeometry type: MULTIPOLYGON\nDimension: XY\nBounding box: xmin: 785111.2 ymin: 341057.8 xmax: 979941.5 ymax: 541112.7\nProjected CRS: Conique_conforme_de_Lambert_du_MTQ_utilis_e_pour_Adresse_Qu_be\n# A tibble: 6 × 6\n RLS_code RLS_nom cas taux_1k dens_…¹ geometry\n \n1 0111 RLS de Kamouraska 152 7.34 6.76 (((827028.3 412772.4, 82…\n2 0112 RLS de Rivière-du-Lo… 256 7.34 19.6 (((855905 452116.9, 8557…\n3 0113 RLS de Témiscouata 81 4.26 4.69 (((911829.4 441311.2, 91…\n4 0114 RLS des Basques 28 3.3 5.35 (((879249.6 471975.6, 87…\n5 0115 RLS de Rimouski 576 9.96 15.5 (((917748.1 503148.7, 91…\n6 0116 RLS de La Mitis 76 4.24 5.53 (((951316 523499.3, 9525…\n# … with abbreviated variable name ¹​dens_pop\n\n\nAjustez un modèle linéaire du nombre de cas par 1000 en fonction de la densité de population (il est suggéré d’appliquer une transformation logarithmique à cette dernière). Vérifiez si les résidus du modèle sont corrélés entre RLS limitrophes avec un test de Moran, puis modélisez les mêmes données avec un modèle autorégressif conditionnel." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#référence", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#référence", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Référence", + "text": "Référence\nVer Hoef, J.M., Peterson, E.E., Hooten, M.B., Hanks, E.M. et Fortin, M.-J. (2018) Spatial autoregressive models for statistical inference from ecological data. Ecological Monographs 88: 36-59." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#données", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#données", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Données", + "text": "Données\nLe jeu de données gambia inclus avec le package geoR présente les résultats d’une étude sur la prévalence du paludisme chez les enfants de 65 villages en Gambie. Nous utiliserons une version légèrement transformée des données contenues dans le fichier gambia.csv.\n\nlibrary(geoR)\n\ngambia <- read.csv(\"data/gambia.csv\")\nhead(gambia)\n\n id_village x y pos age netuse treated green phc\n1 1 349.6313 1458.055 1 1783 0 0 40.85 1\n2 1 349.6313 1458.055 0 404 1 0 40.85 1\n3 1 349.6313 1458.055 0 452 1 0 40.85 1\n4 1 349.6313 1458.055 1 566 1 0 40.85 1\n5 1 349.6313 1458.055 0 598 1 0 40.85 1\n6 1 349.6313 1458.055 1 590 1 0 40.85 1\n\n\nVoici les champs de ce jeu de données:\n\nid_village: Identifiant du village.\nx and y: Coordonnées spatiales du village (en km, basé sur les coordonnées UTM).\npos: Réponse binaire, si l’enfant a eu un test positif du paludisme.\nage: Âge de l’enfant en jours.\nnetuse: Si l’enfant dort sous un moustiquaire ou non.\ntreated: Si le moustiquaire est traité ou non.\ngreen: Mesure de la végétation basée sur les données de télédétection (disponible à l’échelle du village).\nphc: Présence ou absence d’un centre de santé publique pour le village.\n\nNous pouvons compter le nombre de cas positifs et le nombre total d’enfants testés par village pour cartographier la fraction des cas positifs (ou prévalence, prev).\n\n# Jeu de données à l'échelle du village\ngambia_agg <- group_by(gambia, id_village, x, y, green, phc) %>%\n summarize(pos = sum(pos), total = n()) %>%\n mutate(prev = pos / total) %>%\n ungroup()\n\n`summarise()` has grouped output by 'id_village', 'x', 'y', 'green'. You can\noverride using the `.groups` argument.\n\nhead(gambia_agg)\n\n# A tibble: 6 × 8\n id_village x y green phc pos total prev\n \n1 1 350. 1458. 40.8 1 17 33 0.515\n2 2 359. 1460. 40.8 1 19 63 0.302\n3 3 360. 1460. 40.1 0 7 17 0.412\n4 4 364. 1497. 40.8 0 8 24 0.333\n5 5 366. 1460. 40.8 0 10 26 0.385\n6 6 367. 1463. 40.8 0 7 18 0.389\n\n\n\nggplot(gambia_agg, aes(x = x, y = y)) +\n geom_point(aes(color = prev)) +\n geom_path(data = gambia.borders, aes(x = x / 1000, y = y / 1000)) +\n coord_fixed() +\n theme_minimal() +\n scale_color_viridis_c()\n\n\n\n\nNous utilisons le jeu de données gambia.borders du package geoR pour tracer les frontières des pays avec geom_path. Comme ces frontières sont en mètres, nous les divisons par 1000 pour obtenir la même échelle que nos points. Nous utilisons également coord_fixed pour assurer un rapport d’aspect de 1:1 entre les axes et utilisons la palette de couleur viridis, qui permet de visualiser plus facilement une variable continue par rapport à la palette par défaut dans ggplot2.\nSur la base de cette carte, il semble y avoir une corrélation spatiale dans la prévalence du paludisme, le groupe de villages de l’est montrant des valeurs de prévalence plus élevées (jaune-vert) et le groupe du milieu montrant des valeurs de prévalence plus faibles (violet)." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#glmm-non-spatial", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#glmm-non-spatial", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "GLMM non spatial", + "text": "GLMM non spatial\nPour ce premier exemple, nous allons ignorer l’aspect spatial des données et modéliser la présence du paludisme (pos) en fonction de l’utilisation d’une moustiquaire (netuse) et de la présence d’un centre de santé publique (phc). Comme nous avons une réponse binaire, nous devons utiliser un modèle de régression logistique (un GLM). Comme nous avons des prédicteurs au niveau individuel et au niveau du village et que nous nous attendons à ce que les enfants d’un même village aient une probabilité plus similaire d’avoir le paludisme même après avoir pris en compte ces prédicteurs, nous devons ajouter un effet aléatoire du village. Le résultat est un GLMM que nous ajustons en utilisant la fonction glmer du package lme4.\n\nlibrary(lme4)\n\nmod_glmm <- glmer(pos ~ netuse + phc + (1 | id_village), \n data = gambia, family = binomial)\nsummary(mod_glmm)\n\nGeneralized linear mixed model fit by maximum likelihood (Laplace\n Approximation) [glmerMod]\n Family: binomial ( logit )\nFormula: pos ~ netuse + phc + (1 | id_village)\n Data: gambia\n\n AIC BIC logLik deviance df.resid \n 2428.0 2450.5 -1210.0 2420.0 2031 \n\nScaled residuals: \n Min 1Q Median 3Q Max \n-2.1286 -0.7120 -0.4142 0.8474 3.3434 \n\nRandom effects:\n Groups Name Variance Std.Dev.\n id_village (Intercept) 0.8149 0.9027 \nNumber of obs: 2035, groups: id_village, 65\n\nFixed effects:\n Estimate Std. Error z value Pr(>|z|) \n(Intercept) 0.1491 0.2297 0.649 0.5164 \nnetuse -0.6044 0.1442 -4.190 2.79e-05 ***\nphc -0.4985 0.2604 -1.914 0.0556 . \n---\nSignif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n\nCorrelation of Fixed Effects:\n (Intr) netuse\nnetuse -0.422 \nphc -0.715 -0.025\n\n\nD’après ces résultats, les variables netuse et phc sont toutes deux associées à une diminution de la prévalence du paludisme, bien que l’effet de phc ne soit pas significatif à un seuil \\(\\alpha = 0.05\\). L’ordonnée à l’origine (0.149) est le logit de la probabilité de présence du paludisme pour un enfant sans moustiquaire et sans centre de santé publique, mais c’est l’ordonnée à l’origine moyenne pour tous les villages. Il y a beaucoup de variation entre les villages selon l’écart-type de l’effet aléatoire (0.90). Nous pouvons obtenir l’ordonnée à l’origine estimée pour chaque village avec la fonction coef:\n\nhead(coef(mod_glmm)$id_village)\n\n (Intercept) netuse phc\n1 0.93727515 -0.6043602 -0.4984835\n2 0.09204843 -0.6043602 -0.4984835\n3 0.22500620 -0.6043602 -0.4984835\n4 -0.46271089 -0.6043602 -0.4984835\n5 0.13680037 -0.6043602 -0.4984835\n6 -0.03723346 -0.6043602 -0.4984835\n\n\nPar exemple, l’ordonnée à l’origine pour le village 1 est environ 0.94, équivalente à une probabilité de 72%:\n\nplogis(0.937)\n\n[1] 0.7184933\n\n\ntandis que celle pour le village 2 est équivalente à une probabilité de 52%:\n\nplogis(0.092)\n\n[1] 0.5229838\n\n\nLe package DHARMa fournit une méthode générale pour vérifier si les résidus d’un GLMM sont distribués selon le modèle spécifié et s’il existe une tendance résiduelle. Il simule des réplicats de chaque observation selon le modèle ajusté et détermine ensuite un “résidu standardisé”, qui est la position relative de la valeur observée par rapport aux valeurs simulées, par exemple 0 si l’observation est plus petite que toutes les simulations, 0.5 si elle se trouve au milieu, etc. Si le modèle représente bien les données, chaque valeur du résidu standardisé entre 0 et 1 doit avoir la même probabilité, de sorte que les résidus standardisés doivent produire une distribution uniforme entre 0 et 1.\nLa fonction simulateResiduals effectue le calcul des résidus standardisés, puis la fonction plot trace les graphiques de diagnostic avec les résultats de certains tests.\n\nlibrary(DHARMa)\nres_glmm <- simulateResiduals(mod_glmm)\nplot(res_glmm)\n\n\n\n\nLe graphique de gauche est un graphique quantile-quantile des résidus standardisés. Les résultats de trois tests statistiques sont également présentés: un test de Kolmogorov-Smirnov (KS) qui vérifie s’il y a un écart par rapport à la distribution théorique, un test de dispersion qui vérifie s’il y a une sous-dispersion ou une surdispersion et un test de valeurs aberrantes (outlier) basé sur le nombre de résidus qui sont plus extrêmes que toutes les simulations. Ici, nous obtenons un résultat significatif pour les valeurs aberrantes, bien que le message indique que ce résultat pourrait avoir un taux d’erreur de type I plus grand que prévu dans ce cas.\nÀ droite, nous obtenons généralement un graphique des résidus standardisés (en y) en fonction du rang des valeurs prédites, afin de vérifier l’absence de tendance résiduelle. Ici, les prédictions sont regroupées par quartile, il serait donc préférable d’agréger les prédictions et les résidus par village, ce que nous pouvons faire avec la fonction recalculateResiduals.\n\nplot(recalculateResiduals(res_glmm, group = gambia$id_village))\n\nDHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details\n\n\n\n\n\nLe graphique de droite montre les points individuels, ainsi qu’une régression quantile pour le 1er quartile, la médiane et le 3e quartile. En théorie, ces trois courbes devraient être des lignes droites horizontales (pas de tendance des résidus par rapport aux prévisions). La courbe pour le 3e quartile (en rouge) est significativement différente d’une ligne horizontale, ce qui pourrait indiquer un effet systématique manquant dans le modèle." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#glmm-spatial-avec-spamm", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#glmm-spatial-avec-spamm", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "GLMM spatial avec spaMM", + "text": "GLMM spatial avec spaMM\nLe package spaMM (modèles mixtes spatiaux) est un package R relativement récent qui permet d’effectuer une estimation approximative du maximum de vraisemblance des paramètres pour les GLM avec dépendance spatiale, modélisés soit comme un processus gaussien, soit avec un CAR (nous verrons ce dernier dans la dernière section). Le package implémente différents algorithmes, mais il existe une fonction unique fitme qui choisit l’algorithme approprié pour chaque type de modèle. Par exemple, voici le même modèle (non spatial) que nous avons vu ci-dessus, ajusté avec spaMM.\n\nlibrary(spaMM)\n\nmod_spamm_glmm <- fitme(pos ~ netuse + phc + (1 | id_village),\n data = gambia, family = binomial)\nsummary(mod_spamm_glmm)\n\nformula: pos ~ netuse + phc + (1 | id_village)\nEstimation of lambda by ML (p_v approximation of logL).\nEstimation of fixed effects by ML (p_v approximation of logL).\nfamily: binomial( link = logit ) \n ------------ Fixed effects (beta) ------------\n Estimate Cond. SE t-value\n(Intercept) 0.1491 0.2287 0.6519\nnetuse -0.6045 0.1420 -4.2567\nphc -0.4986 0.2593 -1.9231\n --------------- Random effects ---------------\nFamily: gaussian( link = identity ) \n --- Variance parameters ('lambda'):\nlambda = var(u) for u ~ Gaussian; \n id_village : 0.8151 \n --- Coefficients for log(lambda):\n Group Term Estimate Cond.SE\n id_village (Intercept) -0.2045 0.2008\n# of obs: 2035; # of groups: id_village, 65 \n ------------- Likelihood values -------------\n logLik\nlogL (p_v(h)): -1210.016\n\n\nNotez que les estimés des effets fixes ainsi que la variance des effets aléatoires sont presque identiques à ceeux obtenues par glmer ci-dessus.\nNous pouvons maintenant utiliser spaMM pour ajuster le même modèle avec l’ajout de corrélations spatiales entre les villages. Dans la formule du modèle, ceci est représenté comme un effet aléatoire Matern(1 | x + y), ce qui signifie que les ordonnées à l’origine sont spatialement corrélées entre les villages suivant une fonction de corrélation de Matérn des coordonnées (x, y). La fonction de Matérn est une fonction flexible de corrélation spatiale qui comprend un paramètre de forme \\(\\nu\\) (nu), de sorte que lorsque \\(\\nu = 0,5\\), elle est équivalente à la corrélation exponentielle, mais quand \\(\\nu\\) prend de grandes valeurs, elle se rapproche d’une corrélation gaussienne. Nous pourrions laisser la fonction estimer \\(\\nu\\), mais ici nous le fixons à 0.5 avec l’argument fixed de fitme.\n\nmod_spamm <- fitme(pos ~ netuse + phc + Matern(1 | x + y) + (1 | id_village),\n data = gambia, family = binomial, fixed = list(nu = 0.5))\n\nIncrease spaMM.options(separation_max=<.>) to at least 21 if you want to check separation (see 'help(separation)').\n\nsummary(mod_spamm)\n\nformula: pos ~ netuse + phc + Matern(1 | x + y) + (1 | id_village)\nEstimation of corrPars and lambda by ML (p_v approximation of logL).\nEstimation of fixed effects by ML (p_v approximation of logL).\nEstimation of lambda by 'outer' ML, maximizing logL.\nfamily: binomial( link = logit ) \n ------------ Fixed effects (beta) ------------\n Estimate Cond. SE t-value\n(Intercept) 0.06861 0.3352 0.2047\nnetuse -0.51719 0.1407 -3.6757\nphc -0.44416 0.2052 -2.1648\n --------------- Random effects ---------------\nFamily: gaussian( link = identity ) \n --- Correlation parameters:\n 1.nu 1.rho \n0.50000000 0.05128692 \n --- Variance parameters ('lambda'):\nlambda = var(u) for u ~ Gaussian; \n x + y : 0.6421 \n id_village : 0.1978 \n# of obs: 2035; # of groups: x + y, 65; id_village, 65 \n ------------- Likelihood values -------------\n logLik\nlogL (p_v(h)): -1197.968\n\n\nCommençons par vérifier les effets aléatoires du modèle. La fonction de corrélation spatiale a un paramètre rho égal à 0.0513. Ce paramètre dans spaMM est l’inverse de la portée, donc ici la portée de la corrélation exponentielle est de 1/0.0513 ou environ 19.5 km. Il y a maintenant deux pramètres de variance, celui identifié comme x + y est la variance à longue distance (i.e. le palier) pour le modèle de corrélation exponentielle alors que celui identifié comme id_village montre la portion non corrélée de la variation entre les villages.\nSi nous avions ici laissé les effets aléatoires (1 | id_village) dans la formule pour représenter la partie non spatiale de la variation entre les villages, nous pourrions également représenter ceci avec un effet de pépite dans le modèle géostatistique. Dans les deux cas, cela représenterait l’idée que même deux villages très proches l’un de l’autre auraient des prévalences de base différentes dans le modèle.\nPar défaut, la fonction Matern n’a pas d’effet de pépite, mais nous pouvons en ajouter un en spécifiant une pépite non nulle dans la liste initiale des paramètres init.\n\nmod_spamm2 <- fitme(pos ~ netuse + phc + Matern(1 | x + y),\n data = gambia, family = binomial, fixed = list(nu = 0.5),\n init = list(Nugget = 0.1))\n\nIncrease spaMM.options(separation_max=<.>) to at least 21 if you want to check separation (see 'help(separation)').\n\nsummary(mod_spamm2)\n\nformula: pos ~ netuse + phc + Matern(1 | x + y)\nEstimation of corrPars and lambda by ML (p_v approximation of logL).\nEstimation of fixed effects by ML (p_v approximation of logL).\nEstimation of lambda by 'outer' ML, maximizing logL.\nfamily: binomial( link = logit ) \n ------------ Fixed effects (beta) ------------\n Estimate Cond. SE t-value\n(Intercept) 0.06861 0.3352 0.2047\nnetuse -0.51719 0.1407 -3.6757\nphc -0.44416 0.2052 -2.1648\n --------------- Random effects ---------------\nFamily: gaussian( link = identity ) \n --- Correlation parameters:\n 1.nu 1.Nugget 1.rho \n0.50000000 0.23551027 0.05128692 \n --- Variance parameters ('lambda'):\nlambda = var(u) for u ~ Gaussian; \n x + y : 0.8399 \n# of obs: 2035; # of groups: x + y, 65 \n ------------- Likelihood values -------------\n logLik\nlogL (p_v(h)): -1197.968\n\n\nComme vous pouvez le voir, toutes les estimations sont les mêmes, sauf que la variance de la portion spatiale (palier) est maintenant de 0.84 et que la pépite est égale à une fraction 0.235 de ce palier, soit une variance de 0.197, ce qui est identique à l’effet aléatoire id_village dans la version ci-dessus. Les deux formulations sont donc équivalentes.\nMaintenant, rappelons les coefficients que nous avions obtenus pour le GLMM non spatial :\n\nsummary(mod_glmm)$coefficients\n\n Estimate Std. Error z value Pr(>|z|)\n(Intercept) 0.1490596 0.2296971 0.6489399 5.163772e-01\nnetuse -0.6043602 0.1442448 -4.1898243 2.791706e-05\nphc -0.4984835 0.2604083 -1.9142382 5.558973e-02\n\n\nDans la version spatiale, les deux effets fixes se sont légèrement rapprochés de zéro, mais l’erreur-type de l’effet de phc a diminué. Il est intéressant de noter que l’inclusion de la dépendance spatiale nous a permis d’estimer plus précisément l’effet de la présence d’un centre de santé publique dans le village. Ce ne serait pas toujours le cas: pour un prédicteur qui est également fortement corrélé dans l’espace, la corrélation spatiale dans la réponse rend plus difficile l’estimation de l’effet de ce prédicteur, puisqu’il est confondu avec l’effet spatial. Cependant, pour un prédicteur qui n’est pas corrélé dans l’espace, l’inclusion de l’effet spatial réduit la variance résiduelle (non spatiale) et peut donc augmenter la précision de l’effet du prédicteur.\nLe package spaMM est également compatible avec DHARMa pour les diagnostics résiduels. (Vous pouvez ignorer l’avertissement selon lequel il ne fait pas partie de la classe des modèles pris en charge, cela est dû à l’utilisation de la fonction fitme plutôt que d’une fonction d’algorithme spécifique dans spaMM).\n\nres_spamm <- simulateResiduals(mod_spamm2)\nplot(res_spamm)\n\nDHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details\n\n\n\n\nplot(recalculateResiduals(res_spamm, group = gambia$id_village))\n\nDHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details\n\n\n\n\n\nEnfin, bien que nous allons montrer comment calculer et visualiser des prédictions spatiales ci-dessous, nous pouvons produire une carte rapide des effets spatiaux estimés dans un modèle spaMM avec la fonction filled.mapMM.\n\nfilled.mapMM(mod_spamm2)" + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#processus-gaussiens-vs.-splines-de-lissage", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#processus-gaussiens-vs.-splines-de-lissage", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Processus gaussiens vs. splines de lissage", + "text": "Processus gaussiens vs. splines de lissage\nSi vous connaissez bien les modèles additifs généralisés (GAM), vous avez peut-être pensé à représenter la variation spatiale de la prévalence du paludisme (comme le montre la carte ci-dessus) par une spline de lissage en 2D (en fonction de \\(x\\) et \\(y\\)) dans un GAM.\nLe code ci-dessous correspond à l’équivalent GAM de notre GLMM avec processus gaussien ci-dessus, ajusté avec la fonction gam du package mgcv. L’effet spatial est représenté par la spline 2D s(x, y) alors que l’effet aléatoire non spatial de village est représenté par s(id_village, bs = \"re\"), qui est équivalent à (1 | id_village) dans les modèles précédents. Notez que pour la fonction gam, les variables catégorielles doivent être explicitement converties en facteurs.\n\nlibrary(mgcv)\ngambia$id_village <- as.factor(gambia$id_village)\nmod_gam <- gam(pos ~ netuse + phc + s(id_village, bs = \"re\") + s(x, y), \n data = gambia, family = binomial)\n\nPour visualiser la spline en 2D, nous utiliserons le package gratia.\n\nlibrary(gratia)\ndraw(mod_gam)\n\n\n\n\nNotez que le graphique de la spline s(x, y) (en haut à droite) ne s’étend pas trop loin des emplacements des données (les autres zones sont vides). Dans ce graphique, on peut également voir que les effets aléatoires des villages suivent la distribution gaussienne attendue (en haut à gauche).\nEnsuite, nous utiliserons à la fois le GLMM spatial de la section précédente et ce GAMM pour prédire la prévalence moyenne sur une grille spatiale de points contenue dans le fichier gambia_pred.csv. Le graphique ci-dessous ajoute ces points de prédiction (en noir) sur la carte précédente des points de données.\n\ngambia_pred <- read.csv(\"data/gambia_pred.csv\")\n\nggplot(gambia_agg, aes(x = x, y = y)) +\n geom_point(data = gambia_pred) +\n geom_point(aes(color = prev)) +\n geom_path(data = gambia.borders, aes(x = x / 1000, y = y / 1000)) +\n coord_fixed() +\n theme_minimal() +\n scale_color_viridis_c()\n\n\n\n\nPour faire des prédictions à partir du modèle GAMM à ces endroits, le code ci-dessous effectue les étapes suivantes:\n\nTous les prédicteurs du modèle doivent se trouver dans le tableau de données de prédiction, nous ajoutons donc des valeurs constantes de netuse et phc (toutes deux égales à 1) pour tous les points. Ainsi, nous ferons des prédictions sur la prévalence du paludisme dans le cas où un moustiquaire est utilisée et où un centre de santé publique est présent. Nous ajoutons également un id_village constant, bien qu’il ne soit pas utilisé dans les prédictions (voir ci-dessous).\nNous appelons la fonction predict à la sortie de gam pour produire des prédictions aux nouveaux points de données (argument newdata), en incluant les erreurs-types (se.fit = TRUE) et en excluant les effets aléatoires du village, donc la prédiction est faite pour un “village moyen”. L’objet résultant gam_pred aura des colonnes fit (prédiction moyenne) et se.fit (erreur-type). Ces prédictions et erreurs-types sont sur l’échelle du lien (logit).\nNous rattachons le jeu de données de prédiction original à gam_pred avec cbind.\nNous ajoutons des colonnes pour la prédiction moyenne et les limites de l’intervalle de confiance à 50% (moyenne \\(\\pm\\) 0.674 erreur-type), converties de l’échelle logit à l’échelle de probabilité avec plogis. Nous choisissons un intervalle de 50% car un intervalle de 95% peut être trop large ici pour contraster les différentes prédictions sur la carte à la fin de cette section.\n\n\ngambia_pred <- mutate(gambia_pred, netuse = 1, phc = 1, id_village = 1)\n\ngam_pred <- predict(mod_gam, newdata = gambia_pred, se.fit = TRUE, \n exclude = \"s(id_village)\")\ngam_pred <- cbind(gambia_pred, as.data.frame(gam_pred))\ngam_pred <- mutate(gam_pred, pred = plogis(fit), \n lo = plogis(fit - 0.674 * se.fit), # 50% CI\n hi = plogis(fit + 0.674 * se.fit))\n\nNote : La raison pour laquelle nous ne faisons pas de prédictions directement sur l’échelle de probabilité (réponse) est que la formule normale des intervalles de confiance s’applique plus précisément sur l’échelle logit. L’ajout d’un certain nombre d’erreurs-types autour de la moyenne sur l’échelle de probabilité conduirait à des intervalles moins précis et peut-être même à des intervalles de confiance en dehors de la plage de valeurs possible (0, 1) pour une probabilité.\nNous appliquons la même stratégie pour faire des prédictions à partir du GLMM spatial avec spaMM. Il y a quelques différences dans la méthode predict par rapport au cas du GAMM.\n\nL’argument binding = \"fit\" signifie que les prédictions moyennes (colonne fit) seront attachées à l’ensemble de données de prédiction et retournées sous forme de tableau de données spamm_pred.\nL’argument variances = list(linPred = TRUE) indique à predict de calculer la variance du prédicteur linéaire (donc le carré de l’erreur-type). Cependant, il apparaît comme un attribut predVar dans le tableau de données de sortie plutôt que dans une colonne se.fit, donc nous le déplaçons vers une colonne sur la ligne suivante.\n\n\nspamm_pred <- predict(mod_spamm, newdata = gambia_pred, type = \"link\",\n binding = \"fit\", variances = list(linPred = TRUE))\nspamm_pred$se.fit <- sqrt(attr(spamm_pred, \"predVar\"))\nspamm_pred <- mutate(spamm_pred, pred = plogis(fit), \n lo = plogis(fit - 0.674 * se.fit),\n hi = plogis(fit + 0.674 * se.fit))\n\nEnfin, nous combinons les deux ensembles de prédictions sous la forme de différentes rangées d’un tableau de données pred_all avec bind_rows. Le nom du tableau de données d’où provient chaque prédiction (gam ou spamm) apparaîtra dans la colonne “model” (argument .id). Pour simplifier la production du prochain graphique, nous utilisons ensuite pivot_longer dans le package tidyr pour changer les trois colonnes “pred”, “lo” et “hi” en deux colonnes, “stat” et “value” (pred_tall a donc trois rangées pour chaque rangée dans pred_all).\n\npred_all <- bind_rows(gam = gam_pred, spamm = spamm_pred, .id = \"model\")\n\nlibrary(tidyr)\npred_tall <- pivot_longer(pred_all, c(pred, lo, hi), names_to = \"stat\",\n values_to = \"value\")\n\nUne fois ces étapes franchies, nous pouvons enfin examiner les cartes de prédiction (moyenne, limites inférieure et supérieure de l’intervalle de confiance à 50 %) à l’aide d’un graphique ggplot. Les points de données originaux sont indiqués en rouge.\n\nggplot(pred_tall, aes(x = x, y = y)) +\n geom_point(aes(color = value)) +\n geom_point(data = gambia_agg, color = \"red\", size = 0) +\n coord_fixed() +\n facet_grid(stat~model) +\n scale_color_viridis_c() +\n theme_minimal()\n\n\n\n\nBien que les deux modèles s’accordent à dire que la prévalence est plus élevée près du groupe de villages de l’est, le GAMM estime également une prévalence plus élevée en quelques points (bord ouest et autour du centre) où il n’y a pas de données. Il s’agit d’un artefact de la forme de la spline autour des points de données, puisqu’une spline est censée correspondre à une tendance globale, bien que non linéaire. En revanche, le modèle géostatistique représente l’effet spatial sous forme de corrélations locales et revient à la prévalence moyenne globale lorsqu’il est éloigné de tout point de données, ce qui est une supposition plus sûre. C’est l’une des raisons pour lesquelles il est préférable de choisir un modèle géostatistique / processus gaussien dans ce cas." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#méthodes-bayésiennes-pour-les-glmm-avec-processus-gaussiens", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#méthodes-bayésiennes-pour-les-glmm-avec-processus-gaussiens", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Méthodes bayésiennes pour les GLMM avec processus gaussiens", + "text": "Méthodes bayésiennes pour les GLMM avec processus gaussiens\nLes modèles bayésiens fournissent un cadre flexible pour exprimer des modèles avec une structure de dépendance complexe entre les données, y compris la dépendance spatiale. Cependant, l’ajustement d’un modèle de processus gaussien avec une approche entièrement bayésienne peut être lent, en raison de la nécessité de calculer une matrice de covariance spatiale entre toutes les paires de points à chaque itération.\nLa méthode INLA (pour integrated nested Laplace approximation) effectue un calcul approximatif de la distribution postérieure bayésienne, ce qui la rend adaptée aux problèmes de régression spatiale. Nous ne l’abordons pas dans ce cours, mais je recommande le manuel de Paula Moraga (dans la section des références ci-dessous) qui fournit des exemples concrets d’utilisation de la méthode INLA pour divers modèles de données géostatistiques et aréales, dans le contexte de l’épidémiologie, y compris des modèles avec une dépendance à la fois spatiale et temporelle. Le livre présente les mêmes données sur le paludisme en Gambie comme exemple d’un ensemble de données géostatistiques, ce qui a inspiré son utilisation dans ce cours." + }, + { + "objectID": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#référence-1", + "href": "posts/2021-01-12-4-day-training-in-spatial-statistics-with-philippe-marchand/index.html#référence-1", + "title": "4-Day Training in Spatial Statistics with Philippe Marchand", + "section": "Référence", + "text": "Référence\nMoraga, Paula (2019) Geospatial Health Data: Modeling and Visualization with R-INLA and Shiny. Chapman & Hall/CRC Biostatistics Series. Disponible en ligne: https://www.paulamoraga.com/book-geospatial/." + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html", + "title": "Making websites with HUGO", + "section": "", + "text": "I am only 10 hours of a crash course in web development ahead of you. As part of a major research project on setting a biodiversity observation network, I had to develop a prototype of a portal for the project, for biodiversity information and bunch of dashboards on biodiversity trends. Never made a website before. I know how to code in a few langages, and I know that I hate playing with boxes, menus, importing images manually, and most of all, dealing with a crash of the system and having to redo the whole thing because I made a mistake somewhere. Not that a bug when I try to compile is better, but at least it is more tractable.\nHugo made it very easily because of its fundamental feature (which is the same reason I edit papers with LaTeX): the distinction between the view and the content. Once you have set up the rules defining the visual aspects of the pages, then you can focus on the content and let the software automatically constructing the html code for you. It’s fast, accessible, scriptable and could be version-controlled. All qualities for an open and reproducible science.\nTook me a few hours to learn the basics (much harder to get the higher level skills, especially to write your own Go scripts), I took some tricks here and there in different templates and at looking what others do, and that was it I had my website. Realized that it could be a good entry level course to BIOS2 fellows and decided to turn that experience into a training workshop.\nYou will find below basic instructions to install and run a template. The following is not a full tutorial, for that I recommend simply to take time looking at the documentation provided on the Hugo page (https://gohugo.io/). I also consulted the online book Hugo in action (https://www.manning.com/books/hugo-in-action). There are many other references, all of them with goods and bads. But it’s nice to have multiple ones because sometimes the description of a concept may be obscure in one reference but better in the other and it’s by comparing and switching between them that you can make progress." + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html#exercise-edit-the-toml-file-to-include-your-own-information.", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html#exercise-edit-the-toml-file-to-include-your-own-information.", + "title": "Making websites with HUGO", + "section": "Exercise : Edit the toml file to include your own information.", + "text": "Exercise : Edit the toml file to include your own information.\nYou may want to change the section People to Collaborators and also provide a proper reference to your on github page. You can also add or remove sections, this will affect the menu at the top of the page. For instance, you can add a blog section." + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html#build-for-local-development", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html#build-for-local-development", + "title": "Making websites with HUGO", + "section": "Build for local development", + "text": "Build for local development\nHugo will use all of the material to generate static html files that will be displayed on your browser. The command is really easy to use to run it on your own computer, you simply have to type the following in the main folder :\nhugo server\nAnd that’s it, it compiles and you can simply open it in your browser by clicking on the adress indicated in the terminal. Congratulations for your first Hugo webste !\nThere are useful information in the terminal about the building process." + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html#build-for-publishing-your-website", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html#build-for-publishing-your-website", + "title": "Making websites with HUGO", + "section": "Build for publishing your website", + "text": "Build for publishing your website\nThe command hugo server is very fast and useful to test your website while you develop it. But once you’ll be ready to distribute it, you’ll need all of the html files and related material to distribute the website. This is easily done with the even simpler command\nhugo\nYou will find in the directory that a new folder named public appeared, with all of the material needed to deploy the website. If you click on the index.html file, you’ll get to the home page of the website. It is interesting to open this file in your text editor, you’ll get a sense of the html code that hugo generated automatically for you. You can also take a look at other files." + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html#exercise", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html#exercise", + "title": "Making websites with HUGO", + "section": "Exercise", + "text": "Exercise\nTake 15 minutes to remove Tim’s material and replace it by the three chapters of your thesis." + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html#github-user-or-organization-pages", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html#github-user-or-organization-pages", + "title": "Making websites with HUGO", + "section": "GitHub User or Organization Pages", + "text": "GitHub User or Organization Pages\n\nStep-by-step Instructions\n\nCreate a (e.g. blog) repository on GitHub. This repository will contain Hugo’s content and other source files.\nCreate a .github.io GitHub repository. This is the repository that will contain the fully rendered version of your Hugo website.\ngit clone && cd \nPaste your existing Hugo project into the new local repository. Make sure your website works locally (hugo server or hugo server -t ) and open your browser to http://localhost:1313.\nOnce you are happy with the results: Press Ctrl+C to kill the server Before proceeding run rm -rf public to completely remove the public directory\ngit submodule add -b main https://github.com//.github.io.git public. This creates a git submodule. Now when you run the hugo command to build your site to public, the created public directory will have a different remote origin (i.e. hosted GitHub repository).\nMake sure the baseURL in your config file is updated with: .github.io\n\n\n\nPut it Into a Script\nYou’re almost done. In order to automate next steps create a deploy.sh script. You can also make it executable with chmod +x deploy.sh.\nThe following are the contents of the deploy.sh script:\n #!/bin/sh\n\n # If a command fails then the deploy stops\n set -e\n\n printf \"\\033[0;32mDeploying updates to GitHub...\\033[0m\\n\"\n\n # Build the project.\n hugo # if using a theme, replace with `hugo -t `\n\n # Go To Public folder\n cd public\n\n # Add changes to git.\n git add .\n\n # Commit changes.\n msg=\"rebuilding site $(date)\"\n if [ -n \"$*\" ]; then\n msg=\"$*\"\n fi\n git commit -m \"$msg\"" + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html#using-a-theme", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html#using-a-theme", + "title": "Making websites with HUGO", + "section": "Using a theme", + "text": "Using a theme\nIt is usually a good idea to not modify a template directly, but to have the template and the site in a separate folder. The basic concept when doing this is that the config.toml file of the site has to link to the proper folder of the theme.\nFor example\ntheme = \"template-site\"\nthemesDir = \"../..\"\nThis means that the template site is in a folder named template-site which is a parent folder of the site folder. Other options are possible.\nUsually, all the content should go in the site folder, not in the theme folder.\n\nExercise 1\n\nStart modifying the theme to make it look like a website for a Zoo. Choose your preferred color scheme by changing the style= parameter in the config.toml file.\nFeel free to download some images from unsplash and save them in the static/img folder. You can then use these images in the carrousel, as “testimonial” photos or as background images for some of the sections. You can add or remove sections from the home page by editing the config.toml file and changing the enable= parameter in the params. segment at the bottom.\nYou can also try to create a new blog entry by adding a new file in the content/blog folder. This file will have a .md extension and will be written in markdown format." + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html#customizing-a-theme", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html#customizing-a-theme", + "title": "Making websites with HUGO", + "section": "Customizing a theme", + "text": "Customizing a theme" + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html#basics-of-html", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html#basics-of-html", + "title": "Making websites with HUGO", + "section": "Basics of HTML", + "text": "Basics of HTML\nCore structure of an HTML page\n\n\n\nThis is my great website\n\n\n\n

Main title

\n
Main content goes here
\n\n\n\nA divider, used to organize content into blocks\n
\n\n\nA span, used to organize content or text into sections with different styles. Usually on the same line.\n\n\n\nA paragraph\n

\n\n\nHeadings at different levels\n

Main title

\n

Second level

\n

Third level

\n\n\nAn image\n\n\n\nA link\nGreat website here!" + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html#link-between-html-and-css", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html#link-between-html-and-css", + "title": "Making websites with HUGO", + "section": "Link between HTML and CSS", + "text": "Link between HTML and CSS\n\nIn html\nid is always unique. Class is not.\n
\nOne great div!\n
\n\n\nIn CSS\n“#” is applied to id and “.” is applied to class. When nothing is specified, applies to tag.\n#this-div-only{\n font-size:24px;\n}\n\n.this-type-of-div{\n color: #bb0000;\n}\n\ndiv{\n display:block;\n}" + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html#basics-of-css", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html#basics-of-css", + "title": "Making websites with HUGO", + "section": "Basics of CSS", + "text": "Basics of CSS\nW3 Schools CSS reference\n\n\n\n\n\n\n\n\nProperty\nDescription\nExample\n\n\n\n\nwidth, height\nwidth of item\n200px, 200pt, 100%, 100vw/vh\n\n\nmin-width, min-height\nminimum size of item\n200px, 200pt, 100%, 100vw\n\n\ncolor\nfont color\n#aa0000, red or rgb(255,0,0)\n\n\nbackground-color\ncolor of background\n#aa0000, red or rgb(255,0,0)\n\n\nborder-color\ncolor of border\n#aa0000, red or rgb(255,0,0)\n\n\nborder\nsize, type and color of border\n1px solid black\n\n\nmargin\nmargin around item (top right bottom left)\n1px, or 1px 2px 2px 1px\n\n\npadding\npadding within item, inside div for example\n10px\n\n\nfont-family\nname of font\nVerdana, Arial\n\n\nfont-size\nsize of text\n14px, 2em\n\n\ndisplay\nshould item be on the same line, or in a separate block?\ninline, block, inline-block, flex, …\n\n\n\n\nExercise 2\n\nCreate a file named custom.css under template-site/my-site/static/css/.\nRight-click on elements on the web page that you want to modify, then click on Inspect element and try to find CSS properties that you could modify to improve the look of the page. Then, choosing the proper class, add entries in the custom.css file that start with a dot (.) followed by the proper class names.\n\n.this-class {\n font-size:28px;\n}" + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html#partials", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html#partials", + "title": "Making websites with HUGO", + "section": "Partials", + "text": "Partials\nPartials are snippets of HTML code that could be reused on different places on the website. For example, you will see that the layouts/index.html file in the template-site folder lists all the partials that create the home page.\nAn important point to remember is that Hugo will look for files first in the site’s folders, and if it doesn’t find the files there, it will look for them in the theme’s folder. So site folder layouts and CSS take priority over the theme folder.\n\nExercise 3\n\nCreate a new folder template-site/my-site/layouts. In this folder, create a new file named index.html and copy the content of the template-site/layouts/index.html file into it. Remove the testimonials section from the newly created file.\nCreate a new folder template-site/my-site/layouts/partials. In this folder, create a new file named featured-species.html put the following content into it, replacing the information with the species you selected.\n\n
\n\"\"\n
\n

Red-Eyed Tree Frog

\n

This frog can be found in the tropical rain forests of Costa Rica.

\n
\n
\n\nThen, add this section to the index.html file created above.\n\n\n{{ partial \"featured_species.html\" . }}\n\nYou will probably need to restart the Hugo server to see the changes appear on the site.\nNow, you need to edit the CSS! In your custom.css file, add the following lines.\n\n\n.featured-species{\n height:300px;\n background-color: #1d1f20;\n color:white;\n}\n\n.species-image{\n height:300px;\n float:left;\n}\n\n.featured-species h3{\n color:white;\n font-size:1.5em;\n}\n\n.species-description{\n float:left;\n padding:20px;\n font-size:2em;\n}\nModify this as you see fit!" + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html#now-a-bit-of-go-lang-to-make-the-featured-species-different.", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html#now-a-bit-of-go-lang-to-make-the-featured-species-different.", + "title": "Making websites with HUGO", + "section": "Now a bit of GO lang to make the featured species different.", + "text": "Now a bit of GO lang to make the featured species different.\nIntroduction to Hugo templating\n\nExercise 4\n\nReplace your partial featured-species.html content with this one\n\n{{ range .Site.Data.species }}\n {{ if eq (.enable) true }}\n
\n \"\"\n
\n

{{ .name }}

\n

{{ .description }}

\n
\n
\n {{end}}\n{{end}}\n\nNow, create a new folder /template-site/my-site/data/species.\nIn this folder, create new file named frog.yaml with the following content.\n\nenable: true\nname: \"Red-eyed tree frog\"\ndescription: \"This frog can be found in the forests of Costa Rica\"\nimage: \"frog.jpg\"\n\nFind other species photos and add them to the img folder. Then you can add new .yaml files in the data/species folder for each species." + }, + { + "objectID": "posts/2020-12-07-making-websites-with-hugo/index.html#iframes", + "href": "posts/2020-12-07-making-websites-with-hugo/index.html#iframes", + "title": "Making websites with HUGO", + "section": "iFrames", + "text": "iFrames\nAn iFrame is a HTML tag that essentially allows you to embed another web page inside of your site.\n\nExercise 5\nFind a Youtube video and click on the share option below the video. Find the Embed option and copy the code that starts with \n\nEdit the custom.css file and add this section\n.video{\n width:100%;\n background-color:black;\n text-align:center;\n}" + }, + { + "objectID": "posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/index.html", + "href": "posts/2021-01-22-introduction-aux-concepts-edi-en-contexte-scientifique/index.html", + "title": "Introduction to EDI concepts in a scientific context", + "section": "", + "text": "Texte en français à la suite.\n\n1 Introduction to EDI concepts in a scientific context\nIn 2021, the BIOS2 training program will be holding a series of training and reflection activities on equity, diversity and inclusion issues. The goal is to develop an EDI action plan for the program in order to consolidate a more inclusive, respectful and open environment.\nThe objectives of this workshop are:\n\nDefine the concepts of equity, diversity and inclusion\nIdentify the benefits and challenges of EDI in the university context\nRecongnize how to become an EDI bearer during one’s university career\nRaise awareness of intercultural communication (professional competence of tomorrow)\n\nThe workshop is developed by Agathe Riallan, Faculty Coordinator for Equity, Diversity and Inclusion (EDI) at the Faculty of Science, Université de Sherbrooke, in collaboration with Marie-José Naud, Equity, Diversity and Inclusion Advisor and Coordinator at the Centre d’études nordiques (CEN).\n\n\n \n\n\n\n2 Introduction aux concepts EDI en contexte scientifique\nEn 2021, nous aurons une série de formations et d’activités de réflexion sur les questions d’équité, diversité et d’inclusion. Notre objectif est de mettre en place un plan d’action EDI pour le programme afin de consolider un environnement plus inclusif, respectueux et ouvert.\nLes objectifs de cet ateliers sont:\n\nDéfinir les concepts d’équité, de diversité et d’inclusion\nIdentifier les avantages et les défis de l’ÉDI en contexte universitaire\nIdentifier comment être porteuse ou porteur de l’ÉDI lors de son parcours universitaire\nSe sensibiliser à la communication interculturelle (compétence professionnelle de demain)\n\nL’atelier est développé par Agathe Riallan, Coordinatrice facultaire de l’Équité, de la Diversité et de l’Inclusion (ÉDI) de la Faculté des Sciences à Université de Sherbrooke, en collaboration avec Marie-José Naud, Conseillère en équité, diversité et inclusion et coordonnatrice au Centre d’études nordiques (CEN)." + }, + { + "objectID": "posts/2021-03-25-point-count-data-analysis/index.html", + "href": "posts/2021-03-25-point-count-data-analysis/index.html", + "title": "Point-count Data Analysis", + "section": "", + "text": "This course is aimed towards researchers analyzing field observations, who are often faced by data heterogeneities due to field sampling protocols changing from one project to another, or through time over the lifespan of projects, or trying to combine ‘legacy’ data sets with new data collected by recording units.\nSuch heterogeneities can bias analyses when data sets are integrated inadequately, or can lead to information loss when filtered and standardized to common standards. Accounting for these issues is important for better inference regarding status and trend of species and communities.\nAnalysts of such ‘messy’ data sets need to feel comfortable with manipulating the data, need a full understanding the mechanics of the models being used (i.e. critically interpreting the results and acknowledging assumptions and limitations), and should be able to make informed choices when faced with methodological challenges.\nThe course emphasizes critical thinking and active learning through hands on programming exercises. We will use publicly available data sets to demonstrate the data manipulation and analysis. We will use freely available and open-source R packages.\nThe expected outcome of the course is a solid foundation for further professional development via increased confidence in applying these methods for field observations." + }, + { + "objectID": "posts/2021-03-25-point-count-data-analysis/index.html#instructor", + "href": "posts/2021-03-25-point-count-data-analysis/index.html#instructor", + "title": "Point-count Data Analysis", + "section": "Instructor", + "text": "Instructor\nDr. Peter Solymos\nBoreal Avian Modelling Project and the Alberta Biodiversity Monitoring Institute\nDepartment of Biological Sciences, University of Alberta" + }, + { + "objectID": "posts/2021-03-25-point-count-data-analysis/index.html#outline", + "href": "posts/2021-03-25-point-count-data-analysis/index.html#outline", + "title": "Point-count Data Analysis", + "section": "Outline", + "text": "Outline\nEach day will consist of 3 sessions, roughly one hour each, with short breaks in between.\n\nThe video recordings from the workshop can be found on YouTube.\n\n\n\n\nSession\nTopic\nFiles\nVideos\n\n\n\n\nDay 1\nNaive techniques\n\n\n\n\n\n1. Introductions\nSlides\nVideo\n\n\n\n2. Organizing point count data\nNotes\nPart 1, Part 2\n\n\n\n3. Regression techniques\nNotes\nPart 1, Part 2\n\n\nDay 2\nBehavioral complexities\n\n\n\n\n\n1. Statistical assumptions and nuisance variables\nSlides\nVideo\n\n\n\n2. Behavioral complexities\nNotes\nbSims, Video\n\n\n\n3. Removal modeling techniques\nNotes\nVideo\n\n\n\n4. Finite mixture models and testing assumptions\nNotes\nMixtures, Testing\n\n\nDay 3\nThe detection process\n\n\n\n\n\n1. The detection process\nSlides\nVideo\n\n\n\n2. Distance sampling and density\nNotes\nVideo\n\n\n\n3. Estimating population density\nNotes\nVideo\n\n\n\n4. Assumptions\nNotes\nVideo\n\n\nDay 4\nComing full circle\n\n\n\n\n\n1. QPAD overview\nSlides\nVideo\n\n\n\n2. Models with detectability offsets\nNotes\nOffsets, Models\n\n\n\n3. Model validation and error propagation\nNotes\nValidation, Error\n\n\n\n4. Recordings, roadsides, closing remarks\nNotes\nVideo" + }, + { + "objectID": "posts/2021-03-25-point-count-data-analysis/index.html#get-course-materials", + "href": "posts/2021-03-25-point-count-data-analysis/index.html#get-course-materials", + "title": "Point-count Data Analysis", + "section": "Get course materials", + "text": "Get course materials\n\nInstall required software\nFollow the instructions at the R website to download and install the most up-to-date base R version suitable for your operating system (the latest R version at the time of writing these instructions is 4.0.4).\nThen run the following script in R:\nsource(\"https://raw.githubusercontent.com/psolymos/qpad-workshop/main/src/install.R\")\nHaving RStudio is not absolutely necessary, but it will make life easier. RStudio is also available for different operating systems. Pick the open source desktop edition from here (the latest RStudio Desktop version at the time of writing these instructions is 1.4.1106).\nPrior exposure to R programming is not necessary, but knowledge of basic R object types and their manipulation (arrays, data frames, indexing) is useful for following hands-on exercises. Software Carpentry’s Data types and structures in R is a good resource to brush up your R skills.\n\n\nGet the notes\nIf you don’t want to use git:\n\nDownload the workshop archive release into a folder\nExtract the zip archive\nOpen the workshop.Rproj file in RStudio (or open any other R GUI/console and setwd() to the directory where you downloaded the file)\n(You can delete the archive)\n\nIf you want to use git: fork or clone the repository\ncd into/your/dir\ngit clone https://github.com/psolymos/qpad-workshop.git" + }, + { + "objectID": "posts/2021-03-25-point-count-data-analysis/index.html#useful-resources", + "href": "posts/2021-03-25-point-count-data-analysis/index.html#useful-resources", + "title": "Point-count Data Analysis", + "section": "Useful resources", + "text": "Useful resources\n\nUsing the QPAD package to get offsets based on estimates from the Boreal Avian Modelling Project’s database\nNA-POPS: Point count Offsets for Population Sizes of North America landbirds" + }, + { + "objectID": "posts/2021-03-25-point-count-data-analysis/index.html#references", + "href": "posts/2021-03-25-point-count-data-analysis/index.html#references", + "title": "Point-count Data Analysis", + "section": "References", + "text": "References\nSólymos, P., Toms, J. D., Matsuoka, S. M., Cumming, S. G., Barker, N. K. S., Thogmartin, W. E., Stralberg, D., Crosby, A. D., Dénes, F. V., Haché, S., Mahon, C. L., Schmiegelow, F. K. A., and Bayne, E. M., 2020. Lessons learned from comparing spatially explicit models and the Partners in Flight approach to estimate population sizes of boreal birds in Alberta, Canada. Condor, 122: 1-22. PDF\nSólymos, P., Matsuoka, S. M., Cumming, S. G., Stralberg, D., Fontaine, P., Schmiegelow, F. K. A., Song, S. J., and Bayne, E. M., 2018. Evaluating time-removal models for estimating availability of boreal birds during point-count surveys: sample size requirements and model complexity. Condor, 120: 765-786. PDF\nSólymos, P., Matsuoka, S. M., Stralberg, D., Barker, N. K. S., and Bayne, E. M., 2018. Phylogeny and species traits predict bird detectability. Ecography, 41: 1595-1603. PDF\nVan Wilgenburg, S. L., Sólymos, P., Kardynal, K. J. and Frey, M. D., 2017. Paired sampling standardizes point count data from humans and acoustic recorders. Avian Conservation and Ecology, 12(1):13. PDF\nYip, D. A., Leston, L., Bayne, E. M., Sólymos, P. and Grover, A., 2017. Experimentally derived detection distances from audio recordings and human observers enable integrated analysis of point count data. Avian Conservation and Ecology, 12(1):11. PDF\nSólymos, P., and Lele, S. R., 2016. Revisiting resource selection probability functions and single-visit methods: clarification and extensions. Methods in Ecology and Evolution, 7:196-205. PDF\nMatsuoka, S. M., Mahon, C. L., Handel, C. M., Sólymos, P., Bayne, E. M., Fontaine, P. C., and Ralph, C. J., 2014. Reviving common standards in point-count surveys for broad inference across studies. Condor 116:599-608. PDF\nSólymos, P., Matsuoka, S. M., Bayne, E. M., Lele, S. R., Fontaine, P., Cumming, S. G., Stralberg, D., Schmiegelow, F. K. A. & Song, S. J., 2013. Calibrating indices of avian density from non-standardized survey data: making the most of a messy situation. Methods in Ecology and Evolution 4:1047-1058. PDF\nMatsuoka, S. M., Bayne, E. M., Sólymos, P., Fontaine, P., Cumming, S. G., Schmiegelow, F. K. A., & Song, S. A., 2012. Using binomial distance-sampling models to estimate the effective detection radius of point-counts surveys across boreal Canada. Auk 129:268-282. PDF" + }, + { + "objectID": "posts/2021-03-25-point-count-data-analysis/index.html#license", + "href": "posts/2021-03-25-point-count-data-analysis/index.html#license", + "title": "Point-count Data Analysis", + "section": "License", + "text": "License\nThe course material is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) license. Source code is under MIT license." + }, + { + "objectID": "posts/2021-07-19-glm-community-ecology/index.html", + "href": "posts/2021-07-19-glm-community-ecology/index.html", + "title": "Generalized Linear Models for Community Ecology", + "section": "", + "text": "Generalized Linear Model for Community Ecology\nPedro Peres-Neto, Concordia University\nBIOS2 workshop, May 17 to 21, 2021\nThis document was put together for the first time for this workshop.\nLet me know if you have suggestions or find any issues in the document.\n\n\n\nTentative schedule\n\nDay 1:\nIntroduction to types of data and approaches using GLMs in community ecology.\nTypes of patterns in species distributions involving trait and environmental variation.\nSimulating data as a path to understand GLMs in community ecology.\nThe simplest GLM: widely used bivariate correlations.\nThe challenges of statistical inference regarding linking different types of information from communities and species.\nUnderstanding estimators and their properties in GLMs.\nDay 2:\nFrom bivariate correlations to a variety of more complex GLMs: the case of Binomial and Poisson.\nThe role of latents in specifying GLMs for community ecology.\nThe issues underlying autocorrelation in ecological data: the cases of spatial and phylogenetic autocorrelation.\nSimple GLMM approaches (Generalized Linear Mixed Models).\nDay 3:\nMore complex GLMM approaches.\nPotential approaches for incorporating intraspecific data on traits.\nDiscussion with participants: your research interests, your questions or your data (or anything really).\n\nPhilosophy: We can’t cover everything with extreme details. I’ve chosen a level that should be interesting enough and cover many different important aspects of GLMs applied to community ecology.\nNote: I mostly apply here base functions so that participants without strong knowledge of certain packages (e.g., ggplot, dplyr) can follow the code more easily.\nQuestions: Participants should feel free to ask questions either directly or in the zoom chat. I’ve also set a good doc where participants can put questions there during the week when we are not connected. I’ll read them and try to provide an answer or cover the question somehow:\nhttps://docs.google.com/document/d/17GQvGkBFs9MmLv6Yn473_Dr1t1Ps03VdHOHMhbZhBKk/edit\n\n\n\nSimulating data\n\nSimulating a single species\nOne way to develop good intuition underlying quantitative methods is to be able to simulate data according to certain desired characteristics. We can then apply methods (GLMs here) to see how well they retrieve the data characteristics.\nLet’s start with a very simple GLM, the logistic regression for one single species. Here, for simplicity, we considered one predictor. In many ecological simulations, this single predictor is considered an “environmental gradient” containing many environmental predictors. We can consider more gradients and we will discuss that later on in the workshop.\n\nset.seed(100) # so that we all have the same results\nn.sites <- 100\nX <- rnorm(n.sites)\nb0 <- 0.5 # controls the max prob. values\nprob.presence <- 1./(1+exp(-(b0+3*X)))\nplot(prob.presence ~ X)\n\n\n\n\nThis model is pretty simple and its form is:\n\\[p=\\frac{1}{1+e^{-(\\beta_0+\\beta_1X_1)}} = \\frac{1}{1+e^{-(0.5+3X_1)}}\\]\nNow let’s generate presences and absences according to the logistic model expectation. Since is a logistic model, we use rbinom,i.e., binomial trials:\n\nDistribution <- rbinom(n.sites,1,prob.presence)\n\nView(cbind(prob.presence,Distribution))\nLet’s model the data using logistic regression:\n\nmodel <- glm(Distribution ~ X,family=binomial(link=logit))\ncoefficients(model)\n\n(Intercept) X \n 0.09200133 3.66168492 \n\n\nView(cbind(prob.presence,Distribution,model$fitted.values))\nPlotting the predicted versus the observed presence-absence values:\n\nplot(model$fitted.values ~ Distribution)\n\n\n\n\nAt this point, we won’t cover model diagnostics. Data were simulated according to the model and, as such, assumptions hold well. Plus, this is a single-species model; and this workshop is about community data, i.e., multiple species :).\nThis is a good blog explaining how to check for assumptions of logistic regressions.\nSimulating a more realistic single species\nSpecies don’t tend to respond linearly to environmental features:\n\n\n\n\n\nNow that we understand some basics of presence-absence data, let’s concentrate on more realistic species distribution data and multi-species data. There are many ways (found in the ecological literature) in which we can simulate these type of data. Below we will generate data using a standard Gaussian model for presence-absence data according to a trait and environmental feature (we will cover abundance data later on). This is a commonly used way to simulate data. Let’s start with a single species and one environmental variable.\n\nset.seed(100) # so that we all have the same results\nn.sites <- 100\nX <- rnorm(n.sites)\noptimum <- 0.2\nniche.breadth <- 0.5\nb0 <- 1 # controls the max prob. values\nb1 <- -2\n# this is a logistic model:\nprob.presence <- 1./(1+exp(-(b0+(b1*(X-optimum)^2)/(2*niche.breadth^2)))) \n\nThis more “complex” model has the following form:\n\\[p=\\frac{1}{1+e^{-(\\beta_0+\\beta_1\\frac{(X-\\mu)^2}{2\\sigma^2})}}=\\frac{1}{1+e^{-(1+2\\frac{(X-0.2)^2}{2\\cdot0.5^2})}}\\] where \\(\\mu\\) represents the species optimum and \\(\\sigma\\) its niche breadth.\nLet’s plot these probabilities:\n\nplot(X,prob.presence,ylim=c(0,1))\n# plot optimum\nabline(v=optimum,col=\"red\")\n\n\n\n\nNow let’s simulate the distribution, i.e., presences and absences according to the model. Since is a logistic, we use rbinom,i.e., binomial trials:\n\nDistribution <- rbinom(n.sites,1,prob.presence)\n\nPlot the species distribution against the environmental variable:\n\nplot(X,prob.presence,ylim=c(0,1))\nsites.present <- which(Distribution==1)\npoints(X[sites.present],Distribution[sites.present],col=\"green\",pch=16,cex=0.5)\nsites.absent <- which(Distribution==0)\npoints(X[sites.absent],Distribution[sites.absent],col=\"red\",pch=16,cex=0.5)\n\n\n\n\nThe parameters can be then estimated from the data using a logistic regression:\n\npredictor <- cbind(X,X^2) \nmodel <- glm(Distribution ~ predictor,family=binomial(link=logit))\ncoeffs <- coefficients(model)\nb0 <- coeffs[1]\nb1 <- coeffs[2]\nb2 <- coeffs[3]\nestimated.optimum <- -b1/(2*b2) # as in ter Braak and Looman 1986\nestimated.niche.breadth <- 1/sqrt(-2*b2)\nc(estimated.optimum,estimated.niche.breadth) # estimated by the glm\n\npredictorX predictor \n 0.3317377 0.3922625 \n\nc(optimum,niche.breadth) # set in our simulations above\n\n[1] 0.2 0.5\n\n\nWe can demonstrate computationally that the parameter estimations are unbiased as they are maximum likelihood via the GLM. Here we will be showing the sampling variation only for niche optimum and breadth. The other two parameters, \\(\\beta_0\\) and \\(\\beta_1\\) can be placed in the code below as well, demonstrating that they are also not biased.\n\nn.samples <- 1000\nestimation.matrix <- matrix(0,n.samples,2)\ncolnames(estimation.matrix) <- c(\"optimum\",\"niche.breadth\")\n# remember that we already set the parameters for the model above, i.e., optimum and niche breadth\nfor (i in 1:n.samples){\n X <- rnorm(n.sites)\n prob.presence <- 1./(1+exp((-b0+((X-optimum)^2)/(2*niche.breadth^2)))) # this is a logistic model\n Distribution <- rbinom(n.sites,1,prob.presence)\n predictor <- cbind(X,X^2) \n model <- glm(Distribution ~ predictor,family=binomial(link=logit))\n coeffs <- coefficients(model)\n intercept <- coeffs[1]\n b1 <- coeffs[2]\n b2 <- coeffs[3]\n estimation.matrix[i,\"optimum\"] <- -b1/(2*b2)\n estimation.matrix[i,\"niche.breadth\"] <- 1/sqrt(-2*b2)\n}\n\nThere may be warnings “glm.fit: fitted probabilities numerically 0 or 1 occurred”. But that is not a problem per se. It just tells us that the for some species, their models capture the distribution values perfectly. By the way, that also happens with real data.\nLet’s observe the random variation around the parameter estimates and the average values:\n\nboxplot(estimation.matrix)\nabline(h=apply(estimation.matrix,2,mean),col=\"firebrick\")\n\n\n\napply(estimation.matrix,2,mean)\n\n optimum niche.breadth \n 0.2016913 0.4834230 \n\nc(optimum,niche.breadth) # set in our simulations above\n\n[1] 0.2 0.5\n\n\nNote how the mean values are pretty close to the true values used to generate the data. This small simulation helps one understand the principles of sampling variation and unbiased estimation.\nSimulating multiple species\nNow, let’s generalize our code to multiple species. We will create a function that allow us to make sure that all sites have at least one species present and all species are present at least in one site; this is a common (but not necessary) characteristic of data used in community ecology.\n\ngenerate_communities <- function(tolerance,E,T,n.species,n.communities){\n repeat {\n # generates variation in niche breadth across species\n niche.breadth <- runif(n.species)*tolerance \n b0 <- runif(n.species,min=-4,max=4)\n prob.presence <- matrix(data=0,nrow=n.communities,ncol=n.species)\n Dist.matrix <- matrix(data=0,nrow=n.communities,ncol=n.species)\n for(j in 1:n.species){\n # species optima are trait values; which makes sense ecologically\n prob.presence[,j] <- 1./(1+exp((-b0[j]+((E-T[j])^2)/(2*niche.breadth[j]^2)))) \n Dist.matrix[,j] <- rbinom(n.communities,1,prob.presence[,j])\n }\n n_species_c <- sum(colSums(Dist.matrix)!=0) # _c for check\n n_communities_c <- sum(rowSums(Dist.matrix)!=0)\n if ((n_species_c == n.species) & (n_communities_c==n.communities)){break}\n }\n result <- list(Dist.matrix=Dist.matrix,prob.presence=prob.presence)\n return(result)\n}\n\nNow let’s generate a community. Note that we are using one environmental gradient and one trait. We could consider more variables (trait or environmental features) by adding terms to the logistic equation above. But for the time being, that will suffice. Note, thout, that in many ecological simulations, this single predictor is considered an “environmental gradient” containing many environmental predictors. We can consider more gradients and we will discuss that later on in the workshop.\n\nset.seed(12351) # so that we all have the same results\nn.communities <- 100\nn.species <- 50\nE <- rnorm(n.communities)\nT <- rnorm(n.species)\nDist <- generate_communities(tolerance = 1.5, E, T, n.species, n.communities)\nProbs <- Dist$prob.presence\nDistribution <- Dist$Dist.matrix\n\nLet’s plot the probability values across environmental values. To do that nicely, we need to order the communities according to their environmental values as follows:\n\nE.sorted <- sort(E, index.return=TRUE)\nProbs.sorted <- Probs[E.sorted$ix,]\nE.sorted <- E.sorted$x\nmatplot(E.sorted, Probs.sorted, cex.lab=1.5,cex.axis=2,lty = \"solid\", type = \"l\", pch = 1:10, cex = 0.8,\n xlab = \"Enviroment\", ylab = \"Probability of presence\")\n\n\n\n\nAnd let’s plot presences and absences against ordered environmental and trait values:\n\nheatmap(as.matrix(Distribution),scale=\"none\",Rowv=E,Colv=T,col=c(\"white\",\"black\"),labCol=\"species\",labRow=\"communities\")\n\n\n\n\n\n\n\nClassic and simple GLMs for one trait and one environment (bivariate correlations)\n\nNow that we have a basic understanding of one GLM (logistic) and how they can model different types of community ecology data, i.e., species distributions, traits and environmental variation, we can start looking into approaches that that are used by ecologists to estimate the importance of environmental and trait variation to species distributions.\nLet’s start by calculating the simplest and widely used metric of the community weighted trait mean:\n\nCWM <- Distribution %*% T / rowSums(Distribution)\n\nFor data that are based on presence-absence, this is simply the average of species trait values within communities.\nLet’s now correlate CWM with the environment, i.e., community weighted means correlation. This is a widely used approach by ecologists:\n\nplot(CWM ~ E)\n\n\n\ncor(CWM,E)\n\n [,1]\n[1,] 0.9296338\n\n\nAgain, the community weighted means correlation is likely the most commonly used approach with 1000s of studies having been published with it.\nAnother approach is to calculate the species weighted environment means and correlate with trait values. This approach is less common (but still quite used in the ecological literature) and is sometimes referred as to species niche centroid (SNC):\n\nSNC <- t(E %*% Distribution) / colSums(Distribution)\n\nLet’s now correlate SNC with species traits:\n\nplot(T ~ SNC)\n\n\n\ncor(T,SNC)\n\n [,1]\n[1,] 0.7700065\n\n\nNote that the two correlations (CWM- and SNC-based) differ. That’s odd as they were both calculated on exactly the same information: the same Species Matrix, Environment and Trait. Peres-Neto, Dray & ter Braak (2017) demonstrated (mathematically) that this issue is related to the fact that although CWM and SNC are based on weights, they don’t standardized and correlate them with the proper weights. CWM is based on averages calculated based on the sum of species (richness or total abundance per community) and SNC is based on averages calculated based on the number of communities in which species are presence (prevalence) or their total abundance.\nBecause of that, we have found (Peres-Neto et al. 2017) a few undesirable properties of these two correlations (CWM and SNC-based correlations). One is that when the correlation is expected to be zero, the sampling variation of these correlations are quite large (i.e., low precision). Let’s evaluate this issue: Below we generate data with structure, but then use a false trait completely independent of the original one, thus destroying the link between trait and environmental variation.\n\nset.seed(120) # so that we all have the same results\nn.communities <- 100\nn.species <- 50\nn.samples <- 100 # set to larger later\n\nCWM.cor <- as.matrix(0,n.samples)\nfor (i in 1:n.samples){\n E <- rnorm(n.communities)\n T <- rnorm(n.species)\n Dist <- generate_communities(tolerance = 1.5, E, T, n.species, n.communities)\n T.false <- rnorm(n.species)\n CWM <- Dist$Dist.matrix %*% T.false / rowSums(Dist$Dist.matrix)\n CWM.cor[i] <- cor(CWM,E)\n}\n\nLet’s plot the correlations:\n\nboxplot(CWM.cor)\nabline(h=mean(CWM.cor),col=\"firebrick\")\n\n\n\n\nNote that the variation is quite large for correlations based on a random trait (i.e., T.false). For example, some correlations were greater than 0.7 and smaller than -0.60. We showed that although the variation is quite large, the expected value is zero; we would need 10000 or more simulations to make mean(CWM.cor) approach almost zero. A similar issue (i.e., large variation, low precision) happens for correlations based on SNO but we won’t simulate here for brevity. One can easily adapt the code above to do so though.\nWe have shown that precision is much increased when using the 4th corner statistic. Originally described in matrix form by Legendre et al. (1997), we (Peres-Neto et al. 2017) demonstrated that the 4th corner statisticit is a GLM assuming an identity link, i.e., normally distributed residuals.\nThe basis of the 4th corner correlation is that it starts by the standardization of the trait by the sum of their species abundances (or number of sites occupied for presence-absence data), and the standardization of the environment by the sum of their community abundances. The default standardization (function scale) transforms the variable (trait or environment) in a way that its mean and standard deviation are 0 and 1, respectively. A weighted standardization makes the weighted mean and weighted standard deviation to be 0 and 1, respectively.\nR doesn’t have a default function for weighted standardization. But this can be done using the follow function:\n\nstandardize_w <- function(X,w){\n ones <- rep(1,length(w))\n Xc <- X - ones %*% t(w)%*% X\n Xc / ones%*%sqrt(t(ones)%*%(Xc*Xc*w)) \n} \n\nLet’s get back to the original data used to calculate CWM and SNC based correlations:\n\nset.seed(12351) # so that we all have the same results\nn.communities <- 100\nn.species <- 50\nE <- rnorm(n.communities)\nT <- rnorm(n.species)\nDist <- generate_communities(tolerance = 1.5, E, T, n.species, n.communities)\nDistribution <- Dist$Dist.matrix\n\nWe then standardize environment and trait by their respective abundance sums (rows for environment & columns for trait).\n\n# make distribution matrix relative to its total sum; it makes calculations easier\nDist.rel <- Distribution/sum(Distribution)\nWn <- rowSums(Dist.rel)\nWs <- colSums(Dist.rel)\nE.std_w <- standardize_w(E,Wn)\nT.std_w <- standardize_w(T,Ws)\n\nNote: In the future, include here the calculation of the weighted mean and standard deviation of E.std_w and T.std_w to show that they are zero and one, respectively (when weighted).\nWe then calculate the community average trait (weighted standardized) or the species niche centroid (weighted standardized):\n\nCWM.w <- Dist.rel %*% T.std_w / Wn\nSNC.w <- t(E.std_w) %*% Dist.rel / Ws\n\nWe then calculate the weighted correlation between the two vectors above but their appropriate weights. In the case of CWM.w:\n\n# either using weighted correlation:\nt(CWM.w) %*% (E.std_w*Wn)\n\n [,1]\n[1,] 0.2813709\n\n# or the same value using weighted regression:\nlm(CWM.w ~ E.std_w,weights = Wn)\n\n\nCall:\nlm(formula = CWM.w ~ E.std_w, weights = Wn)\n\nCoefficients:\n(Intercept) E.std_w \n 8.804e-17 2.814e-01 \n\n\nIn the case of SNC.w:\n\n# either using weighted correlation:\nSNC.w %*% (T.std_w*Ws)\n\n [,1]\n[1,] 0.2813709\n\n# or the same value using weighted regression:\nlm(t(SNC.w)~T.std_w,weights = Ws)\n\n\nCall:\nlm(formula = t(SNC.w) ~ T.std_w, weights = Ws)\n\nCoefficients:\n(Intercept) T.std_w \n -5.000e-17 2.814e-01 \n\n\nNote that regardless whether SNC or CWM were used, the 4th corner correlation gives the same result, which makes sense mathematically as both correlations use the exact same information. The reason (again) that the CWM and SNC standard correlation approaches differ is because they don’t use appropriate weights in their standardization and weighted correlation.\nAnother issue to notice is that the 4th corner values are smaller than their standard CWM values. Whereas the CWM correlation was 0.9296, the 4th corner was 0.2814. The issue here is that the CWM correlation refers only to the trait variation among communities (trait beta-diversity), whereas the 4th corner refers to the total variation in traits (within, i.e., trait alpha diversity, and among communities, i.e., trait beta-diversity). This was demonstrated by algebraic proofs in Peres-Neto et al. (2017) but we won’t get into these details here.\nThis does bring an interesting point for the analysis of trait in a community ecology context. The relative trait variation among communities (i.e., total trait beta-diversity) and within communities (i.e., gamma trait diversity) can be estimated as follows:\n\n# Among communities \nAmong.Variation <- sum(diag(t(CWM.w)%*%(CWM.w* Wn))) * 100\n# Within communities \nWithin.Variation <- 100 - Among.Variation\nc(Among.Variation,Within.Variation)\n\n[1] 9.460287 90.539713\n\n\nThe standard CWM correlation is high because it pertains to only 9.46% of the total variation, whereas the 4th corner correlation pertains to all variation, i.e., both within and among. As the among communities component become large, the two correlations become somewhat more similar.\nLet’s now investigate the sampling properties of the 4th corner correlation as we did above for the CWM correlation, i.e., when the trait-environment correlation is expected to be zero:\n\nset.seed(120) # so that we all have the same results and the same communities and traits are generated as before\nn.communities <- 100\nn.species <- 50\nn.samples <- 100 # set to larger later\n\nCWM.4th.cor <- as.matrix(0,n.samples)\nfor (i in 1:n.samples){\n E <- rnorm(n.communities)\n T <- rnorm(n.species)\n Dist <- generate_communities(tolerance = 1.5, E, T, n.species, n.communities)\n T.false <- rnorm(n.species) # destroys the original generated relationship\n Dist.rel <- Dist$Dist.matrix/sum(Distribution)\n Wn <- rowSums(Dist.rel)\n E.std_w <- standardize_w(E,Wn)\n T.std_w.false <- standardize_w(T.false,Ws)\n CWM.w.false <- Dist.rel %*% T.std_w.false / Wn\n t(CWM.w.false) %*% (E.std_w*Wn)\n CWM.4th.cor[i] <- cor(CWM,E)\n}\n\nLet’s compare the two statistics:\n\nboxplot(cbind(CWM.cor,CWM.4th.cor))\n\n\n\n\nNote how the 4th corner correlation is a much more precise predictor around the true value of zero.\n\n\n\nStatistical hypothesis testing\n\nWe know for a while that the bivariate correlations discussed so far have elevated type I error rates based on parametric testing and under certain permutation schemes (Dray and Legendre 2008; and Dray et al. 2014). That means that when the statistical null hypothesis of no link between trait and environment will be rejected more often than the preset alpha level (significance level, e.g., 0.05 or 0.01). More recently, this was also established for more complex models (more on this later). Resolving these issues are challenging and remain a very active field of research.\nThe code so far has helped to build some intuition underlying the different bivariate correlations. We will now use a more complete utility function that allows calculating these different metrics using one single function. This function is part of Peres-Neto et al. (2017).\nDownload the utility function file:\nClick here to download it\nLoad the functions into R:\n\nsource(\"UtilityFunctions.R\")\n\nLet’s use the function that calculates a number of the bivariate correlations, which are essentially simple GLMs.\n\nset.seed(125)\nE <- rnorm(n.communities)\nT <- rnorm(n.species)\nDist <- generate_communities(tolerance = 1.5, E, T, n.species, n.communities)\nTraitEnv.res <- TraitEnvCor(Distribution,E,T, Chessel = TRUE)\nTraitEnv.res\n\n CWM.cor wCWM.cor SNC.cor \n 0.016601826 0.054714685 0.288779046 \n wSNC.cor Fourthcorner Chessel.4thcor \n 0.039080469 0.006235766 0.015313259 \n Among Wn-variance (%) Within Wn-variance (%) \n 1.298888497 98.701111503 \n\n\nIf we want to isolate the 4th corner correlation, we can simply:\n\nTraitEnv.res[\"Fourthcorner\"]\n\nFourthcorner \n 0.006235766 \n\n\nLet’s now run permutation Model 2, Model 4 and p.max for data without a link between trait and environment. We first create the data with no link:\n\nset.seed(125)\nE <- rnorm(n.communities)\nT <- rnorm(n.species)\nDist <- generate_communities(tolerance = 1.5, E, T, n.species, n.communities)\nDistribution <- Dist$Dist.matrix\nT.false <- rnorm(n.species)\nTraitEnv.res <- TraitEnvCor(Distribution,E,T.false, Chessel = FALSE)\nTraitEnv.res[\"Fourthcorner\"]\n\nFourthcorner \n 0.04168433 \n\n\nNote how the 4th corner correlation is quite low, i.e., 0.0417. Now let’s check this value with permutations:\n\nset.seed(125)\nnrepet <- 99\nobs <- TraitEnv.res[\"Fourthcorner\"]\nsim.row <- matrix(0, nrow = nrepet, ncol = 1)\nsim.col <- matrix(0, nrow = nrepet, ncol = 1)\nfor(i in 1:nrepet){\n per.row <- sample(nrow(Distribution)) # permute communities\n per.col <- sample(ncol(Distribution)) # permute species\n sim.row[i] <- TraitEnvCor(Distribution,E[per.row],T.false)[\"Fourthcorner\"]\n sim.col[i] <- TraitEnvCor(Distribution,E,T.false[per.col])[\"Fourthcorner\"]\n}\npval.row <- (length(which(abs(sim.row) >= abs(obs))) + 1) / (nrepet + 1)\npval.col <- (length(which(abs(sim.col) >= abs(obs))) + 1) / (nrepet + 1)\np.max <- max(pval.row,pval.col)\nc(pval.row,pval.col,p.max)\n\n[1] 0.01 0.47 0.47\n\n\nAs we can see, although only environmental features were important but not traits, the row permutation (across commmunities) detected the relationship as significant. Note, however, that the permutation across species did not. ter Braak et al. (2012) determined that the maximum value between the two p-values (row and column based) assures appropriate type I error rate as expected alpha.\nThe function above allows understanding the permutation procedures. That said, the utility function file has a more complete function:\n\nset.seed(125)\nCorPermutationTest(Distribution, E, T.false, nrepet = 99)\n\n cor prow pcol pmax\nCWM.cor 0.36605145 0.01 0.33 0.33\nwCWM.cor 0.28014652 0.01 0.44 0.44\nSNC.cor 0.14836877 0.39 0.36 0.39\nwSNC.cor 0.09492897 0.26 0.47 0.47\nFourthcorner 0.04168433 0.01 0.47 0.47\n\n\n\n\n\nBivariate correlations in practice\n\nI hope by now you are convinced that the 4th corner is a more robust metric of bivariate correlation (one trait and one environment). Here we will use the Aravo community plant data set (Massif du Grand Gabilier, France; Choler 2005) contained in the package ade4. We provide more explanation on the data in Dray et al. (2012). Here we will replicate the analysis in that paper. The data contain species abundances for 82 species distributed into 75 sites. Sites are described by 6 environmental variables: mean snowmelt date over the period 1997–1999, slope inclination, aspect, index of microscale landform, index of physical disturbance due to cryoturbation and solifluction, and an index of zoogenic disturbance due to trampling and burrowing activities of the Alpine marmot. All variables are quantitative except the landform and zoogenic disturbance indexes that are categorical variables with five and three categories, respectively. And eight quantitative functional traits (i.e., vegetative height, lateral spread, leaf elevation angle, leaf area, leaf thickness, specific leaf area, mass-based leaf nitrogen content, and seed mass) were measured on the 82 most abundant plant species (out of a total of 132 recorded species).\n\n\n\n\n\nLoad the package and the data:\n\n# install.packages(\"ade4\") in case you don't have it installed\nlibrary(ade4)\ndata(aravo)\ndim(aravo$spe)\n\n[1] 75 82\n\ndim(aravo$env)\n\n[1] 75 6\n\ndim(aravo$trait)\n\n[1] 82 8\n\n\nLet’s estimate the 4th corner correlations between each trait and environmental variable. nrept is the number of permutations and should be set to a reasonable high number (say 9999). Here we will use 999 to speed calculations. Note that all permutation tests (not only the ones for the 4th corner) include the observed correlation as part of the null distribution (i.e., permuted); hence the use of nrept as 999, i.e., 1000 possible permutations (the observed correlation is a possible permutation if we run the test infinite times; which is not possible; so we consider it as default. modeltype is set to 6, which is the largest p-value between model 2 permutation (entire communities in the distribution matrix) and model 4 (entire species in the distribution matrix). The p-max procedure is detailed in ter Braak et. 2012. Finally, p-values are adjusted using the false discovery rate for multiple testing.\n\nfour.comb.aravo.adj <- fourthcorner(aravo$env, aravo$spe,\naravo$traits, modeltype = 6, p.adjust.method.G = \"none\",\np.adjust.method.D = \"fdr\", nrepet = 999)\n\nResults can be retrieved by simply typing:\nfour.comb.aravo \nThe ‘classic’ table of results can be produced as follows. D2 indicates that the 4th corner correlation is to be used between the quantitative variable and each category of the qualitative variables. Other bivariate metrics of 4th corner association are also described in Dray and Legendre (2008) for qualitative-quantitative associations. In the default plot, blue cells correspond to negative signicant relationships while red cells correspond to positive signicant relationships (this can be modified using the argument col in the function fourthcorner).\n\nplot(four.comb.aravo.adj, alpha = 0.05, stat = \"D2\")\n\n\n\n\n\n\n\nStacking species information as a way to understand how to build more complex GLMs\n\nAlthough widely used (1000s of studies published using them), bivariate correlations are the simplest forms of GLMs for community data. That said, the 4th corner correlation can be calculated in a way that allows us (hopefully) to understand how more complex GLMs can be produced. They allow us understanding species stacking. Perhaps I should have considered this presentation before the calculations based on weights and standardizations (will inverst in the next version of the workshop). Let’s build a small data so that we understand this principle. Consider a very artificial distribution matrix with 4 communities and 4 species. It was made artificial so that we can understand well its structure:\n\nDistribution <- as.matrix(rbind(c(1,1,0,0),c(1,0,0,0),c(0,0,1,1),c(0,0,1,0)))\nDistribution\n\n [,1] [,2] [,3] [,4]\n[1,] 1 1 0 0\n[2,] 1 0 0 0\n[3,] 0 0 1 1\n[4,] 0 0 1 0\n\n\nLet’s create some traits and environmental features:\n\nT <- c(1,2,5,8)\nE <- c(10,12,100,112)\n\nNow let’s calculate its 4th corner correlation:\n\nTraitEnvCor(Distribution,E,T)[\"Fourthcorner\"]\n\nFourthcorner \n 0.8902989 \n\n\nThe 4th corner correlation is pretty high given the highly structured data. Another way to calculate a 4th corner correlation is by using what we refer to as an “inflated approach”. This approach allows understanding the structure of stacked information. This figure demonstrates the process and calculation:\n\n\n\n\n\nNext we stack species distributions, environment and trait information:\n\nn.species <- ncol(Distribution)\nn.sites <- nrow(Distribution)\nDist.stacked <- as.vector(Distribution)\nE.stacked <- rep(1, n.species) %x% E\nT.stacked <- T %x% rep(1, n.sites) \n\nView(cbind(Dist.stacked,E.stacked,T.stacked))\nWe then eliminatate the cells for which the distribution is zero and calculate the correlation:\n\nzeros.dist <- which(Dist.stacked==0)\ncor(E.stacked[-zeros.dist],T.stacked[-zeros.dist])\n\n[1] 0.8902989\n\n\nNote: perhaps I should have started with this explanation and then move to the more complicated way of using weights. The inflated approach is in fact a way to see how weights are given.\n\n\n\nSimulating abundance data and understanding link functions in GLMs\n\nSimple model\nAlthough community ecologists commonly work with presence-absence data, abundance data are also commonly used in many approaches. Here we will use a Poisson model to simulate community data involving species distributions, traits and environment. Although link functions are used in all families of GLMs (poisson, binomial, negative binomial, gamma, etc), we will try to provide an explanation here of what they mean using abundance data. But the same rationale will apply to all families.\n\nset.seed(100) # so that we all have the same results\nn.sites <- 100\nX <- rnorm(n.sites)\nb0 <- 0.05\nb1 <- 2\nY <- exp(b0 + b1*X)\nAbundance <- rpois(n.sites,Y)\nplot(Abundance ~ X)\n\n\n\n\nThis Poisson model has the following form. Note that multiple predictors can be considered. Here, for simplicity, we considered one predictor. Again, in many ecological simulations, this single predictor is considered an “environmental gradient” containing many environmental predictors. We can consider more gradients and we will discuss that later on in the workshop.\n\\[Y={e^{(\\beta_0+\\beta_1X_1)}}=e^{(0.05+1.2X_1)}=log(Y)=0.05+1.2X_1\\] The model can be estimated as:\n\nmodel <- glm(Abundance ~ X, family=\"poisson\")\ncoefficients(model)\n\n(Intercept) X \n 0.03095719 2.02323099 \n\nplot(model$fitted.values ~ Abundance)\n\n\n\n\nGLMs are linear models because they use link-functions to map non-linear relationships to a linear one. In this way, the link function connects the predictors in a model with the expected (mean) value of the response variable (dependent variable). In other words, the link-functions transforms the response values into new values that can be then regressed using linear approaches (Maximum Likelihood-based approaches and not simple OLS, ordinary least square approaches as in linear regression) against the X values. As we saw in the first example of the Poisson regression above, the relationship is not linear. The link-function for the Poisson distribution is ln of the response. Let’s understand this point by plotting the log(Y) and X. Note that Y has no error and Abundance has error (i.e., based on the rpois, i.e., poisson trials)\n\n# without error:\nplot(log(Y) ~ X)\n\n\n\n# with error\nplot(log(Abundance) ~ X)\n\n\n\n\nWhat does the passage “the link-function connects the predictors in a model with the expected (mean) value of the response variable (dependent variable)” mean? As you can notice, we used Poisson trials to generate error around the initial Y values. Let’s create a 100 possible trials:\n\nmult.Y <- replicate(n=100,expr=rpois(n.sites,Y))\n\nView(mult.Y)\nEach column in mult.Y contains one single trial. This would mimic, for instance, your error in estimating abundances when sampling real populations and assuming that a Poisson GLM would model your abundances across sites well. As such, in real data, obviously, we only have one “trial”. But this small demonstration hopefully helps you understand what the GLM is trying to estimate via the link-function.\nLet’s repeat the predictor X 100 times`so that it becomes compatible in size with the multiple trials; and we can then plot them:\n\nrep.X <- rep(X, times = 100)\nplot(as.vector(mult.Y) ~ rep.X,pch=16,cex=0.5,col=\"firebrick\")\n\n\n\n\nNote that larger values of abundances tend to have more error under the poisson model (which is also ecologically plausible).\nNow we can understand what the passage “the link-function connects the predictors in a model with the expected (mean) value of the response”. Let’s first increase the number of trials to 10000 and for each site (for which we have an X value), calculate its mean:\n\nmult.Y <- replicate(n=10000,expr=rpois(n.sites,Y))\nmean.mult.Y <- apply(mult.Y,1,mean)\nplot(mean.mult.Y ~ Y)\n\n\n\n\nAs we can observe, the mean across all trials (errors) equal the response variable Y, i.e., without error. Hopefully this provides a general understanding of what link functions are. A similar explanation can be given for the logistic regression (i.e., binomial error). In there we use a logit link function (transformation) instead.\nMissing predictors in GLMs as a source of error\nObviously the fit is great, particularly because we considered all the important predictors in the model. We don’t usually have all predictors in a model and this can be simulated as well. Considering the following example where two environmental predictors were used to generate the abundance data but only was used in the regression model:\n\\[p={e^{(\\beta_0+\\beta_1X_1+\\beta_1X_2)}}\\]\n\nset.seed(100) # so that we all have the same results\nn.sites <- 100\nX <- matrix(rnorm(n.sites*2),n.sites,2)\nb0 <- 2\nb1 <- 0.5\nb2 <- 1.2\nY <- exp(b0 + b1*X[,1] + b1*X[,2]) # there are more direct matricial ways to do that\nAbundance <- rpois(n.sites,Y)\nmodel <- glm(Abundance ~ X[,1], family=\"poisson\")\nmodel\n\n\nCall: glm(formula = Abundance ~ X[, 1], family = \"poisson\")\n\nCoefficients:\n(Intercept) X[, 1] \n 2.0472 0.5294 \n\nDegrees of Freedom: 99 Total (i.e. Null); 98 Residual\nNull Deviance: 532.1 \nResidual Deviance: 258.8 AIC: 637.7\n\nplot(model$fitted.values ~ Abundance)\n\n\n\nAIC(model)\n\n[1] 637.7152\n\n\nNote that the errors around predicted and true values are much greater because only one predictor was included in the GLM even though two predictors were important. Now considering both predictors:\n\nmodel <- glm(Abundance ~ X, family=\"poisson\")\nmodel\n\n\nCall: glm(formula = Abundance ~ X, family = \"poisson\")\n\nCoefficients:\n(Intercept) X1 X2 \n 1.9808 0.5300 0.4931 \n\nDegrees of Freedom: 99 Total (i.e. Null); 97 Residual\nNull Deviance: 532.1 \nResidual Deviance: 119 AIC: 500\n\nplot(model$fitted.values ~ Abundance)\n\n\n\nAIC(model)\n\n[1] 500.0011\n\n\nThis is a critical empirical (ecological) consideration because we can’t measure everything. The error is much smaller and, as a consequence, the model fit is much improved (i.e., smaller AIC values) because it considers the two predictors. It can’t be perfect because of the error related to the poisson trials that will always result in random variation (residual variation).\nA more realistic Gaussian Poisson model\nAs for the logistic model, we can also consider a more realistic Poisson model based on a Gaussian distribution:\n\\[Y={h\\cdot e^{-(\\beta_0+\\beta_1\\frac{(X-\\mu)^2}{2\\sigma^2})}}\\] As before, \\(\\mu\\) represents the species optimum and \\(\\sigma\\) its niche breadth. \\(h\\) represents the expected abundance in the optimum environmental value. Using code to simulate this model for one species; for simplicity, we will set \\(\\beta_0=0\\) and \\(\\beta_1=1\\):\n\nset.seed(110)\nX <- rnorm(n.sites)\noptimum <- 1.2\nniche.breadth <- 0.5\nh <- 104\nY <- h * exp(-(X-optimum)^2/(2*niche.breadth^2))\nAbundance <- rpois(n.sites,Y)\nplot(Abundance~X)\nabline(v=1.2,col=\"firebrick\")\n\n\n\n\nLet’s fit the Poisson model:\n\npredictor <- cbind(X,X^2) \nmodel <- glm(Abundance ~ predictor,family=\"poisson\")\nplot(model$fitted ~ X)\n\n\n\ncoeffs <- coefficients(model)\n\nAs before, parameters used to simulate the species distribution can be estimated as:\n\nb0 <- coeffs[1]\nb1 <- coeffs[2]\nb2 <- coeffs[3]\nestimated.optimum <- -b1/(2*b2) \nestimated.niche.breadth <- 1/sqrt(-2*b2)\nh <- exp(b0 + b1*estimated.optimum + b2*estimated.optimum^2)\ncbind(estimated.optimum,estimated.niche.breadth,h)\n\n estimated.optimum estimated.niche.breadth h\npredictorX 1.179753 0.4726181 104.8035\n\n\nNow we can generalize the code to generate abundance data for multiple species:\n\ngenerate_community_abundance <- function(tolerance,E,T,preset_nspecies,preset_ncommunities){\n repeat {\n # one trait, one environmental variable\n h <- runif(preset_nspecies,min=0.3,max=1)\n sigma <- runif(preset_nspecies)*tolerance\n L <- matrix(data=0,nrow=preset_ncommunities,ncol=preset_nspecies)\n for(j in 1:preset_nspecies){\n L[,j] <- 30*h[j]*exp(-(E-T[j])^2/(2*sigma[j]^2))\n #rpois(preset_ncommunities,30*h[j]*exp(-(E-T[j])^2/(2*sigma[j]^2)))\n }\n n_species_c <- sum(colSums(L)!=0) # _c for check\n n_communities_c <- sum(rowSums(L)!=0)\n if ((n_species_c == preset_nspecies) & (n_communities_c==preset_ncommunities)){break}\n }\n return(L)\n}\n\n\nset.seed(120) # so that we all have the same results\nn.communities <- 100\nn.species <- 50\nE <- rnorm(n.communities)\nT <- rnorm(n.species)\nY <- generate_community_abundance(tolerance = 1.5, E, T, n.species, n.communities)\n\nLet’s plot the expected abundance values across environmental values. To do that nicely, we need to order the communities according to their environmental values as follows:\n\nE.sorted <- sort(E, index.return=TRUE)\nY.sorted <- Y[E.sorted$ix,]\nE.sorted <- E.sorted$x\nmatplot(E.sorted, Y.sorted, cex.lab=1.5,cex.axis=2,lty = \"solid\", type = \"l\", pch = 1:10, cex = 0.8,\n xlab = \"Enviroment\", ylab = \"Abundance\")\n\n\n\n\nY, however, has no error and to create abundance values for each species (i.e., each column of Y; MARGIN = 2) according to a poisson model we can simply:\n\nAbundances <- apply(Y,MARGIN=2,function(x) rpois(n.communities,x))\n\nLet’s plot the abundance values across environmental values. With erorr, they don’t look as nice, obviously:\n\nE.sorted <- sort(E, index.return=TRUE)\nAbundances.sorted <- Abundances[E.sorted$ix,]\nE.sorted <- E.sorted$x\nmatplot(E.sorted, Abundances.sorted, cex.lab=1.5,cex.axis=2,lty = \"solid\", type = \"l\", pch = 1:10, cex = 0.8, xlab = \"Enviroment\", ylab = \"Abundance\")\n\n\n\n\nFinally, let’s calculate the 4th corner statistics for these data:\n\nTraitEnvCor(Abundances,E,T, Chessel = TRUE)[\"Fourthcorner\"]\n\nFourthcorner \n 0.5365449 \n\n\nAnd now for the data without error, i.e., before the poisson trials:\n\nTraitEnvCor(Y,E,T, Chessel = TRUE)[\"Fourthcorner\"]\n\nFourthcorner \n 0.5333836 \n\n\nDespite the error we observed once we transformed Y (values without error) into abundances (with error via the poisson trials), the bivariate correlations are pretty similar, indicating that these metrics are robust against sampling error in abundances. Note, however, that we only used one predictor which was the one used to simulate the data to begin with; empirical data are much more complex than that.\nFinally, note that, as such, bivariate correlations are calculated in the same way regardless if the data are presence-absence or abundance; biomass data could be also considered.\n\n\n\nMoving to more complex GLMs - the bilinear model\n\nLet’s go back to our stacked model:\n\n\n\n\n\nAnd now let’s get back to our stacked approach using again the simplest example we used earlier. Let’s enter the data again to make sure that we have the same data.\n\nDistribution <- as.matrix(rbind(c(1,1,0,0),c(1,0,0,0),c(0,0,1,1),c(0,0,1,0)))\nT <- c(1,2,5,8)\nE <- c(10,12,100,112)\nn.species <- ncol(Distribution)\nn.sites <- nrow(Distribution)\nDist.stacked <- as.vector(Distribution)\nE.stacked <- rep(1, n.species) %x% scale(E)\nT.stacked <- scale(T) %x% rep(1, n.sites)\n\nThere are two ways in which we can code the analysis. Using the stacked way or using a kronecker product. The kronecker product stacks the data in the same way but it’s a bit more “cryptic” and demonstrating the stacking is then easier by using simple coding. The stacked GLM below estimates the statistical interaction between Environment and Traits only. Note that the distribution for our ficitional example above is for presence and absences, hence we will use a binomial link-function (i.e., logistic regression). This can be referred as to the bilinear model by Gabriel (1998) which is rarely used in ecology but can provide a good introduction to what “stacking” means which is critical to understand more complex GLMs.\nUsing the stacked vectors above, we have:\n\n predictor <- E.stacked * T.stacked\n model <- glm(Dist.stacked ~ predictor,family=binomial(link=logit))\n summary(model)\n\n\nCall:\nglm(formula = Dist.stacked ~ predictor, family = binomial(link = logit))\n\nDeviance Residuals: \n Min 1Q Median 3Q Max \n-2.1282 -0.5101 -0.2570 0.7417 1.3162 \n\nCoefficients:\n Estimate Std. Error z value Pr(>|z|) \n(Intercept) -0.9160 0.7681 -1.193 0.2330 \npredictor 2.4991 1.1975 2.087 0.0369 *\n---\nSignif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n\n(Dispersion parameter for binomial family taken to be 1)\n\n Null deviance: 21.170 on 15 degrees of freedom\nResidual deviance: 13.597 on 14 degrees of freedom\nAIC: 17.597\n\nNumber of Fisher Scoring iterations: 5\n\n\nThe stacking we saw can be easily done using matrix algebra (the early presentation is helpful to understand the principles though). To do it in algebra, we use the kronecker product as follows:\n\\[Y= T\\otimes E\\]\nAs such, the bilinear model is testing the statistical interaction between traits and environmental variables.\nwhich in R becomes:\n\npredictor2 <- T %x% E\nmodel <- glm(Dist.stacked ~ predictor,family=binomial(link=logit))\nsummary(model)\n\n\nCall:\nglm(formula = Dist.stacked ~ predictor, family = binomial(link = logit))\n\nDeviance Residuals: \n Min 1Q Median 3Q Max \n-2.1282 -0.5101 -0.2570 0.7417 1.3162 \n\nCoefficients:\n Estimate Std. Error z value Pr(>|z|) \n(Intercept) -0.9160 0.7681 -1.193 0.2330 \npredictor 2.4991 1.1975 2.087 0.0369 *\n---\nSignif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n\n(Dispersion parameter for binomial family taken to be 1)\n\n Null deviance: 21.170 on 15 degrees of freedom\nResidual deviance: 13.597 on 14 degrees of freedom\nAIC: 17.597\n\nNumber of Fisher Scoring iterations: 5\n\n\nNote that the two ways to run the model results in the exact same estimates. Here we should interpret the slope for the model as the strength between trait and environment, i.e., \\(\\beta_1 = 2.4991\\). Obviously the bilinear model can be easily extended to any class of GLMs as well depending on the nature of the response variable (e.g., poisson, negative binomial, etc; more on these below).\nNote also that we could have considered multiple traits and environments (as long as we have enough degrees of freedom).\nStacked or bilinear model on the Aravo data set\nLet’s apply the Aravo data set we saw early here. We will reduce the environmental matrix by removing the qualitative variables. These can be easily accommodated but for the sake of speed, we will reduce it.\n\nE <- aravo$env[,c(\"Aspect\",\"Slope\",\"Snow\")]\nE <- as.matrix(E)\nT <- as.matrix(aravo$trait)\n\nNow we apply the kronecker product using the base function kronecker rather than %x% that we saw early. This function generate names for each column of the matrix (i.e., interactions between each trait and predictor). The columns contain all possible two by two (pairwise) combinations of traits and environmental features.\n\nTE <- kronecker(T, E, make.dimnames = TRUE)\ndim(TE)\n\n[1] 6150 24\n\ncolnames(TE)\n\n [1] \"Height:Aspect\" \"Height:Slope\" \"Height:Snow\" \"Spread:Aspect\"\n [5] \"Spread:Slope\" \"Spread:Snow\" \"Angle:Aspect\" \"Angle:Slope\" \n [9] \"Angle:Snow\" \"Area:Aspect\" \"Area:Slope\" \"Area:Snow\" \n[13] \"Thick:Aspect\" \"Thick:Slope\" \"Thick:Snow\" \"SLA:Aspect\" \n[17] \"SLA:Slope\" \"SLA:Snow\" \"N_mass:Aspect\" \"N_mass:Slope\" \n[21] \"N_mass:Snow\" \"Seed:Aspect\" \"Seed:Slope\" \"Seed:Snow\" \n\n\nBecause we have abundance data, let’s run the GLM using the poisson model (log link function) and the negative binomial which may work better when data are overdispersed (e.g., too many zeros, i.e., absences).\n\nDist.stacked <- as.vector(as.matrix(aravo$spe))\nColNames <- colnames(TE)\nTE <- scale(TE) # so that slopes can be compared directly to one another\ncolnames(TE) <- ColNames\nmodel.bilinear.poisson <- glm(Dist.stacked ~ TE,family=\"poisson\")\nlibrary(MASS)\nmodel.bilinear.negBinom <- glm.nb(Dist.stacked ~ TE)\n\nLet’s compare the two models:\n\nc(BIC(model.bilinear.poisson),BIC(model.bilinear.negBinom))\n\n[1] 9310.771 8784.627\n\n\nThe BIC suggests that negative binomial fits the data better (smaller BIC, better fit).\nModel diagnostics for non-Gaussian models are challenging and often standard tools don’t provide a good way to assess quality of models. Let’s check model residuals using the more classic approach. sppVec below will be used to create a different color for each species.\n\n# create a vector of species names compatible with the stacked model:\nsppVec = rep(row.names(aravo$traits),each=nrow(aravo$spe))\nplot(residuals(model.bilinear.negBinom),log(fitted(model.bilinear.negBinom)),col=as.numeric(factor(sppVec)),xlab=\"Fitted values [log scale]\",ylab=\"residuals\")\n\n\n\n\nAs we can see, the plot is pretty bad; and that’s a common feature for GLMs.\nDunn and Smyth (1996) developed a new class of residuals that allows a much better way to diagnose whether the model fits the data well. The package DHARMa implements the approach. A tutorial for this package and the package features can be found at: 0), function (eta) \nTRUE, function (object, nsim) \n{\n ftd <- fitted(object)\n rnegbin(nsim * length(ftd), ftd, .Theta)\n}))\n\n\nWarning: Something went wrong when calculating the pseudo R-squared. Returning NA\ninstead.\n\n\n\n\n\n \n Observations \n 6150 \n \n \n Dependent variable \n Dist.stacked \n \n \n Type \n Generalized linear model \n \n \n Family \n Negative Binomial(0.5278) \n \n \n Link \n log \n \n\n \n\n \n 𝛘²(NA) \n NA \n \n \n Pseudo-R² (Cragg-Uhler) \n NA \n \n \n Pseudo-R² (McFadden) \n NA \n \n \n AIC \n 8609.80 \n \n \n BIC \n 8784.63 \n \n\n \n \n \n \n Est. \n S.E. \n z val. \n p \n \n \n\n \n (Intercept) \n -1.27 \n 0.03 \n -40.67 \n 0.00 \n \n \n TEHeight:Aspect \n 0.09 \n 0.11 \n 0.81 \n 0.42 \n \n \n TEHeight:Slope \n 0.08 \n 0.05 \n 1.56 \n 0.12 \n \n \n TEHeight:Snow \n -0.07 \n 0.11 \n -0.69 \n 0.49 \n \n \n TESpread:Aspect \n 0.06 \n 0.10 \n 0.56 \n 0.58 \n \n \n TESpread:Slope \n 0.07 \n 0.06 \n 1.18 \n 0.24 \n \n \n TESpread:Snow \n -0.38 \n 0.10 \n -3.82 \n 0.00 \n \n \n TEAngle:Aspect \n 0.05 \n 0.11 \n 0.50 \n 0.62 \n \n \n TEAngle:Slope \n 0.21 \n 0.07 \n 2.99 \n 0.00 \n \n \n TEAngle:Snow \n -0.35 \n 0.10 \n -3.52 \n 0.00 \n \n \n TEArea:Aspect \n 0.05 \n 0.12 \n 0.36 \n 0.72 \n \n \n TEArea:Slope \n 0.01 \n 0.06 \n 0.16 \n 0.87 \n \n \n TEArea:Snow \n -0.24 \n 0.12 \n -1.90 \n 0.06 \n \n \n TEThick:Aspect \n -0.01 \n 0.09 \n -0.09 \n 0.93 \n \n \n TEThick:Slope \n 0.10 \n 0.05 \n 2.09 \n 0.04 \n \n \n TEThick:Snow \n -0.17 \n 0.09 \n -1.91 \n 0.06 \n \n \n TESLA:Aspect \n 0.45 \n 0.19 \n 2.43 \n 0.02 \n \n \n TESLA:Slope \n -0.31 \n 0.14 \n -2.19 \n 0.03 \n \n \n TESLA:Snow \n -0.42 \n 0.15 \n -2.81 \n 0.00 \n \n \n TEN_mass:Aspect \n -0.60 \n 0.19 \n -3.10 \n 0.00 \n \n \n TEN_mass:Slope \n -0.06 \n 0.15 \n -0.38 \n 0.70 \n \n \n TEN_mass:Snow \n 0.67 \n 0.15 \n 4.54 \n 0.00 \n \n \n TESeed:Aspect \n 0.30 \n 0.11 \n 2.80 \n 0.01 \n \n \n TESeed:Slope \n 0.11 \n 0.05 \n 2.21 \n 0.03 \n \n \n TESeed:Snow \n -0.50 \n 0.11 \n -4.39 \n 0.00 \n \n\n\n Standard errors: MLE\n\n\n\nThe package jtools offers a variety of table and graphical outputs and is worth exploring. Here we will produce a confidence interval plot for each slope. This will take a moment (one minute or less):\n\nplot_summs(model.bilinear.negBinom, scale = TRUE)\n\nError in glm.control(...) : \n unused argument (family = list(\"Negative Binomial(0.5278)\", \"log\", function (mu) \nlog(mu), function (eta) \npmax(exp(eta), .Machine$double.eps), function (mu) \nmu + mu^2/.Theta, function (y, mu, wt) \n2 * wt * (y * log(pmax(1, y)/mu) - (y + .Theta) * log((y + .Theta)/(mu + .Theta))), function (y, n, mu, wt, dev) \n{\n term <- (y + .Theta) * log(mu + .Theta) - y * log(mu) + lgamma(y + 1) - .Theta * log(.Theta) + lgamma(.Theta) - lgamma(.Theta + y)\n 2 * sum(term * wt)\n}, function (eta) \npmax(exp(eta), .Machine$double.eps), expression({\n if (any(y < 0)) stop(\"negative values not allowed for the negative binomial family\")\n n <- rep(1, nobs)\n mustart <- y + (y == 0)/6\n}), function (mu) \nall(mu > 0), function (eta) \nTRUE, function (object, nsim) \n{\n ftd <- fitted(object)\n rnegbin(nsim * length(ftd), ftd, .Theta)\n}))\n\n\nWarning: Something went wrong when calculating the pseudo R-squared. Returning NA\ninstead.\n\n\nRegistered S3 methods overwritten by 'broom':\n method from \n tidy.glht jtools\n tidy.summary.glht jtools\n\n\nLoading required namespace: broom.mixed\n\n\n\n\n\nOne needs to be careful when interpreting these confidence intervals as they were produced parametrically and they may be biased as we discussed in the section on statistical hypothesis testing. Again, this is a strong area of development among quantitative ecologists; but we haven’t yet derived unified views on this issue.\nWe can also plot the coefficients building:\n\ncf <- coefficients(model.bilinear.negBinom)[-1] # removes the intercept\ncfInter <- matrix(t(cf),nrow=ncol(E))\ncolnames(cfInter) <- colnames(T)\nrownames(cfInter) <- colnames(E)\ncfInter\n\n Height Spread Angle Area Thick SLA\nAspect 0.08562528 0.05659044 0.05406318 0.04512061 -0.008000594 0.4512878\nSlope 0.08477186 0.06555292 0.20518548 0.01057746 0.101762893 -0.3083102\nSnow -0.07428183 -0.37726596 -0.35230429 -0.23652105 -0.174573655 -0.4210057\n N_mass Seed\nAspect -0.59525146 0.2977853\nSlope -0.05644061 0.1137532\nSnow 0.67458707 -0.5011741\n\n# install.packages(\"lattice\")\nlibrary(lattice)\na <- max(abs(cfInter))\ncolort = colorRampPalette(c(\"blue\",\"white\",\"red\"))\nlevelplot(cfInter, xlab=\"traits\",ylab=\"environment\", col.regions=colort(100), at=seq(-a, a, length=100))\n\n\n\n\n\n\n\nConsidering main effects of trait and environment, and their interactions - predicting and explaining species distributions\n\nThe bilinear model estimates and test for the interactions between traits and environmental features in a single model. That allows for partial slopes to be estimated (i.e., in which the effects of one trait-environment interaction is independent of the others as in standard linear regression models and GLMs). Understanding partial slopes is essential for inference and usually covered in Intro statistics for biologists/ecologists under multiple regression. A standard definition is “The partial slope in multiple regression (or GLM) is the slope of the relationship between a predictor variable that is independent of the other predictor variables and the criterion. It is also the regression coefficient for the predictor variable in question.” (https://onlinestatbook.com/2/glossary/partial_slope.html).\nNow, we may want to consider also the main effects of each environmental feature and traits in addition to their interactions. This is the model implemented in Jamil et al. (2013) and Brown et al. (2014). The Brown model et al. model is:\n\\[{ln(Y_{ij}) = \\beta_0\\ +\\beta_1env_i\\ +\\beta_2env_i^2\\ +\\beta_3spp_j\\ +\\beta_4(env \\times\\ trait)_{ij}\\ }\\] where \\(\\beta_0\\) is the overall intercept for the model, \\(\\beta_1env_i\\) contains the slopes for each environmental variable, the model also consider square terms for the environmental variables \\(\\beta_2env_i^2\\), \\(\\beta_3spp_j\\) contains species-specific intercept terms which allows predictions for each species separately, \\(\\beta_4(env \\times\\ trait)_{ij}\\) contains the slopes for each trait by environment interaction (the 4th corner slopes). Whereas Brown et al. treated \\(spp_j\\) as fixed, Jamil et al. (2013) treated as random (more on this later). I’ve followed the formulation notation given in Brown et al. to facilitate understanding their paper; but we could easily change by the notation used in the mixed model selection (following Gelman and Hill 2007).\nBy setting species-specific intercept terms (i.e., \\(\\beta_3spp_j\\)) we can predict species in their appropriate scale of abundance variation. As such, we can use these types of models to predict species distributions. This sort of modelling is becoming the standard for predicting multiple species because it considers multiple types of predictors (trait, environments, non-linearities) and their interactions. Single species models, for instance, can’t consider trait variation and the interactions of traits and environment. As such, stacked models are extremely powerful tools even for modelling single species distributions.\nThe Brown et al. model can be fit using the package mvabund as follows:\n\n# install.packages(\"mvabund\")\nlibrary(mvabund)\nglm.trait.res <- traitglm(as.matrix(aravo$spe),E,T,family=\"negative.binomial\",col.intercepts=TRUE)\nBIC(glm.trait.res)\n\n l \n8104.818 \n\n\nAll coefficients of the model can be retrieved by:\n\ncoefficients(glm.trait.res)\n\n l\n(Intercept) -1.939671753\nsppAlch.glau -0.054831143\nsppAlch.pent 0.024330521\nsppAlch.vulg -0.155929316\nsppAlop.alpi 0.069840352\nsppAndr.brig -0.144086942\nsppAndr.vita -0.117405506\nsppAnte.carp -0.105193294\nsppAnte.dioi -0.259135963\nsppAnth.alpe -0.404567216\nsppAnth.nipp -0.069393787\nsppArni.mont -0.265964212\nsppAste.alpi -0.324558310\nsppAven.vers -0.108786793\nsppBart.alpi -0.332898371\nsppCamp.sche -0.008108304\nsppCard.alpi -0.136528887\nsppCare.foet 0.027908430\nsppCare.parv -0.174556575\nsppCare.rosa -0.091371379\nsppCare.rupe -0.182772040\nsppCare.semp -0.112095430\nsppCera.cera -0.171760014\nsppCera.stri -0.021497460\nsppCirs.acau -0.188888639\nsppDrab.aizo -0.118690070\nsppDrya.octo -0.358279264\nsppErig.unif -0.059293913\nsppFest.laev -0.365739677\nsppFest.quad -0.105113832\nsppFest.viol -0.058339848\nsppGent.acau -0.181050369\nsppGent.camp -0.134520188\nsppGent.vern -0.044346876\nsppGeum.mont 0.064963289\nsppHeli.sede -0.217416821\nsppHier.pili -0.138692435\nsppHomo.alpi -0.207003373\nsppKobr.myos -0.028361647\nsppLeon.pyre 0.029558348\nsppLeuc.alpi -0.003570705\nsppLigu.muto -0.064014046\nsppLloy.sero -0.284035626\nsppLotu.alpi -0.144194010\nsppLuzu.lute -0.193109208\nsppMinu.sedo 0.021602219\nsppMinu.vern -0.137286811\nsppMyos.alpe -0.092884602\nsppOmal.supi 0.033812911\nsppOxyt.camp -0.233480701\nsppOxyt.lapp -0.201732614\nsppPhyt.orbi -0.327727501\nsppPlan.alpi 0.066971460\nsppPoa.alpi 0.095801892\nsppPoa.supi -0.203286074\nsppPoly.vivi -0.016324658\nsppPote.aure 0.053779431\nsppPote.cran -0.126165407\nsppPote.gran -0.231501706\nsppPuls.vern -0.096096734\nsppRanu.kuep -0.020389979\nsppSagi.glab -0.011366535\nsppSali.herb 0.053863437\nsppSali.reti -0.286340876\nsppSali.retu -0.255645078\nsppSali.serp -0.283448058\nsppSaxi.pani -0.185168997\nsppScab.luci -0.331712183\nsppSedu.alpe -0.065750719\nsppSemp.mont -0.074418068\nsppSene.inca -0.162375900\nsppSesl.caer -0.205203677\nsppSibb.proc 0.019139245\nsppSile.acau -0.179836450\nsppTara.alpi -0.250167730\nsppThym.poly -0.280189375\nsppTrif.alpi -0.134717635\nsppTrif.badi -0.322563479\nsppTrif.thal -0.225527793\nsppVero.alli -0.293989557\nsppVero.alpi -0.100779079\nsppVero.bell -0.011889063\nAspect 0.014997588\nSlope 0.064347175\nSnow -0.303043451\nAspect.squ 0.013997280\nSlope.squ -0.047627887\nSnow.squ -0.274070121\nAspect.Height -0.010645817\nAspect.Spread -0.070752741\nAspect.Angle -0.083977548\nAspect.Area -0.040276747\nAspect.Thick -0.082064700\nAspect.SLA 0.065782084\nAspect.N_mass -0.138709436\nAspect.Seed 0.042758169\nSlope.Height -0.020464655\nSlope.Spread 0.023128427\nSlope.Angle -0.018699260\nSlope.Area -0.027960323\nSlope.Thick -0.012369639\nSlope.SLA -0.108694248\nSlope.N_mass 0.021179434\nSlope.Seed 0.014142823\nSnow.Height -0.209648151\nSnow.Spread 0.049505713\nSnow.Angle -0.188496204\nSnow.Area -0.046298194\nSnow.Thick 0.099956790\nSnow.SLA 0.309130472\nSnow.N_mass 0.317287032\nSnow.Seed -0.169753499\n\n\nThe overall intercept \\(\\beta_0=-1.9397\\), the individual intercept for each species \\(\\beta_3spp_j\\) are the coefficients above starting with spp; for instance, the individual slope for Alch.glau (1st species in the list) is \\(\\beta_3spp_1=-0.055\\). The slopes for each environmental variable appear under the names we gave. For instance, the slope for aspect is \\(\\beta_1env_aspect=0.015\\). Note that .squ in the coefficients are the slopes for the squared environmental terms; for instance \\(\\beta_2env_{snow}^2=-0.274\\). Finally we have the 4th corner slopes. For instance, \\(\\beta_4(env \\times\\ trait)_{snow,seed\\_mass}=-0.1698\\). Remember that snow here refers to the mean snowmelt date. As such, communities with large seed masses (in average) are found in sites that have early snowmelt dates compared to sites with late snowmelt dates; these sites have communities that tend to have small seed masses in average.\nLet’s understand this model by programming it from scratch. That’s really the best way to understand models; and whenever possible I try to demonstrate them from ‘scratch’; not always possible depending on the amount of operations (e.g., mixed models) and our abilities to understand large codes . But this one is simple enough that we can do it:\n\nn.species <- ncol(aravo$spe)\nn.communities <- nrow(aravo$spe)\nn.env.variables <- ncol(E)\n# repeats each trait to make it compatible (vectorized) with the stacked species distributions\ntraitVec <- T[rep(1:n.species,each=n.communities),]\n# repeats each environmental variable to make it compatible (vectorized) with the stacked species distributions:\nenvVec <- matrix(rep(t(E),n.species),ncol=NCOL(E),byrow=TRUE)\n# creates an intercept for each species:\nspecies.intercepts <- rep(1:n.species,each=n.communities)\nspecies.intercepts <- as.factor(species.intercepts)\nmod <- as.formula(\"~species.intercepts-1\")\nspecies.intercepts <- model.matrix(mod)[,-1]\n# the interaction terms:\nTE <- kronecker(T, E, make.dimnames = TRUE)\n# combining the predictors in a single matrix:\npreds <- cbind(species.intercepts,envVec,envVec^2,TE)\n# running the model\nmodel.bilinear.negBinom.Brown <- glm.nb(Dist.stacked ~ preds)\n\nAnd as we can see, they are exactly the same model:\n\nBIC(glm.trait.res)\n\n l \n8104.818 \n\nBIC(model.bilinear.negBinom.Brown)\n\n[1] 8104.818\n\n\nWe can easily adapt the graphical and diagnostic outputs for this model as well, but we won’t for simplicity.\n\nsumm(model.bilinear.negBinom)\n\nError in glm.control(...) : \n unused argument (family = list(\"Negative Binomial(0.5278)\", \"log\", function (mu) \nlog(mu), function (eta) \npmax(exp(eta), .Machine$double.eps), function (mu) \nmu + mu^2/.Theta, function (y, mu, wt) \n2 * wt * (y * log(pmax(1, y)/mu) - (y + .Theta) * log((y + .Theta)/(mu + .Theta))), function (y, n, mu, wt, dev) \n{\n term <- (y + .Theta) * log(mu + .Theta) - y * log(mu) + lgamma(y + 1) - .Theta * log(.Theta) + lgamma(.Theta) - lgamma(.Theta + y)\n 2 * sum(term * wt)\n}, function (eta) \npmax(exp(eta), .Machine$double.eps), expression({\n if (any(y < 0)) stop(\"negative values not allowed for the negative binomial family\")\n n <- rep(1, nobs)\n mustart <- y + (y == 0)/6\n}), function (mu) \nall(mu > 0), function (eta) \nTRUE, function (object, nsim) \n{\n ftd <- fitted(object)\n rnegbin(nsim * length(ftd), ftd, .Theta)\n}))\n\n\nWarning: Something went wrong when calculating the pseudo R-squared. Returning NA\ninstead.\n\n\n\n\n\n \n Observations \n 6150 \n \n \n Dependent variable \n Dist.stacked \n \n \n Type \n Generalized linear model \n \n \n Family \n Negative Binomial(0.5278) \n \n \n Link \n log \n \n\n \n\n \n 𝛘²(NA) \n NA \n \n \n Pseudo-R² (Cragg-Uhler) \n NA \n \n \n Pseudo-R² (McFadden) \n NA \n \n \n AIC \n 8609.80 \n \n \n BIC \n 8784.63 \n \n\n \n \n \n \n Est. \n S.E. \n z val. \n p \n \n \n\n \n (Intercept) \n -1.27 \n 0.03 \n -40.67 \n 0.00 \n \n \n TEHeight:Aspect \n 0.09 \n 0.11 \n 0.81 \n 0.42 \n \n \n TEHeight:Slope \n 0.08 \n 0.05 \n 1.56 \n 0.12 \n \n \n TEHeight:Snow \n -0.07 \n 0.11 \n -0.69 \n 0.49 \n \n \n TESpread:Aspect \n 0.06 \n 0.10 \n 0.56 \n 0.58 \n \n \n TESpread:Slope \n 0.07 \n 0.06 \n 1.18 \n 0.24 \n \n \n TESpread:Snow \n -0.38 \n 0.10 \n -3.82 \n 0.00 \n \n \n TEAngle:Aspect \n 0.05 \n 0.11 \n 0.50 \n 0.62 \n \n \n TEAngle:Slope \n 0.21 \n 0.07 \n 2.99 \n 0.00 \n \n \n TEAngle:Snow \n -0.35 \n 0.10 \n -3.52 \n 0.00 \n \n \n TEArea:Aspect \n 0.05 \n 0.12 \n 0.36 \n 0.72 \n \n \n TEArea:Slope \n 0.01 \n 0.06 \n 0.16 \n 0.87 \n \n \n TEArea:Snow \n -0.24 \n 0.12 \n -1.90 \n 0.06 \n \n \n TEThick:Aspect \n -0.01 \n 0.09 \n -0.09 \n 0.93 \n \n \n TEThick:Slope \n 0.10 \n 0.05 \n 2.09 \n 0.04 \n \n \n TEThick:Snow \n -0.17 \n 0.09 \n -1.91 \n 0.06 \n \n \n TESLA:Aspect \n 0.45 \n 0.19 \n 2.43 \n 0.02 \n \n \n TESLA:Slope \n -0.31 \n 0.14 \n -2.19 \n 0.03 \n \n \n TESLA:Snow \n -0.42 \n 0.15 \n -2.81 \n 0.00 \n \n \n TEN_mass:Aspect \n -0.60 \n 0.19 \n -3.10 \n 0.00 \n \n \n TEN_mass:Slope \n -0.06 \n 0.15 \n -0.38 \n 0.70 \n \n \n TEN_mass:Snow \n 0.67 \n 0.15 \n 4.54 \n 0.00 \n \n \n TESeed:Aspect \n 0.30 \n 0.11 \n 2.80 \n 0.01 \n \n \n TESeed:Slope \n 0.11 \n 0.05 \n 2.21 \n 0.03 \n \n \n TESeed:Snow \n -0.50 \n 0.11 \n -4.39 \n 0.00 \n \n\n\n Standard errors: MLE\n\n\n\nAs mentioned earlier, we can get predicted models per species, making stacked models not only a community model but also considering information from multiple sources for single species distributions as well:\n\nfitted.by.species <- matrix(glm.trait.res$fitted,n.communities,n.species)\n\nPredicted abundance values per species are in columns:\nView(fitted.by.species)\n\n\n\nA very brief way to understand mixed models: the Simpson’s paradox \n\nSpecies and sites are not likely to differ from one another randomly but rather have some sites more similar to others (or more different). We call this a hierarchical structure. For instance, sites that are more close to one another may have more similar values than sites further way. Or some species may be more similar in abundance than others, and so on.\nWhen using linear models and GLMS, researchers often ignore the hierarchical structure of the data (some sites have more similar or differences in total abundances of species, some species have more similar or differences in their total abundances). As such, standard GLMs can generate biased variance estimates and increase the likelihood of committing type I errors (i.e., rejecting the statistical null hypothesis more often than set by alpha, i.e., significance level).\nAlthough this is very interesting ecologically, it does bring some inferential challenges (parameter estimation and statistical hypothesis testing) when fitting statistical models. GLMM (Generalized Linear Mixed Models) are then used to deal with these issues. This paper by Harrison et al. (2018) provides a great Introduction to GLLMs for ecologists: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5970551/.\nOne common feature here is that species may differ in the way they are structured by environmental and/or trait variation. This can be well described by the Simpson’s paradox (Simpson 1951), which is defined “as a phenomenon in probability and statistics in which a trend appears in several groups of data but disappears or reverses when the groups are combined.”\nLet’s understand this paradox by simulating some data (code not show here) and graphing it. This sort of demonstration has become somewhat common when explaining the utility of mixed model.\n\n\n\n\n\n\n\n\nAt first glance, the influence of temperature on abundance is positive if we consider the variation across all data points independent of the sites. However, within species, the influence of the environment is negative. As such, it is obvious that there is variation among species that can’t be explained by temperature alone. As such, we should consider a mixed model with temperature as a fixed factor (measured variable) and species as a random factor. Obviously one question of interest is why do species vary in their effects of temperature. But we don’t have other predictors that could assist in explaining these differences (e.g., physiology). Perhaps considering traits could assist in determining this variation (more on that later).\nThe data was saved in a matrix called data.Simpson. For simplicity, we will treat these data as normally distributed. The data were generated assuming normality any way; the goal here is just a demonstration.\nLet’s analyze these data with a fixed model using a simple regression:\n\nlibrary(jtools)\nlm.mod <- lm(abundance ~ scale(temperature),data=data.Simpson)\nsumm(lm.mod,scale = TRUE)\n\n\n\n\n \n Observations \n 100 \n \n \n Dependent variable \n abundance \n \n \n Type \n OLS linear regression \n \n\n \n\n \n F(1,98) \n 15.13 \n \n \n R² \n 0.13 \n \n \n Adj. R² \n 0.12 \n \n\n \n \n \n \n Est. \n S.E. \n t val. \n p \n \n \n\n \n (Intercept) \n -0.08 \n 0.18 \n -0.48 \n 0.63 \n \n \n `scale(temperature)` \n 0.69 \n 0.18 \n 3.89 \n 0.00 \n \n\n\n Standard errors: OLS; Continuous predictors are mean-centered and scaled by 1 s.d.\n\n\n\nAs we can see, the overal influence of temperature is positive and significant, explaining 12% of the variation in abundance as a function of temperature (i.e., \\(R^2=0.12\\)).\nLet’s consider now a mixed effect model that we estimate the variation in intercepts but still assume a common slope for all species. This is a common procedure in mixed model effects, i.e., starting with the simplest model. This fixed effect is coded as usually and the random effect is coded as (1|species), where 1 means the intercepts (common way to code the intercept in statistical models). As such, one intercept per species is estimated. The scale=TRUE in the function summ below reports the analysis with standardized predictors.\n\n# install.packages(\"lme4\")\nlibrary(lme4)\n\nLoading required package: Matrix\n\n\n\nAttaching package: 'Matrix'\n\n\nThe following objects are masked from 'package:tidyr':\n\n expand, pack, unpack\n\nlm.mod.intercept <- lmer(abundance ~ temperature + (1|species),data=data.Simpson)\nsumm(lm.mod.intercept,scale = TRUE)\n\n\n\n\n \n Observations \n 100 \n \n \n Dependent variable \n abundance \n \n \n Type \n Mixed effects linear regression \n \n\n \n\n \n AIC \n 343.74 \n \n \n BIC \n 354.16 \n \n \n Pseudo-R² (fixed effects) \n 0.30 \n \n \n Pseudo-R² (total) \n 0.95 \n \n\n \n \nFixed Effects\n \n \n Est. \n S.E. \n t val. \n d.f. \n p \n \n \n\n \n (Intercept) \n -0.08 \n 1.88 \n -0.04 \n 3.94 \n 0.97 \n \n \n temperature \n -2.84 \n 0.35 \n -8.10 \n 97.70 \n 0.00 \n \n\n\n p values calculated using Kenward-Roger standard errors and d.f. ; Continuous predictors are mean-centered and scaled by 1 s.d.\n \n \nRandom Effects\n \n Group \n Parameter \n Std. Dev. \n \n \n\n \n species \n (Intercept) \n 4.20 \n \n \n Residual \n \n 1.16 \n \n\n \n \nGrouping Variables\n \n Group \n # groups \n ICC \n \n \n\n \n species \n 5 \n 0.93 \n \n\n\n\n\nWow, what a change in the interpretation. By considering variation in intercepts across species, the fixed effect influence of temperature is now negative (as we should expect). Note, however, that we had information on a categorical factor, i.e, species, that could be used to estimate random effects related to variation among them. The variation (standard deviation) of intercepts among species is quite large in contrast to residuals; 4.20 against 1.16, respectively. The explanatory power of variation among intercepts make the \\(R^2=0.95\\) increase dramatically in contrast to the fixed model, demonstrating that the species random effect has a huge effect and ability to improve the model predictive power. We also find the ICC (Intra Class Correlation) which measures how similar the abundance is within groups, i.e., species. The ICC is 0.93, indicating that abundance values are more similar within than among species.\nThe variation in intercepts can be plotted as follows:\n\nlibrary(ggplot2)\nintercepts <- coefficients(lm.mod.intercept)$species[,\"(Intercept)\"]\nslopes <- coefficients(lm.mod.intercept)$species[,\"temperature\"]\nlines <- data.frame(intercepts,slopes)\nlines[\"species\"] <- unique(data.Simpson[,\"species\"])\ndata.Simpson$pred <- predict(lm.mod.intercept)\nggplot() +\ngeom_point(data=data.Simpson,aes(x=temperature,y=abundance,color=species),size=1) + \ngeom_abline(aes(intercept = `(Intercept)`, slope = temperature),size = 1.5,as.data.frame(t(fixef(lm.mod.intercept)))) +\ngeom_abline(data = lines, aes(intercept=intercepts, slope=slopes, color=species)) +\ntheme_classic() + \nxlab(\"Temperature\") + ylab(\"log(Abundance)\")\n\nWarning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.\nℹ Please use `linewidth` instead.\n\n\n\n\n\nThe black line represents the common model. Since only intercepts were allowed to vary, the species per slope are the same as the fixed model (after controlling for variation across species, which made the overall slope to be negative).\nFinally, let’s estimate the random intercept and slope model. Here we estimate variation due to differences in intercepts and slopes across species:\n\nlm.mod.interceptSlope <- lmer(abundance ~ temperature + (1 + temperature|species),data=data.Simpson)\nsumm(lm.mod.interceptSlope,scale = TRUE)\n\n\n\n\n \n Observations \n 100 \n \n \n Dependent variable \n abundance \n \n \n Type \n Mixed effects linear regression \n \n\n \n\n \n AIC \n 336.10 \n \n \n BIC \n 351.73 \n \n \n Pseudo-R² (fixed effects) \n 0.31 \n \n \n Pseudo-R² (total) \n 0.96 \n \n\n \n \nFixed Effects\n \n \n Est. \n S.E. \n t val. \n d.f. \n p \n \n \n\n \n (Intercept) \n 0.11 \n 1.75 \n 0.06 \n 3.99 \n 0.95 \n \n \n temperature \n -2.91 \n 0.84 \n -3.45 \n 3.98 \n 0.03 \n \n\n\n p values calculated using Kenward-Roger standard errors and d.f. ; Continuous predictors are mean-centered and scaled by 1 s.d.\n \n \nRandom Effects\n \n Group \n Parameter \n Std. Dev. \n \n \n\n \n species \n (Intercept) \n 3.84 \n \n \n species \n temperature \n 1.73 \n \n \n Residual \n \n 1.05 \n \n\n \n \nGrouping Variables\n \n Group \n # groups \n ICC \n \n \n\n \n species \n 5 \n 0.93 \n \n\n\n\n\nThe variation (standard deviation) in intercepts across species in much larger (3.84) than slopes (1.73). Is the predictive power between the two models significant? In order words, does a model that estimate independent slopes for each species explain more variation than one that only considers variation in intercepts? We can simply compare the BIC of both models:\n\nc(BIC(lm.mod),BIC(lm.mod.intercept),BIC(lm.mod.interceptSlope))\n\n[1] 408.7963 356.1764 353.7488\n\n\nThere is more support for the mixed model that considers variation in intercepts and slopes. One can also estimate the p-value that one model fits better than the other:\n\nanova(lm.mod.intercept,lm.mod.interceptSlope)\n\nrefitting model(s) with ML (instead of REML)\n\n\nData: data.Simpson\nModels:\nlm.mod.intercept: abundance ~ temperature + (1 | species)\nlm.mod.interceptSlope: abundance ~ temperature + (1 + temperature | species)\n npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)\nlm.mod.intercept 4 346.41 356.83 -169.21 338.41 \nlm.mod.interceptSlope 6 340.30 355.93 -164.15 328.30 10.114 2 0.006365\n \nlm.mod.intercept \nlm.mod.interceptSlope **\n---\nSignif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n\n\nFinally, we can plot the intercept and slope variation. The common fixed effect slope has been now estimated by pooling the variation among species, hence it become negative in contrast to the original fixed effect slope.\n\nintercepts <- coefficients(lm.mod.interceptSlope)$species[,\"(Intercept)\"]\nslopes <- coefficients(lm.mod.interceptSlope)$species[,\"temperature\"]\nlines <- data.frame(intercepts,slopes)\nlines[\"species\"] <- unique(data.Simpson[,\"species\"])\ndata.Simpson$pred <- predict(lm.mod.intercept)\nggplot() +\ngeom_point(data=data.Simpson,aes(x=temperature,y=abundance,color=species),size=2) + \ngeom_abline(aes(intercept = `(Intercept)`, slope = temperature),size = 2,as.data.frame(t(fixef(lm.mod.interceptSlope)))) +\ngeom_abline(data = lines, aes(intercept=intercepts, slope=slopes, color=species),size = 2) +\ntheme_classic() + \nxlab(\"Temperature\") + ylab(\"log(Abundance)\")\n\n\n\n\nAn extreme example pf the Simpson’s paradox\nLet’s consider (just visually) an even more extreme case. The fixed effect is very strong but the within species effect is almost zero. Hopefully the “Simpson’s” examples here provide a good intuition on the importance of mixed models.\n\n\n\n\n\n\n\n\n\nOur first GLMM applied to the fourth corner problem treating species as a random effect - the MLML1 model\n\nThere are different ways that we can account for the potential random effects in community ecology data. Here we will review a few of the latest developments.\nMLM stands for multilevel (i.e., hierarchical) models (MLM). The simplest of these models is the one introduced by Pollock et al. (2012) and is often referred in the ecological literature as MLM1 (see Miller et al. 2018). The model has the following form (following the notation of Gelman and Hill 2007; as in Miller et al. 2018). This is a model that considers species as a random effect while estimating variation in both intercepts and slopes as the last model in the previous session (Simpson’s paradox)\n\\[{ln(Y_{i}) = \\alpha\\ +a_{spp[i]}\\ +\\beta_{12}env_{site[i]}\\times trait_{spp[i]} + (\\beta_1+c_{spp[i]})env_{site[i]}+e_i}\\] \\(a,c \\sim Gaussian(0,\\sigma_a^2,\\sigma_c^2,\\rho_{ac})\\) \\(e \\sim Gaussian(0,\\sigma_e^2)\\)\nNote that we changed the notation of Brown et al. \\(ij\\) that served as an index for the \\(i^{th}\\) site and \\(j^{th}\\) species to simply one index \\(i\\) since we are using a stacked model anyway, i.e., only rows for \\(Y_{i}\\) and one column (i.e., stacked species distributions). As such, the functions \\(spp[i]\\) and \\(site[i]\\) map row i onto the corresponding species and sites. \\(\\beta_{12}\\) contains the slopes for the interactions between environment and trait. The fixed effect \\(\\alpha\\) gives the overall average abundance of species among sites (one overall intercept), and the fixed effect \\(\\beta_{1}\\) gives the mean response of species to the different environmental variables. Random effect \\(a_{spp[i]}\\) allows different species to have different overall abundance (i.e., sum of abundances across species; random intercept model across species), and random effect \\(c_{spp[i]}\\) allows different species to have different responses to the environmental variables (i.e., random slope model across species). \\(a_{spp[i]}\\) and \\(c_{spp[i]}\\) have means zero and variances \\(\\sigma_a^2\\) and \\(\\sigma_c^2\\) (referred as to hyperparameters in mixed model lingo), with \\(\\rho_{ac}\\) denoting the correlation between \\(a_{spp[i]}\\) and \\(c_{spp[i]}\\) (i.e., species intercepts and species slopes for the environment can correlate). Finally,random effect \\(e_i\\) gives observation-level variance; this is necessary here to allow for overdispersion (Harisson, 2014). We can also use the negative binomial as we saw earlier. Note that we are assuming hierarchical variation in variance and not covariance (e.g., phylogenetic and spatial autocorrelation). One step at the time.\nLet’s start by setting an appropriate data structure to run the mixed model. To make the coding more manageable we will consider here only one trait and one environment. The code can be easily generalized for multiple traits and environments. We found early a strong interaction between seed mass and snow in which species with greater seed mass tended to be found in sites with small levels of snow (i.e., a negative correlation between snow and seed mass).\nFor simplicity, let’s load the aravo data again:\n\nlibrary(ade4)\ndata(aravo)\nE <- aravo$env[,c(\"Aspect\",\"Slope\",\"Snow\")]\nE <- as.matrix(E)\nT <- as.matrix(aravo$trait)\nDist.stacked <- as.vector(as.matrix(aravo$spe))\nn.species <- ncol(aravo$spe)\nn.communities <- nrow(aravo$spe)\nn.env.variables <- ncol(E)\n\n\n# to code for observation-level variance:\nobs <- 1:(n.species*n.communities)\n# to code for species (as we saw earlier to plot residuals):\nspecies <- rep(row.names(aravo$traits),each=nrow(aravo$spe))\nsites <- rep(row.names(aravo$spe),each=ncol(aravo$spe))\n# standardizing the data:\nseed.mass <- scale(T[rep(1:n.species,each=n.communities),\"Seed\"])\nsnow.melt.days <- scale(matrix(rep(t(E[,\"Snow\"]),n.species),ncol=1,byrow=TRUE))\ndata.df <- data.frame(abundance=Dist.stacked,snow.melt.days,seed.mass,species,sites,obs)\n\nLet’s see the data frame:\nView(data.df)\nLet’s start by fitting a glm:\n\nglm.mod <- glm(abundance ~ snow.melt.days + snow.melt.days:seed.mass,data=data.df, family = \"poisson\")\nsumm(glm.mod,scale = TRUE)\n\n\n\n\n \n Observations \n 6150 \n \n \n Dependent variable \n abundance \n \n \n Type \n Generalized linear model \n \n \n Family \n poisson \n \n \n Link \n log \n \n\n \n\n \n 𝛘²(2) \n 56.18 \n \n \n Pseudo-R² (Cragg-Uhler) \n 0.01 \n \n \n Pseudo-R² (McFadden) \n 0.01 \n \n \n AIC \n 9421.91 \n \n \n BIC \n 9442.08 \n \n\n \n \n \n \n Est. \n S.E. \n z val. \n p \n \n \n\n \n (Intercept) \n -1.17 \n 0.02 \n -50.74 \n 0.00 \n \n \n snow.melt.days \n -0.10 \n 0.02 \n -4.20 \n 0.00 \n \n \n snow.melt.days:seed.mass \n -0.14 \n 0.02 \n -6.39 \n 0.00 \n \n\n\n Standard errors: MLE; Continuous predictors are mean-centered and scaled by 1 s.d.\n\n\n\nDespite the very low \\(R^2=0.01\\), the coefficiences are all significant and negative.\nLet’s run the model. Below, both intercepts (coded as 1) and slopes for snow.melt.days (coded as env) are allowed to vary among species (i.e., (1 + env|species)) and we also allow\n\nMLM1.mod <- glmer(abundance ~ snow.melt.days + snow.melt.days:seed.mass + (1 + snow.melt.days|species) + (1 | obs), family = \"poisson\", control=glmerControl(calc.derivs=F), nAGQ = 0, data=data.df)\nsumm(MLM1.mod,scale = TRUE)\n\n\n\n\n \n Observations \n 6150 \n \n \n Dependent variable \n abundance \n \n \n Type \n Mixed effects generalized linear model \n \n \n Family \n poisson \n \n \n Link \n log \n \n\n \n\n \n AIC \n 7335.48 \n \n \n BIC \n 7382.55 \n \n \n Pseudo-R² (fixed effects) \n 0.09 \n \n \n Pseudo-R² (total) \n 0.65 \n \n\n \n \nFixed Effects\n \n \n Est. \n S.E. \n z val. \n p \n \n \n\n \n (Intercept) \n -2.12 \n 0.17 \n -12.37 \n 0.00 \n \n \n snow.melt.days \n -0.72 \n 0.13 \n -5.51 \n 0.00 \n \n \n snow.melt.days:seed.mass \n -0.08 \n 0.09 \n -0.84 \n 0.40 \n \n\n\n ; Continuous predictors are mean-centered and scaled by 1 s.d.\n \n \nRandom Effects\n \n Group \n Parameter \n Std. Dev. \n \n \n\n \n obs \n (Intercept) \n 0.47 \n \n \n species \n (Intercept) \n 1.46 \n \n \n species \n snow.melt.days \n 1.08 \n \n\n \n \nGrouping Variables\n \n Group \n # groups \n ICC \n \n \n\n \n obs \n 6150 \n 0.07 \n \n \n species \n 82 \n 0.63 \n \n\n\n\n\nThe variation among observations (residuals) is not relevant here; we used it to allow for potential overdispersion in abundance (i.e., variance of abundance much greater than the mean). Note that both the intercept and slopes contribute more or less to the same amount of variation (intercept sd=1.46 and slopes = 1.08), indicating that an intercept and slope mixed model is the most appropriate model. We could have fit the two models and tested as before we saw early in the Simpson’s paradox section. Note the huge increase in \\(R^2=0.65\\), demonstrating that considering a random structure is much better. The coefficient of snow.melt.days remains negative indicating that most species and their variation are negative despite the potential for some species to increase their abundances for large values of snow.melt.days. We will see this below.\nThe residual against the predicted values provide a good indication that the model is appropriate:\n\nlibrary(DHARMa)\nDunnSmyth.res <- simulateResiduals(fittedModel = MLM1.mod, plot = F)\nplot(DunnSmyth.res$scaledResiduals~log(fitted(MLM1.mod)),col=as.numeric(factor(species)),xlab=\"Fitted values [log scale]\",ylab=\"residuals\")\n\n\n\n\nAnd now the Q-Q plot to assess residual normality:\n\nplotQQunif(DunnSmyth.res)\n\nDHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details\n\n\n\n\n\nNote that the Kolmogorov-Smirnov (KS) provides indication that the residuals cannot be assumed to be normal. That said, the distribution of residuals looks somewhat on the expected. The KS becomes quite significant because of the large number of data points. Finally, GLMs and GLMMs tend to be quite robust even when residuals are not normal.\nIntercepts in a poisson model are log of species abundances not explained by the predictors model, i.e., when we set them “manually” to take values of zero. Perhaps some sites are more productive than others and we did not measure trait or environmental variables that could account for the slope and intercept variation variation; but the random effects is telling us that there is something we are potentially missing to explain their variation.\nMoreover, the random effect indicates that species slopes for the environment are strongly and positively correlated with the species intercepts (\\(\\rho_{ac}=0.73\\)). We can plot the intercepts against slopes:\n\nplot(coefficients(MLM1.mod)$species[,\"(Intercept)\"],coefficients(MLM1.mod)$species[,\"snow.melt.days\"],xlab=\"species intercepts\", ylab=\"species environmental slopes\")\n\n\n\n\n\\(\\rho_{ac}\\) does not appear in summ(MLM1.mod) but can be found in summary(MLM1.mod) intead or calculated directly:\n\nsummary(MLM1.mod)\n\nGeneralized linear mixed model fit by maximum likelihood (Adaptive\n Gauss-Hermite Quadrature, nAGQ = 0) [glmerMod]\n Family: poisson ( log )\nFormula: abundance ~ snow.melt.days + snow.melt.days:seed.mass + (1 + \n snow.melt.days | species) + (1 | obs)\n Data: data.df\nControl: glmerControl(calc.derivs = F)\n\n AIC BIC logLik deviance df.resid \n 7335.5 7382.6 -3660.7 7321.5 6143 \n\nScaled residuals: \n Min 1Q Median 3Q Max \n-1.6289 -0.4400 -0.2650 -0.0639 7.6016 \n\nRandom effects:\n Groups Name Variance Std.Dev. Corr\n obs (Intercept) 0.2221 0.4712 \n species (Intercept) 2.1201 1.4560 \n snow.melt.days 1.1671 1.0803 0.73\nNumber of obs: 6150, groups: obs, 6150; species, 82\n\nFixed effects:\n Estimate Std. Error z value Pr(>|z|) \n(Intercept) -2.11504 0.17095 -12.372 < 2e-16 ***\nsnow.melt.days -0.71798 0.13037 -5.507 3.64e-08 ***\nsnow.melt.days:seed.mass -0.07552 0.09024 -0.837 0.403 \n---\nSignif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n\nCorrelation of Fixed Effects:\n (Intr) snw.m.\nsnw.mlt.dys 0.730 \nsnw.mlt.d:. 0.010 0.015 \n\ncor(coefficients(MLM1.mod)$species[,\"(Intercept)\"],coefficients(MLM1.mod)$species[,\"snow.melt.days\"])\n\n[1] 0.7163168\n\n\nAlthough the fixed-only effect model run earlier (glm.mod) indicated a significant correlation between snowmelt date and seed mass in driving species distributions, this effect is no longer relevant once the random effects are considered:\n\nsummary(glm.mod)\n\n\nCall:\nglm(formula = abundance ~ snow.melt.days + snow.melt.days:seed.mass, \n family = \"poisson\", data = data.df)\n\nDeviance Residuals: \n Min 1Q Median 3Q Max \n-1.2804 -0.7946 -0.7868 -0.6822 4.3659 \n\nCoefficients:\n Estimate Std. Error z value Pr(>|z|) \n(Intercept) -1.16767 0.02301 -50.744 < 2e-16 ***\nsnow.melt.days -0.09714 0.02313 -4.199 2.68e-05 ***\nsnow.melt.days:seed.mass -0.14286 0.02237 -6.387 1.70e-10 ***\n---\nSignif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n\n(Dispersion parameter for poisson family taken to be 1)\n\n Null deviance: 6552.0 on 6149 degrees of freedom\nResidual deviance: 6495.8 on 6147 degrees of freedom\nAIC: 9421.9\n\nNumber of Fisher Scoring iterations: 6\n\n\nThis indicates that the random variation across species can account for the initial relationship between snow.melt.days and seed mass. Note that the importance of snow.melt.days remains relevant in driving species abundances across sites, but (again) not its interaction with seed mass.\nLet’s plot regression models per species:\n\nintercepts <- coefficients(MLM1.mod)$species[,\"(Intercept)\"]\nslopes <- coefficients(MLM1.mod)$species[,\"snow.melt.days\"]\nlines <- data.frame(intercepts,slopes)\nlines[\"species\"] <- unique(data.df[,\"species\"])\ndata.df$pred <- predict(MLM1.mod)\nggplot(data=data.df) +\ngeom_point(data=data.df,aes(x=snow.melt.days,y=pred,color=species),size=1) + \ngeom_abline(data = lines, aes(intercept=intercepts, slope=slopes, color=species),size = 2) +\ngeom_abline(aes(intercept = `(Intercept)`, slope = snow.melt.days),size = 2,as.data.frame(t(fixef(MLM1.mod)))) +\ntheme_classic() + \nxlab(\"snow.melt.days\") + ylab(\"log(Abundance)\")\n\n\n\n\nFinally, the GLMM has good predictive power (relative smaller confidence intervals and large \\(R^2=0.51\\):\n\n# install.packages(\"ggeffects\")\nlibrary(ggeffects)\nplot(ggpredict(MLM1.mod, \"snow.melt.days\"))\n\n\n\n\nFinally, as we discussed during the workshop, one needs to be careful while interpreting the significance of interactions between trait and environment. There are bootstrap-based developments to do that for the MLML1 model but they have been show to have inflated type I errors (Miller et al. 2019).\nFunction glmer.nb could have been used to fit the model using the negative binomial family instead.\nHere is a good and simple introduction to mixed models for poisson regression:\nhttps://stats.idre.ucla.edu/r/faq/random-coefficient-poisson-models/\n\nOur second GLMM applied to the fourth corner problem treating species and sites as random effects - the MLML2 model\n\nJamil et al. (2013) implemented a mixed model version in which in contrast to MLM1, it adds a fixed effect term for traits is included in the model (as in Brown et al. 2014) and also an additional random effect (intercepts) for site:\n\nMLM2.mod <- glmer(abundance ~ snow.melt.days * seed.mass + (1 + snow.melt.days|species) + (1 | sites) + (1 | obs), family = \"poisson\", control=glmerControl(calc.derivs=F), nAGQ = 0, data=data.df)\nsummary(MLM2.mod,scale = TRUE)\n\nWarning in summary.merMod(MLM2.mod, scale = TRUE): additional arguments ignored\n\n\nGeneralized linear mixed model fit by maximum likelihood (Adaptive\n Gauss-Hermite Quadrature, nAGQ = 0) [glmerMod]\n Family: poisson ( log )\nFormula: abundance ~ snow.melt.days * seed.mass + (1 + snow.melt.days | \n species) + (1 | sites) + (1 | obs)\n Data: data.df\nControl: glmerControl(calc.derivs = F)\n\n AIC BIC logLik deviance df.resid \n 7264.1 7324.6 -3623.0 7246.1 6141 \n\nScaled residuals: \n Min 1Q Median 3Q Max \n-1.5851 -0.4284 -0.2557 -0.0732 8.9436 \n\nRandom effects:\n Groups Name Variance Std.Dev. Corr\n obs (Intercept) 0.1472 0.3837 \n species (Intercept) 1.6523 1.2854 \n snow.melt.days 1.0169 1.0084 0.71\n sites (Intercept) 0.4344 0.6591 \nNumber of obs: 6150, groups: obs, 6150; species, 82; sites, 75\n\nFixed effects:\n Estimate Std. Error z value Pr(>|z|) \n(Intercept) -2.1239 0.1708 -12.436 < 2e-16 ***\nsnow.melt.days -0.6805 0.1228 -5.543 2.97e-08 ***\nseed.mass -0.2050 0.1634 -1.255 0.210 \nsnow.melt.days:seed.mass -0.1134 0.1281 -0.885 0.376 \n---\nSignif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n\nCorrelation of Fixed Effects:\n (Intr) snw.m. sd.mss\nsnw.mlt.dys 0.630 \nseed.mass 0.022 0.029 \nsnw.mlt.d:. 0.023 0.031 0.680 \n\n\nLet’s test the fit difference between MLM1 and MLM2:\n\nanova(MLM1.mod,MLM2.mod)\n\nData: data.df\nModels:\nMLM1.mod: abundance ~ snow.melt.days + snow.melt.days:seed.mass + (1 + snow.melt.days | species) + (1 | obs)\nMLM2.mod: abundance ~ snow.melt.days * seed.mass + (1 + snow.melt.days | species) + (1 | sites) + (1 | obs)\n npar AIC BIC logLik deviance Chisq Df Pr(>Chisq) \nMLM1.mod 7 7335.5 7382.6 -3660.7 7321.5 \nMLM2.mod 9 7264.1 7324.6 -3623.0 7246.1 75.406 2 < 2.2e-16 ***\n---\nSignif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n\nc(BIC(MLM1.mod),BIC(MLM2.mod))\n\n[1] 7382.551 7324.594\n\n\nWe won’t diagnostics here for brevity and the code for the MLM1 can be easily adapted here.\nAlthough the fixed effects for the trait (seed mass) and interaction (seed mass and snow.melt.day) were not significant, the random effect standard deviation for site is relative large (0.66) and improved the predictive power for abundances across species.\n\nOur last GLMM applied to the fourth corner problem treating species and sites as random effects - the MLML3 model\n\nter Braak (2019) proposed yet another version that seems to work better than the previous ones.\n\nMLM3.mod <- glmer(abundance ~ snow.melt.days * seed.mass + (1 + snow.melt.days|species) + (1 + seed.mass|sites) + (1 | obs), family = \"poisson\", control=glmerControl(calc.derivs=F), nAGQ = 0, data=data.df)\n\nLet’s test the fit difference between MLM2 and MLM3:\n\nanova(MLM2.mod,MLM3.mod)\n\nData: data.df\nModels:\nMLM2.mod: abundance ~ snow.melt.days * seed.mass + (1 + snow.melt.days | species) + (1 | sites) + (1 | obs)\nMLM3.mod: abundance ~ snow.melt.days * seed.mass + (1 + snow.melt.days | species) + (1 + seed.mass | sites) + (1 | obs)\n npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)\nMLM2.mod 9 7264.1 7324.6 -3623.0 7246.1 \nMLM3.mod 11 7267.0 7341.0 -3622.5 7245.0 1.0759 2 0.5839\n\nc(BIC(MLM2.mod),BIC(MLM3.mod))\n\n[1] 7324.594 7340.967\n\n\nFor these data, the MLM3 does not improve the MLM2.\nThis is not the end - we will keep updating this page after the workshop\nReferences (still being filled):\nAM Brown, DI Warton, NR Andrew, M Binns, G Cassis, H Gibb Methods in Ecology and Evolution 5 (4), 344-352\nCholer, P. (2005) Consistent shifts in Alpine plant traits along a mesotopographical gradient. Arctic, Antarctic, and Alpine Research, 37,444–453.\nDray, S., & Legendre, P. (2008) Testing the species traits-environment relationships : The fourth-corner problem revisited. Ecology, 89, 3400–3412.\nDunn, KP & Smyth GK (1996) Randomized quantile residuals. Journal of Computational and Graphical Statistics, 5, 1-10.\nGabriel, KR. (1998) Generalised bilinear regression. Biometrika, 85, 689-700.\nGelman, A & Hill, J (2007). Data analysis using regression and multi-level/hierarchical models. New York, NY: Cambridge University Press.\nHarrison, XA (2014). Using observation-level random effects to model overdispersion in count data in ecology and evolution. PeerJ, 2, e616.\nJamil, T., Ozinga, W. A., Kleyer, M., & ter Braak, C. J. F. (2013). Selecting traits that explain species-environment relationships: A generalized linear mixed model approach. Journal of Vegetation Science, 24, 988–1000.\nPeres-Neto, P. R., Dray, S., & ter Braak, C. J. F. (2017). Linking trait variation to the environment: Critical issues with community-weighted mean correlation resolved by the fourth-corner approach. Ecography, 40, 806–816.\nPollock, L. J., Morris, W. K., & Vesk, P. A. (2012). The role of functional traits in species distributions revealed through a hierarchical model. Ecography, 35, 716–725.\nSimpson, EH (1951). The Interpretation of Interaction in Contingency Tables. Journal of the Royal Statistical Society, Series B., 13, 238–241.\nter Braak, CJF, Cormont, A. & Dray, S. (2012). Improved testing of species traits–environment relationships in the fourth‐corner problem. Ecology, 93, 1525-1526.\nter Braak, CJF & Looman, CWN. (1986). Weighted averaging, logistic regression and the Gaussian response model. Plant Ecology, 65, 3-11.\nuseful sites for GLMs (will also expand on this later on):\n\nBeyond Multiple Linear Regression: https://bookdown.org/roback/bookdown-BeyondMLR/" + }, + { + "objectID": "summer-schools/BiodiversityModelling2022.html", + "href": "summer-schools/BiodiversityModelling2022.html", + "title": "Biodiversity Modelling 2022", + "section": "", + "text": "Diapositives des présentations données lors de la modélisation de la biodiversité en 2022\nSlides from presentations given in Biodiversity modelling in 2022." + }, + { + "objectID": "summer-schools/BiodiversityModelling2022.html#day-1", + "href": "summer-schools/BiodiversityModelling2022.html#day-1", + "title": "Biodiversity Modelling 2022", + "section": "Day 1", + "text": "Day 1" + }, + { + "objectID": "summer-schools/BiodiversityModelling2022.html#day-3", + "href": "summer-schools/BiodiversityModelling2022.html#day-3", + "title": "Biodiversity Modelling 2022", + "section": "Day 3", + "text": "Day 3" + }, + { + "objectID": "summer-schools/BiodiversityModelling2022.html#day-4", + "href": "summer-schools/BiodiversityModelling2022.html#day-4", + "title": "Biodiversity Modelling 2022", + "section": "Day 4", + "text": "Day 4\nhttps://bit.ly/dataviz_uds" + }, + { + "objectID": "index.html", + "href": "index.html", + "title": "BIOS2 Education resources", + "section": "", + "text": "Introduction to Shiny Apps\n\n\n\n\n\n\n\nTechnical\n\n\nFellow contributed\n\n\nEN\n\n\n\n\nIntroduction to interactive app development with R Shiny.\n\n\n\n\n\n\nJun 22, 2021\n\n\nKatherine Hébert, Andrew MacDonald, Jake Lawlor, Vincent Bellevance\n\n\n\n\n\n\n \n\n\n\n\nGeneralized Linear Models for Community Ecology\n\n\n\n\n\n\n\nTechnical\n\n\nEN\n\n\n\n\nIn this workshop we will explore, discuss, and apply generalized linear models to combine information on species distributions, traits, phylogenies, environmental and landscape variation. We will also discuss inference under spatial and phylogenetic autocorrelation under fixed and random effects implementations. We will discuss technical elements and cover implementations using R.\n\n\n\n\n\n\nMay 17, 2021\n\n\nPedro Peres-Neto\n\n\n\n\n\n\n \n\n\n\n\nBuilding R packages\n\n\n\n\n\n\n\nTechnical\n\n\nEN\n\n\n\n\nThis practical training will cover the basics of modern package development in R with a focus on the following three aspects: (1) how to turn your code into functions, (2) how to write tests and documentation, and (3) how to share your R package on GitHub..\n\n\n\n\n\n\nMay 4, 2021\n\n\nAndrew MacDonald\n\n\n\n\n\n\n \n\n\n\n\nPoint-count Data Analysis\n\n\n\n\n\n\n\nTechnical\n\n\nEN\n\n\n\n\nAnalysis of point-count data in the presence of variable survey methodologies and detection error offered by Peter Solymos to BIOS2 Fellows in March 2021.\n\n\n\n\n\n\nMar 25, 2021\n\n\nPeter Solymos\n\n\n\n\n\n\n \n\n\n\n\nIntroduction to EDI concepts in a scientific context\n\n\n\n\n\n\n\nTransversal competencies\n\n\nFR\n\n\nEN\n\n\n\n\nA short introduction to EDI concepts in a scientific context.\n\n\n\n\n\n\nJan 22, 2021\n\n\nAgathe Riallan, Marie-José Naud\n\n\n\n\n\n\n \n\n\n\n\n4-Day Training in Spatial Statistics with Philippe Marchand\n\n\n\n\n\n\n\nFR\n\n\nEN\n\n\nTechnical\n\n\n\n\nTraining session about statistical analysis of spatial data in ecology, hosted by Philippe Marchand (UQAT). | Session de formation sur l’analyse statistique des données spatiales en écologie, animée par Pr. Philippe Marchand (UQAT).\n\n\n\n\n\n\nJan 12, 2021\n\n\nPhilippe Marchand\n\n\n\n\n\n\n \n\n\n\n\nMaking websites with HUGO\n\n\n\n\n\n\n\nTechnical\n\n\nTransversal competencies\n\n\nEN\n\n\n\n\nThis workshop provides a general introduction to HUGO, a popular open source framework for building websites without requiring a knowledge of HTML/CSS or web programming.\n\n\n\n\n\n\nDec 7, 2020\n\n\n\n\n\n\n \n\n\n\n\nData Visualization\n\n\n\n\n\n\n\nTechnical\n\n\nFellow contributed\n\n\nEN\n\n\n\n\nGeneral principles of visualization and graphic design, and techniques of tailored visualization. This training was developed and delivered by Alex Arkilanian and Katherine Hébert on September 21st and 22nd, 2020.\n\n\n\n\n\n\nSep 21, 2020\n\n\nAlex Arkilanian, Katherine Hébert\n\n\n\n\n\n\n \n\n\n\n\nScience Communication\n\n\n\n\n\n\n\nCareer\n\n\nFellow contributed\n\n\nEN\n\n\n\n\nRecordings, content and handouts from a 6-hour Science Communication workshop held over two days on 15 and 16 June 2020.\n\n\n\n\n\n\nJun 15, 2020\n\n\nGracielle Higino, Katherine Hébert\n\n\n\n\n\n\n \n\n\n\n\nSensibilisation aux réalités autochtones et recherche collaborative\n\n\n\n\n\n\n\nTransversal competencies\n\n\nFR\n\n\n\n\nSérie de deux webinaires sur la sensibilisation aux réalités autochtones et la recherche en collaboration avec les Autochtones, offert du 28 au 30 avril 2020 par Catherine-Alexandra Gagnon, PhD.\n\n\n\n\n\n\nApr 28, 2020\n\n\nDr Catherine-Alexandra Gagnon\n\n\n\n\n\n\n \n\n\n\n\nMathematical Modeling in Ecology and Evolution\n\n\n\n\n\n\n\nTechnical\n\n\nEN\n\n\n\n\nThis workshop will introduce participants to the logic behind modeling in biology, focusing on developing equations, finding equilibria, analyzing stability, and running simulations.Techniques will be illustrated with the software tools, Mathematica and Maxima. This workshop was held in two parts: January 14 and January 16, 2020.\n\n\n\n\n\n\nJan 14, 2020\n\n\nDr Sarah P. Otto\n\n\n\n\n\n\nNo matching items" + }, + { + "objectID": "about.html", + "href": "about.html", + "title": "About", + "section": "", + "text": "About this blog" + } +] \ No newline at end of file diff --git a/docs/site_libs/bootstrap/bootstrap-icons.css b/docs/site_libs/bootstrap/bootstrap-icons.css new file mode 100644 index 0000000..f51d04b --- /dev/null +++ b/docs/site_libs/bootstrap/bootstrap-icons.css @@ -0,0 +1,1704 @@ +@font-face { + font-family: "bootstrap-icons"; + src: +url("./bootstrap-icons.woff?524846017b983fc8ded9325d94ed40f3") format("woff"); +} + +.bi::before, +[class^="bi-"]::before, +[class*=" bi-"]::before { + display: inline-block; + font-family: bootstrap-icons !important; + font-style: normal; + font-weight: normal !important; + font-variant: normal; + text-transform: none; + line-height: 1; + vertical-align: -.125em; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.bi-123::before { content: "\f67f"; } +.bi-alarm-fill::before { content: "\f101"; } +.bi-alarm::before { content: "\f102"; } +.bi-align-bottom::before { content: "\f103"; } +.bi-align-center::before { content: "\f104"; } +.bi-align-end::before { content: "\f105"; } +.bi-align-middle::before { content: "\f106"; } +.bi-align-start::before { content: "\f107"; } +.bi-align-top::before { content: "\f108"; } +.bi-alt::before { content: "\f109"; } +.bi-app-indicator::before { content: "\f10a"; } +.bi-app::before { content: "\f10b"; } +.bi-archive-fill::before { content: "\f10c"; } +.bi-archive::before { content: "\f10d"; } +.bi-arrow-90deg-down::before { content: "\f10e"; } +.bi-arrow-90deg-left::before { content: "\f10f"; } +.bi-arrow-90deg-right::before { content: "\f110"; } +.bi-arrow-90deg-up::before { content: "\f111"; } +.bi-arrow-bar-down::before { content: "\f112"; } +.bi-arrow-bar-left::before { content: "\f113"; } +.bi-arrow-bar-right::before { content: "\f114"; } +.bi-arrow-bar-up::before { content: "\f115"; } +.bi-arrow-clockwise::before { content: "\f116"; } +.bi-arrow-counterclockwise::before { content: "\f117"; } +.bi-arrow-down-circle-fill::before { content: "\f118"; } +.bi-arrow-down-circle::before { content: "\f119"; } +.bi-arrow-down-left-circle-fill::before { content: "\f11a"; } +.bi-arrow-down-left-circle::before { content: "\f11b"; } +.bi-arrow-down-left-square-fill::before { content: "\f11c"; } +.bi-arrow-down-left-square::before { content: "\f11d"; } +.bi-arrow-down-left::before { content: "\f11e"; } +.bi-arrow-down-right-circle-fill::before { content: "\f11f"; } +.bi-arrow-down-right-circle::before { content: "\f120"; } +.bi-arrow-down-right-square-fill::before { content: "\f121"; } +.bi-arrow-down-right-square::before { content: "\f122"; } +.bi-arrow-down-right::before { content: "\f123"; } +.bi-arrow-down-short::before { content: "\f124"; } +.bi-arrow-down-square-fill::before { content: "\f125"; } +.bi-arrow-down-square::before { content: "\f126"; } +.bi-arrow-down-up::before { content: "\f127"; } +.bi-arrow-down::before { content: "\f128"; } +.bi-arrow-left-circle-fill::before { content: "\f129"; } +.bi-arrow-left-circle::before { content: "\f12a"; } +.bi-arrow-left-right::before { content: "\f12b"; } +.bi-arrow-left-short::before { content: "\f12c"; } +.bi-arrow-left-square-fill::before { content: "\f12d"; } +.bi-arrow-left-square::before { content: "\f12e"; } +.bi-arrow-left::before { content: "\f12f"; } +.bi-arrow-repeat::before { content: "\f130"; } +.bi-arrow-return-left::before { content: "\f131"; } +.bi-arrow-return-right::before { content: "\f132"; } +.bi-arrow-right-circle-fill::before { content: "\f133"; } +.bi-arrow-right-circle::before { content: "\f134"; } +.bi-arrow-right-short::before { content: "\f135"; } +.bi-arrow-right-square-fill::before { content: "\f136"; } +.bi-arrow-right-square::before { content: "\f137"; } +.bi-arrow-right::before { content: "\f138"; } +.bi-arrow-up-circle-fill::before { content: "\f139"; } +.bi-arrow-up-circle::before { content: "\f13a"; } +.bi-arrow-up-left-circle-fill::before { content: "\f13b"; } +.bi-arrow-up-left-circle::before { content: "\f13c"; } +.bi-arrow-up-left-square-fill::before { content: "\f13d"; } +.bi-arrow-up-left-square::before { content: "\f13e"; } +.bi-arrow-up-left::before { content: "\f13f"; } +.bi-arrow-up-right-circle-fill::before { content: "\f140"; } +.bi-arrow-up-right-circle::before { content: "\f141"; } +.bi-arrow-up-right-square-fill::before { content: "\f142"; } +.bi-arrow-up-right-square::before { content: "\f143"; } +.bi-arrow-up-right::before { content: "\f144"; } +.bi-arrow-up-short::before { content: "\f145"; } +.bi-arrow-up-square-fill::before { content: "\f146"; } +.bi-arrow-up-square::before { content: "\f147"; } +.bi-arrow-up::before { content: "\f148"; } +.bi-arrows-angle-contract::before { content: "\f149"; } +.bi-arrows-angle-expand::before { content: "\f14a"; } +.bi-arrows-collapse::before { content: "\f14b"; } +.bi-arrows-expand::before { content: "\f14c"; } +.bi-arrows-fullscreen::before { content: "\f14d"; } +.bi-arrows-move::before { content: "\f14e"; } +.bi-aspect-ratio-fill::before { content: "\f14f"; } +.bi-aspect-ratio::before { content: "\f150"; } +.bi-asterisk::before { content: "\f151"; } +.bi-at::before { content: "\f152"; } +.bi-award-fill::before { content: "\f153"; } +.bi-award::before { content: "\f154"; } +.bi-back::before { content: "\f155"; } +.bi-backspace-fill::before { content: "\f156"; } +.bi-backspace-reverse-fill::before { content: "\f157"; } +.bi-backspace-reverse::before { content: "\f158"; } +.bi-backspace::before { content: "\f159"; } +.bi-badge-3d-fill::before { content: "\f15a"; } +.bi-badge-3d::before { content: "\f15b"; } +.bi-badge-4k-fill::before { content: "\f15c"; } +.bi-badge-4k::before { content: "\f15d"; } +.bi-badge-8k-fill::before { content: "\f15e"; } +.bi-badge-8k::before { content: "\f15f"; } +.bi-badge-ad-fill::before { content: "\f160"; } +.bi-badge-ad::before { content: "\f161"; } +.bi-badge-ar-fill::before { content: "\f162"; } +.bi-badge-ar::before { content: "\f163"; } +.bi-badge-cc-fill::before { content: "\f164"; } +.bi-badge-cc::before { content: "\f165"; } +.bi-badge-hd-fill::before { content: "\f166"; } +.bi-badge-hd::before { content: "\f167"; } +.bi-badge-tm-fill::before { content: "\f168"; } +.bi-badge-tm::before { content: "\f169"; } +.bi-badge-vo-fill::before { content: "\f16a"; } +.bi-badge-vo::before { content: "\f16b"; } +.bi-badge-vr-fill::before { content: "\f16c"; } +.bi-badge-vr::before { content: "\f16d"; } +.bi-badge-wc-fill::before { content: "\f16e"; } +.bi-badge-wc::before { content: "\f16f"; } +.bi-bag-check-fill::before { content: "\f170"; } +.bi-bag-check::before { content: "\f171"; } +.bi-bag-dash-fill::before { content: "\f172"; } +.bi-bag-dash::before { content: "\f173"; } +.bi-bag-fill::before { content: "\f174"; } +.bi-bag-plus-fill::before { content: "\f175"; } +.bi-bag-plus::before { content: "\f176"; } +.bi-bag-x-fill::before { content: "\f177"; } +.bi-bag-x::before { content: "\f178"; } +.bi-bag::before { content: "\f179"; } +.bi-bar-chart-fill::before { content: "\f17a"; } +.bi-bar-chart-line-fill::before { content: "\f17b"; } +.bi-bar-chart-line::before { content: "\f17c"; } +.bi-bar-chart-steps::before { content: "\f17d"; } +.bi-bar-chart::before { content: "\f17e"; } +.bi-basket-fill::before { content: "\f17f"; } +.bi-basket::before { content: "\f180"; } +.bi-basket2-fill::before { content: "\f181"; } +.bi-basket2::before { content: "\f182"; } +.bi-basket3-fill::before { content: "\f183"; } +.bi-basket3::before { content: "\f184"; } +.bi-battery-charging::before { content: "\f185"; } +.bi-battery-full::before { content: "\f186"; } +.bi-battery-half::before { content: "\f187"; } +.bi-battery::before { content: "\f188"; } +.bi-bell-fill::before { content: "\f189"; } +.bi-bell::before { content: "\f18a"; } +.bi-bezier::before { content: "\f18b"; } +.bi-bezier2::before { content: "\f18c"; } +.bi-bicycle::before { content: "\f18d"; } +.bi-binoculars-fill::before { content: "\f18e"; } +.bi-binoculars::before { content: "\f18f"; } +.bi-blockquote-left::before { content: "\f190"; } +.bi-blockquote-right::before { content: "\f191"; } +.bi-book-fill::before { content: "\f192"; } +.bi-book-half::before { content: "\f193"; } +.bi-book::before { content: "\f194"; } +.bi-bookmark-check-fill::before { content: "\f195"; } +.bi-bookmark-check::before { content: "\f196"; } +.bi-bookmark-dash-fill::before { content: "\f197"; } +.bi-bookmark-dash::before { content: "\f198"; } +.bi-bookmark-fill::before { content: "\f199"; } +.bi-bookmark-heart-fill::before { content: "\f19a"; } +.bi-bookmark-heart::before { content: "\f19b"; } +.bi-bookmark-plus-fill::before { content: "\f19c"; } +.bi-bookmark-plus::before { content: "\f19d"; } +.bi-bookmark-star-fill::before { content: "\f19e"; } +.bi-bookmark-star::before { content: "\f19f"; } +.bi-bookmark-x-fill::before { content: "\f1a0"; } +.bi-bookmark-x::before { content: "\f1a1"; } +.bi-bookmark::before { content: "\f1a2"; } +.bi-bookmarks-fill::before { content: "\f1a3"; } +.bi-bookmarks::before { content: "\f1a4"; } +.bi-bookshelf::before { content: "\f1a5"; } +.bi-bootstrap-fill::before { content: "\f1a6"; } +.bi-bootstrap-reboot::before { content: "\f1a7"; } +.bi-bootstrap::before { content: "\f1a8"; } +.bi-border-all::before { content: "\f1a9"; } +.bi-border-bottom::before { content: "\f1aa"; } +.bi-border-center::before { content: "\f1ab"; } +.bi-border-inner::before { content: "\f1ac"; } +.bi-border-left::before { content: "\f1ad"; } +.bi-border-middle::before { content: "\f1ae"; } +.bi-border-outer::before { content: "\f1af"; } +.bi-border-right::before { content: "\f1b0"; } +.bi-border-style::before { content: "\f1b1"; } +.bi-border-top::before { content: "\f1b2"; } +.bi-border-width::before { content: "\f1b3"; } +.bi-border::before { content: "\f1b4"; } +.bi-bounding-box-circles::before { content: "\f1b5"; } +.bi-bounding-box::before { content: "\f1b6"; } +.bi-box-arrow-down-left::before { content: "\f1b7"; } +.bi-box-arrow-down-right::before { content: "\f1b8"; } +.bi-box-arrow-down::before { content: "\f1b9"; } +.bi-box-arrow-in-down-left::before { content: "\f1ba"; } +.bi-box-arrow-in-down-right::before { content: "\f1bb"; } +.bi-box-arrow-in-down::before { content: "\f1bc"; } +.bi-box-arrow-in-left::before { content: "\f1bd"; } +.bi-box-arrow-in-right::before { content: "\f1be"; } +.bi-box-arrow-in-up-left::before { content: "\f1bf"; } +.bi-box-arrow-in-up-right::before { content: "\f1c0"; } +.bi-box-arrow-in-up::before { content: "\f1c1"; } +.bi-box-arrow-left::before { content: "\f1c2"; } +.bi-box-arrow-right::before { content: "\f1c3"; } +.bi-box-arrow-up-left::before { content: "\f1c4"; } +.bi-box-arrow-up-right::before { content: "\f1c5"; } +.bi-box-arrow-up::before { content: "\f1c6"; } +.bi-box-seam::before { content: "\f1c7"; } +.bi-box::before { content: "\f1c8"; } +.bi-braces::before { content: "\f1c9"; } +.bi-bricks::before { content: "\f1ca"; } +.bi-briefcase-fill::before { content: "\f1cb"; } +.bi-briefcase::before { content: "\f1cc"; } +.bi-brightness-alt-high-fill::before { content: "\f1cd"; } +.bi-brightness-alt-high::before { content: "\f1ce"; } +.bi-brightness-alt-low-fill::before { content: "\f1cf"; } +.bi-brightness-alt-low::before { content: "\f1d0"; } +.bi-brightness-high-fill::before { content: "\f1d1"; } +.bi-brightness-high::before { content: "\f1d2"; } +.bi-brightness-low-fill::before { content: "\f1d3"; } +.bi-brightness-low::before { content: "\f1d4"; } +.bi-broadcast-pin::before { content: "\f1d5"; } +.bi-broadcast::before { content: "\f1d6"; } +.bi-brush-fill::before { content: "\f1d7"; } +.bi-brush::before { content: "\f1d8"; } +.bi-bucket-fill::before { content: "\f1d9"; } +.bi-bucket::before { content: "\f1da"; } +.bi-bug-fill::before { content: "\f1db"; } +.bi-bug::before { content: "\f1dc"; } +.bi-building::before { content: "\f1dd"; } +.bi-bullseye::before { content: "\f1de"; } +.bi-calculator-fill::before { content: "\f1df"; } +.bi-calculator::before { content: "\f1e0"; } +.bi-calendar-check-fill::before { content: "\f1e1"; } +.bi-calendar-check::before { content: "\f1e2"; } +.bi-calendar-date-fill::before { content: "\f1e3"; } +.bi-calendar-date::before { content: "\f1e4"; } +.bi-calendar-day-fill::before { content: "\f1e5"; } +.bi-calendar-day::before { content: "\f1e6"; } +.bi-calendar-event-fill::before { content: "\f1e7"; } +.bi-calendar-event::before { content: "\f1e8"; } +.bi-calendar-fill::before { content: "\f1e9"; } +.bi-calendar-minus-fill::before { content: "\f1ea"; } +.bi-calendar-minus::before { content: "\f1eb"; } +.bi-calendar-month-fill::before { content: "\f1ec"; } +.bi-calendar-month::before { content: "\f1ed"; } +.bi-calendar-plus-fill::before { content: "\f1ee"; } +.bi-calendar-plus::before { content: "\f1ef"; } +.bi-calendar-range-fill::before { content: "\f1f0"; } +.bi-calendar-range::before { content: "\f1f1"; } +.bi-calendar-week-fill::before { content: "\f1f2"; } +.bi-calendar-week::before { content: "\f1f3"; } +.bi-calendar-x-fill::before { content: "\f1f4"; } +.bi-calendar-x::before { content: "\f1f5"; } +.bi-calendar::before { content: "\f1f6"; } +.bi-calendar2-check-fill::before { content: "\f1f7"; } +.bi-calendar2-check::before { content: "\f1f8"; } +.bi-calendar2-date-fill::before { content: "\f1f9"; } +.bi-calendar2-date::before { content: "\f1fa"; } +.bi-calendar2-day-fill::before { content: "\f1fb"; } +.bi-calendar2-day::before { content: "\f1fc"; } +.bi-calendar2-event-fill::before { content: "\f1fd"; } +.bi-calendar2-event::before { content: "\f1fe"; } +.bi-calendar2-fill::before { content: "\f1ff"; } +.bi-calendar2-minus-fill::before { content: "\f200"; } +.bi-calendar2-minus::before { content: "\f201"; } +.bi-calendar2-month-fill::before { content: "\f202"; } +.bi-calendar2-month::before { content: "\f203"; } +.bi-calendar2-plus-fill::before { content: "\f204"; } +.bi-calendar2-plus::before { content: "\f205"; } +.bi-calendar2-range-fill::before { content: "\f206"; } +.bi-calendar2-range::before { content: "\f207"; } +.bi-calendar2-week-fill::before { content: "\f208"; } +.bi-calendar2-week::before { content: "\f209"; } +.bi-calendar2-x-fill::before { content: "\f20a"; } +.bi-calendar2-x::before { content: "\f20b"; } +.bi-calendar2::before { content: "\f20c"; } +.bi-calendar3-event-fill::before { content: "\f20d"; } +.bi-calendar3-event::before { content: "\f20e"; } +.bi-calendar3-fill::before { content: "\f20f"; } +.bi-calendar3-range-fill::before { content: "\f210"; } +.bi-calendar3-range::before { content: "\f211"; } +.bi-calendar3-week-fill::before { content: "\f212"; } +.bi-calendar3-week::before { content: "\f213"; } +.bi-calendar3::before { content: "\f214"; } +.bi-calendar4-event::before { content: "\f215"; } +.bi-calendar4-range::before { content: "\f216"; } +.bi-calendar4-week::before { content: "\f217"; } +.bi-calendar4::before { content: "\f218"; } +.bi-camera-fill::before { content: "\f219"; } +.bi-camera-reels-fill::before { content: "\f21a"; } +.bi-camera-reels::before { content: "\f21b"; } +.bi-camera-video-fill::before { content: "\f21c"; } +.bi-camera-video-off-fill::before { content: "\f21d"; } +.bi-camera-video-off::before { content: "\f21e"; } +.bi-camera-video::before { content: "\f21f"; } +.bi-camera::before { content: "\f220"; } +.bi-camera2::before { content: "\f221"; } +.bi-capslock-fill::before { content: "\f222"; } +.bi-capslock::before { content: "\f223"; } +.bi-card-checklist::before { content: "\f224"; } +.bi-card-heading::before { content: "\f225"; } +.bi-card-image::before { content: "\f226"; } +.bi-card-list::before { content: "\f227"; } +.bi-card-text::before { content: "\f228"; } +.bi-caret-down-fill::before { content: "\f229"; } +.bi-caret-down-square-fill::before { content: "\f22a"; } +.bi-caret-down-square::before { content: "\f22b"; } +.bi-caret-down::before { content: "\f22c"; } +.bi-caret-left-fill::before { content: "\f22d"; } +.bi-caret-left-square-fill::before { content: "\f22e"; } +.bi-caret-left-square::before { content: "\f22f"; } +.bi-caret-left::before { content: "\f230"; } +.bi-caret-right-fill::before { content: "\f231"; } +.bi-caret-right-square-fill::before { content: "\f232"; } +.bi-caret-right-square::before { content: "\f233"; } +.bi-caret-right::before { content: "\f234"; } +.bi-caret-up-fill::before { content: "\f235"; } +.bi-caret-up-square-fill::before { content: "\f236"; } +.bi-caret-up-square::before { content: "\f237"; } +.bi-caret-up::before { content: "\f238"; } +.bi-cart-check-fill::before { content: "\f239"; } +.bi-cart-check::before { content: "\f23a"; } +.bi-cart-dash-fill::before { content: "\f23b"; } +.bi-cart-dash::before { content: "\f23c"; } +.bi-cart-fill::before { content: "\f23d"; } +.bi-cart-plus-fill::before { content: "\f23e"; } +.bi-cart-plus::before { content: "\f23f"; } +.bi-cart-x-fill::before { content: "\f240"; } +.bi-cart-x::before { content: "\f241"; } +.bi-cart::before { content: "\f242"; } +.bi-cart2::before { content: "\f243"; } +.bi-cart3::before { content: "\f244"; } +.bi-cart4::before { content: "\f245"; } +.bi-cash-stack::before { content: "\f246"; } +.bi-cash::before { content: "\f247"; } +.bi-cast::before { content: "\f248"; } +.bi-chat-dots-fill::before { content: "\f249"; } +.bi-chat-dots::before { content: "\f24a"; } +.bi-chat-fill::before { content: "\f24b"; } +.bi-chat-left-dots-fill::before { content: "\f24c"; } +.bi-chat-left-dots::before { content: "\f24d"; } +.bi-chat-left-fill::before { content: "\f24e"; } +.bi-chat-left-quote-fill::before { content: "\f24f"; } +.bi-chat-left-quote::before { content: "\f250"; } +.bi-chat-left-text-fill::before { content: "\f251"; } +.bi-chat-left-text::before { content: "\f252"; } +.bi-chat-left::before { content: "\f253"; } +.bi-chat-quote-fill::before { content: "\f254"; } +.bi-chat-quote::before { content: "\f255"; } +.bi-chat-right-dots-fill::before { content: "\f256"; } +.bi-chat-right-dots::before { content: "\f257"; } +.bi-chat-right-fill::before { content: "\f258"; } +.bi-chat-right-quote-fill::before { content: "\f259"; } +.bi-chat-right-quote::before { content: "\f25a"; } +.bi-chat-right-text-fill::before { content: "\f25b"; } +.bi-chat-right-text::before { content: "\f25c"; } +.bi-chat-right::before { content: "\f25d"; } +.bi-chat-square-dots-fill::before { content: "\f25e"; } +.bi-chat-square-dots::before { content: "\f25f"; } +.bi-chat-square-fill::before { content: "\f260"; } +.bi-chat-square-quote-fill::before { content: "\f261"; } +.bi-chat-square-quote::before { content: "\f262"; } +.bi-chat-square-text-fill::before { content: "\f263"; } +.bi-chat-square-text::before { content: "\f264"; } +.bi-chat-square::before { content: "\f265"; } +.bi-chat-text-fill::before { content: "\f266"; } +.bi-chat-text::before { content: "\f267"; } +.bi-chat::before { content: "\f268"; } +.bi-check-all::before { content: "\f269"; } +.bi-check-circle-fill::before { content: "\f26a"; } +.bi-check-circle::before { content: "\f26b"; } +.bi-check-square-fill::before { content: "\f26c"; } +.bi-check-square::before { content: "\f26d"; } +.bi-check::before { content: "\f26e"; } +.bi-check2-all::before { content: "\f26f"; } +.bi-check2-circle::before { content: "\f270"; } +.bi-check2-square::before { content: "\f271"; } +.bi-check2::before { content: "\f272"; } +.bi-chevron-bar-contract::before { content: "\f273"; } +.bi-chevron-bar-down::before { content: "\f274"; } +.bi-chevron-bar-expand::before { content: "\f275"; } +.bi-chevron-bar-left::before { content: "\f276"; } +.bi-chevron-bar-right::before { content: "\f277"; } +.bi-chevron-bar-up::before { content: "\f278"; } +.bi-chevron-compact-down::before { content: "\f279"; } +.bi-chevron-compact-left::before { content: "\f27a"; } +.bi-chevron-compact-right::before { content: "\f27b"; } +.bi-chevron-compact-up::before { content: "\f27c"; } +.bi-chevron-contract::before { content: "\f27d"; } +.bi-chevron-double-down::before { content: "\f27e"; } +.bi-chevron-double-left::before { content: "\f27f"; } +.bi-chevron-double-right::before { content: "\f280"; } +.bi-chevron-double-up::before { content: "\f281"; } +.bi-chevron-down::before { content: "\f282"; } +.bi-chevron-expand::before { content: "\f283"; } +.bi-chevron-left::before { content: "\f284"; } +.bi-chevron-right::before { content: "\f285"; } +.bi-chevron-up::before { content: "\f286"; } +.bi-circle-fill::before { content: "\f287"; } +.bi-circle-half::before { content: "\f288"; } +.bi-circle-square::before { content: "\f289"; } +.bi-circle::before { content: "\f28a"; } +.bi-clipboard-check::before { content: "\f28b"; } +.bi-clipboard-data::before { content: "\f28c"; } +.bi-clipboard-minus::before { content: "\f28d"; } +.bi-clipboard-plus::before { content: "\f28e"; } +.bi-clipboard-x::before { content: "\f28f"; } +.bi-clipboard::before { content: "\f290"; } +.bi-clock-fill::before { content: "\f291"; } +.bi-clock-history::before { content: "\f292"; } +.bi-clock::before { content: "\f293"; } +.bi-cloud-arrow-down-fill::before { content: "\f294"; } +.bi-cloud-arrow-down::before { content: "\f295"; } +.bi-cloud-arrow-up-fill::before { content: "\f296"; } +.bi-cloud-arrow-up::before { content: "\f297"; } +.bi-cloud-check-fill::before { content: "\f298"; } +.bi-cloud-check::before { content: "\f299"; } +.bi-cloud-download-fill::before { content: "\f29a"; } +.bi-cloud-download::before { content: "\f29b"; } +.bi-cloud-drizzle-fill::before { content: "\f29c"; } +.bi-cloud-drizzle::before { content: "\f29d"; } +.bi-cloud-fill::before { content: "\f29e"; } +.bi-cloud-fog-fill::before { content: "\f29f"; } +.bi-cloud-fog::before { content: "\f2a0"; } +.bi-cloud-fog2-fill::before { content: "\f2a1"; } +.bi-cloud-fog2::before { content: "\f2a2"; } +.bi-cloud-hail-fill::before { content: "\f2a3"; } +.bi-cloud-hail::before { content: "\f2a4"; } +.bi-cloud-haze-1::before { content: "\f2a5"; } +.bi-cloud-haze-fill::before { content: "\f2a6"; } +.bi-cloud-haze::before { content: "\f2a7"; } +.bi-cloud-haze2-fill::before { content: "\f2a8"; } +.bi-cloud-lightning-fill::before { content: "\f2a9"; } +.bi-cloud-lightning-rain-fill::before { content: "\f2aa"; } +.bi-cloud-lightning-rain::before { content: "\f2ab"; } +.bi-cloud-lightning::before { content: "\f2ac"; } +.bi-cloud-minus-fill::before { content: "\f2ad"; } +.bi-cloud-minus::before { content: "\f2ae"; } +.bi-cloud-moon-fill::before { content: "\f2af"; } +.bi-cloud-moon::before { content: "\f2b0"; } +.bi-cloud-plus-fill::before { content: "\f2b1"; } +.bi-cloud-plus::before { content: "\f2b2"; } +.bi-cloud-rain-fill::before { content: "\f2b3"; } +.bi-cloud-rain-heavy-fill::before { content: "\f2b4"; } +.bi-cloud-rain-heavy::before { content: "\f2b5"; } +.bi-cloud-rain::before { content: "\f2b6"; } +.bi-cloud-slash-fill::before { content: "\f2b7"; } +.bi-cloud-slash::before { content: "\f2b8"; } +.bi-cloud-sleet-fill::before { content: "\f2b9"; } +.bi-cloud-sleet::before { content: "\f2ba"; } +.bi-cloud-snow-fill::before { content: "\f2bb"; } +.bi-cloud-snow::before { content: "\f2bc"; } +.bi-cloud-sun-fill::before { content: "\f2bd"; } +.bi-cloud-sun::before { content: "\f2be"; } +.bi-cloud-upload-fill::before { content: "\f2bf"; } +.bi-cloud-upload::before { content: "\f2c0"; } +.bi-cloud::before { content: "\f2c1"; } +.bi-clouds-fill::before { content: "\f2c2"; } +.bi-clouds::before { content: "\f2c3"; } +.bi-cloudy-fill::before { content: "\f2c4"; } +.bi-cloudy::before { content: "\f2c5"; } +.bi-code-slash::before { content: "\f2c6"; } +.bi-code-square::before { content: "\f2c7"; } +.bi-code::before { content: "\f2c8"; } +.bi-collection-fill::before { content: "\f2c9"; } +.bi-collection-play-fill::before { content: "\f2ca"; } +.bi-collection-play::before { content: "\f2cb"; } +.bi-collection::before { content: "\f2cc"; } +.bi-columns-gap::before { content: "\f2cd"; } +.bi-columns::before { content: "\f2ce"; } +.bi-command::before { content: "\f2cf"; } +.bi-compass-fill::before { content: "\f2d0"; } +.bi-compass::before { content: "\f2d1"; } +.bi-cone-striped::before { content: "\f2d2"; } +.bi-cone::before { content: "\f2d3"; } +.bi-controller::before { content: "\f2d4"; } +.bi-cpu-fill::before { content: "\f2d5"; } +.bi-cpu::before { content: "\f2d6"; } +.bi-credit-card-2-back-fill::before { content: "\f2d7"; } +.bi-credit-card-2-back::before { content: "\f2d8"; } +.bi-credit-card-2-front-fill::before { content: "\f2d9"; } +.bi-credit-card-2-front::before { content: "\f2da"; } +.bi-credit-card-fill::before { content: "\f2db"; } +.bi-credit-card::before { content: "\f2dc"; } +.bi-crop::before { content: "\f2dd"; } +.bi-cup-fill::before { content: "\f2de"; } +.bi-cup-straw::before { content: "\f2df"; } +.bi-cup::before { content: "\f2e0"; } +.bi-cursor-fill::before { content: "\f2e1"; } +.bi-cursor-text::before { content: "\f2e2"; } +.bi-cursor::before { content: "\f2e3"; } +.bi-dash-circle-dotted::before { content: "\f2e4"; } +.bi-dash-circle-fill::before { content: "\f2e5"; } +.bi-dash-circle::before { content: "\f2e6"; } +.bi-dash-square-dotted::before { content: "\f2e7"; } +.bi-dash-square-fill::before { content: "\f2e8"; } +.bi-dash-square::before { content: "\f2e9"; } +.bi-dash::before { content: "\f2ea"; } +.bi-diagram-2-fill::before { content: "\f2eb"; } +.bi-diagram-2::before { content: "\f2ec"; } +.bi-diagram-3-fill::before { content: "\f2ed"; } +.bi-diagram-3::before { content: "\f2ee"; } +.bi-diamond-fill::before { content: "\f2ef"; } +.bi-diamond-half::before { content: "\f2f0"; } +.bi-diamond::before { content: "\f2f1"; } +.bi-dice-1-fill::before { content: "\f2f2"; } +.bi-dice-1::before { content: "\f2f3"; } +.bi-dice-2-fill::before { content: "\f2f4"; } +.bi-dice-2::before { content: "\f2f5"; } +.bi-dice-3-fill::before { content: "\f2f6"; } +.bi-dice-3::before { content: "\f2f7"; } +.bi-dice-4-fill::before { content: "\f2f8"; } +.bi-dice-4::before { content: "\f2f9"; } +.bi-dice-5-fill::before { content: "\f2fa"; } +.bi-dice-5::before { content: "\f2fb"; } +.bi-dice-6-fill::before { content: "\f2fc"; } +.bi-dice-6::before { content: "\f2fd"; } +.bi-disc-fill::before { content: "\f2fe"; } +.bi-disc::before { content: "\f2ff"; } +.bi-discord::before { content: "\f300"; } +.bi-display-fill::before { content: "\f301"; } +.bi-display::before { content: "\f302"; } +.bi-distribute-horizontal::before { content: "\f303"; } +.bi-distribute-vertical::before { content: "\f304"; } +.bi-door-closed-fill::before { content: "\f305"; } +.bi-door-closed::before { content: "\f306"; } +.bi-door-open-fill::before { content: "\f307"; } +.bi-door-open::before { content: "\f308"; } +.bi-dot::before { content: "\f309"; } +.bi-download::before { content: "\f30a"; } +.bi-droplet-fill::before { content: "\f30b"; } +.bi-droplet-half::before { content: "\f30c"; } +.bi-droplet::before { content: "\f30d"; } +.bi-earbuds::before { content: "\f30e"; } +.bi-easel-fill::before { content: "\f30f"; } +.bi-easel::before { content: "\f310"; } +.bi-egg-fill::before { content: "\f311"; } +.bi-egg-fried::before { content: "\f312"; } +.bi-egg::before { content: "\f313"; } +.bi-eject-fill::before { content: "\f314"; } +.bi-eject::before { content: "\f315"; } +.bi-emoji-angry-fill::before { content: "\f316"; } +.bi-emoji-angry::before { content: "\f317"; } +.bi-emoji-dizzy-fill::before { content: "\f318"; } +.bi-emoji-dizzy::before { content: "\f319"; } +.bi-emoji-expressionless-fill::before { content: "\f31a"; } +.bi-emoji-expressionless::before { content: "\f31b"; } +.bi-emoji-frown-fill::before { content: "\f31c"; } +.bi-emoji-frown::before { content: "\f31d"; } +.bi-emoji-heart-eyes-fill::before { content: "\f31e"; } +.bi-emoji-heart-eyes::before { content: "\f31f"; } +.bi-emoji-laughing-fill::before { content: "\f320"; } +.bi-emoji-laughing::before { content: "\f321"; } +.bi-emoji-neutral-fill::before { content: "\f322"; } +.bi-emoji-neutral::before { content: "\f323"; } +.bi-emoji-smile-fill::before { content: "\f324"; } +.bi-emoji-smile-upside-down-fill::before { content: "\f325"; } +.bi-emoji-smile-upside-down::before { content: "\f326"; } +.bi-emoji-smile::before { content: "\f327"; } +.bi-emoji-sunglasses-fill::before { content: "\f328"; } +.bi-emoji-sunglasses::before { content: "\f329"; } +.bi-emoji-wink-fill::before { content: "\f32a"; } +.bi-emoji-wink::before { content: "\f32b"; } +.bi-envelope-fill::before { content: "\f32c"; } +.bi-envelope-open-fill::before { content: "\f32d"; } +.bi-envelope-open::before { content: "\f32e"; } +.bi-envelope::before { content: "\f32f"; } +.bi-eraser-fill::before { content: "\f330"; } +.bi-eraser::before { content: "\f331"; } +.bi-exclamation-circle-fill::before { content: "\f332"; } +.bi-exclamation-circle::before { content: "\f333"; } +.bi-exclamation-diamond-fill::before { content: "\f334"; } +.bi-exclamation-diamond::before { content: "\f335"; } +.bi-exclamation-octagon-fill::before { content: "\f336"; } +.bi-exclamation-octagon::before { content: "\f337"; } +.bi-exclamation-square-fill::before { content: "\f338"; } +.bi-exclamation-square::before { content: "\f339"; } +.bi-exclamation-triangle-fill::before { content: "\f33a"; } +.bi-exclamation-triangle::before { content: "\f33b"; } +.bi-exclamation::before { content: "\f33c"; } +.bi-exclude::before { content: "\f33d"; } +.bi-eye-fill::before { content: "\f33e"; } +.bi-eye-slash-fill::before { content: "\f33f"; } +.bi-eye-slash::before { content: "\f340"; } +.bi-eye::before { content: "\f341"; } +.bi-eyedropper::before { content: "\f342"; } +.bi-eyeglasses::before { content: "\f343"; } +.bi-facebook::before { content: "\f344"; } +.bi-file-arrow-down-fill::before { content: "\f345"; } +.bi-file-arrow-down::before { content: "\f346"; } +.bi-file-arrow-up-fill::before { content: "\f347"; } +.bi-file-arrow-up::before { content: "\f348"; } +.bi-file-bar-graph-fill::before { content: "\f349"; } +.bi-file-bar-graph::before { content: "\f34a"; } +.bi-file-binary-fill::before { content: "\f34b"; } +.bi-file-binary::before { content: "\f34c"; } +.bi-file-break-fill::before { content: "\f34d"; } +.bi-file-break::before { content: "\f34e"; } +.bi-file-check-fill::before { content: "\f34f"; } +.bi-file-check::before { content: "\f350"; } +.bi-file-code-fill::before { content: "\f351"; } +.bi-file-code::before { content: "\f352"; } +.bi-file-diff-fill::before { content: "\f353"; } +.bi-file-diff::before { content: "\f354"; } +.bi-file-earmark-arrow-down-fill::before { content: "\f355"; } +.bi-file-earmark-arrow-down::before { content: "\f356"; } +.bi-file-earmark-arrow-up-fill::before { content: "\f357"; } +.bi-file-earmark-arrow-up::before { content: "\f358"; } +.bi-file-earmark-bar-graph-fill::before { content: "\f359"; } +.bi-file-earmark-bar-graph::before { content: "\f35a"; } +.bi-file-earmark-binary-fill::before { content: "\f35b"; } +.bi-file-earmark-binary::before { content: "\f35c"; } +.bi-file-earmark-break-fill::before { content: "\f35d"; } +.bi-file-earmark-break::before { content: "\f35e"; } +.bi-file-earmark-check-fill::before { content: "\f35f"; } +.bi-file-earmark-check::before { content: "\f360"; } +.bi-file-earmark-code-fill::before { content: "\f361"; } +.bi-file-earmark-code::before { content: "\f362"; } +.bi-file-earmark-diff-fill::before { content: "\f363"; } +.bi-file-earmark-diff::before { content: "\f364"; } +.bi-file-earmark-easel-fill::before { content: "\f365"; } +.bi-file-earmark-easel::before { content: "\f366"; } +.bi-file-earmark-excel-fill::before { content: "\f367"; } +.bi-file-earmark-excel::before { content: "\f368"; } +.bi-file-earmark-fill::before { content: "\f369"; } +.bi-file-earmark-font-fill::before { content: "\f36a"; } +.bi-file-earmark-font::before { content: "\f36b"; } +.bi-file-earmark-image-fill::before { content: "\f36c"; } +.bi-file-earmark-image::before { content: "\f36d"; } +.bi-file-earmark-lock-fill::before { content: "\f36e"; } +.bi-file-earmark-lock::before { content: "\f36f"; } +.bi-file-earmark-lock2-fill::before { content: "\f370"; } +.bi-file-earmark-lock2::before { content: "\f371"; } +.bi-file-earmark-medical-fill::before { content: "\f372"; } +.bi-file-earmark-medical::before { content: "\f373"; } +.bi-file-earmark-minus-fill::before { content: "\f374"; } +.bi-file-earmark-minus::before { content: "\f375"; } +.bi-file-earmark-music-fill::before { content: "\f376"; } +.bi-file-earmark-music::before { content: "\f377"; } +.bi-file-earmark-person-fill::before { content: "\f378"; } +.bi-file-earmark-person::before { content: "\f379"; } +.bi-file-earmark-play-fill::before { content: "\f37a"; } +.bi-file-earmark-play::before { content: "\f37b"; } +.bi-file-earmark-plus-fill::before { content: "\f37c"; } +.bi-file-earmark-plus::before { content: "\f37d"; } +.bi-file-earmark-post-fill::before { content: "\f37e"; } +.bi-file-earmark-post::before { content: "\f37f"; } +.bi-file-earmark-ppt-fill::before { content: "\f380"; } +.bi-file-earmark-ppt::before { content: "\f381"; } +.bi-file-earmark-richtext-fill::before { content: "\f382"; } +.bi-file-earmark-richtext::before { content: "\f383"; } +.bi-file-earmark-ruled-fill::before { content: "\f384"; } +.bi-file-earmark-ruled::before { content: "\f385"; } +.bi-file-earmark-slides-fill::before { content: "\f386"; } +.bi-file-earmark-slides::before { content: "\f387"; } +.bi-file-earmark-spreadsheet-fill::before { content: "\f388"; } +.bi-file-earmark-spreadsheet::before { content: "\f389"; } +.bi-file-earmark-text-fill::before { content: "\f38a"; } +.bi-file-earmark-text::before { content: "\f38b"; } +.bi-file-earmark-word-fill::before { content: "\f38c"; } +.bi-file-earmark-word::before { content: "\f38d"; } +.bi-file-earmark-x-fill::before { content: "\f38e"; } +.bi-file-earmark-x::before { content: "\f38f"; } +.bi-file-earmark-zip-fill::before { content: "\f390"; } +.bi-file-earmark-zip::before { content: "\f391"; } +.bi-file-earmark::before { content: "\f392"; } +.bi-file-easel-fill::before { content: "\f393"; } +.bi-file-easel::before { content: "\f394"; } +.bi-file-excel-fill::before { content: "\f395"; } +.bi-file-excel::before { content: "\f396"; } +.bi-file-fill::before { content: "\f397"; } +.bi-file-font-fill::before { content: "\f398"; } +.bi-file-font::before { content: "\f399"; } +.bi-file-image-fill::before { content: "\f39a"; } +.bi-file-image::before { content: "\f39b"; } +.bi-file-lock-fill::before { content: "\f39c"; } +.bi-file-lock::before { content: "\f39d"; } +.bi-file-lock2-fill::before { content: "\f39e"; } +.bi-file-lock2::before { content: "\f39f"; } +.bi-file-medical-fill::before { content: "\f3a0"; } +.bi-file-medical::before { content: "\f3a1"; } +.bi-file-minus-fill::before { content: "\f3a2"; } +.bi-file-minus::before { content: "\f3a3"; } +.bi-file-music-fill::before { content: "\f3a4"; } +.bi-file-music::before { content: "\f3a5"; } +.bi-file-person-fill::before { content: "\f3a6"; } +.bi-file-person::before { content: "\f3a7"; } +.bi-file-play-fill::before { content: "\f3a8"; } +.bi-file-play::before { content: "\f3a9"; } +.bi-file-plus-fill::before { content: "\f3aa"; } +.bi-file-plus::before { content: "\f3ab"; } +.bi-file-post-fill::before { content: "\f3ac"; } +.bi-file-post::before { content: "\f3ad"; } +.bi-file-ppt-fill::before { content: "\f3ae"; } +.bi-file-ppt::before { content: "\f3af"; } +.bi-file-richtext-fill::before { content: "\f3b0"; } +.bi-file-richtext::before { content: "\f3b1"; } +.bi-file-ruled-fill::before { content: "\f3b2"; } +.bi-file-ruled::before { content: "\f3b3"; } +.bi-file-slides-fill::before { content: "\f3b4"; } +.bi-file-slides::before { content: "\f3b5"; } +.bi-file-spreadsheet-fill::before { content: "\f3b6"; } +.bi-file-spreadsheet::before { content: "\f3b7"; } +.bi-file-text-fill::before { content: "\f3b8"; } +.bi-file-text::before { content: "\f3b9"; } +.bi-file-word-fill::before { content: "\f3ba"; } +.bi-file-word::before { content: "\f3bb"; } +.bi-file-x-fill::before { content: "\f3bc"; } +.bi-file-x::before { content: "\f3bd"; } +.bi-file-zip-fill::before { content: "\f3be"; } +.bi-file-zip::before { content: "\f3bf"; } +.bi-file::before { content: "\f3c0"; } +.bi-files-alt::before { content: "\f3c1"; } +.bi-files::before { content: "\f3c2"; } +.bi-film::before { content: "\f3c3"; } +.bi-filter-circle-fill::before { content: "\f3c4"; } +.bi-filter-circle::before { content: "\f3c5"; } +.bi-filter-left::before { content: "\f3c6"; } +.bi-filter-right::before { content: "\f3c7"; } +.bi-filter-square-fill::before { content: "\f3c8"; } +.bi-filter-square::before { content: "\f3c9"; } +.bi-filter::before { content: "\f3ca"; } +.bi-flag-fill::before { content: "\f3cb"; } +.bi-flag::before { content: "\f3cc"; } +.bi-flower1::before { content: "\f3cd"; } +.bi-flower2::before { content: "\f3ce"; } +.bi-flower3::before { content: "\f3cf"; } +.bi-folder-check::before { content: "\f3d0"; } +.bi-folder-fill::before { content: "\f3d1"; } +.bi-folder-minus::before { content: "\f3d2"; } +.bi-folder-plus::before { content: "\f3d3"; } +.bi-folder-symlink-fill::before { content: "\f3d4"; } +.bi-folder-symlink::before { content: "\f3d5"; } +.bi-folder-x::before { content: "\f3d6"; } +.bi-folder::before { content: "\f3d7"; } +.bi-folder2-open::before { content: "\f3d8"; } +.bi-folder2::before { content: "\f3d9"; } +.bi-fonts::before { content: "\f3da"; } +.bi-forward-fill::before { content: "\f3db"; } +.bi-forward::before { content: "\f3dc"; } +.bi-front::before { content: "\f3dd"; } +.bi-fullscreen-exit::before { content: "\f3de"; } +.bi-fullscreen::before { content: "\f3df"; } +.bi-funnel-fill::before { content: "\f3e0"; } +.bi-funnel::before { content: "\f3e1"; } +.bi-gear-fill::before { content: "\f3e2"; } +.bi-gear-wide-connected::before { content: "\f3e3"; } +.bi-gear-wide::before { content: "\f3e4"; } +.bi-gear::before { content: "\f3e5"; } +.bi-gem::before { content: "\f3e6"; } +.bi-geo-alt-fill::before { content: "\f3e7"; } +.bi-geo-alt::before { content: "\f3e8"; } +.bi-geo-fill::before { content: "\f3e9"; } +.bi-geo::before { content: "\f3ea"; } +.bi-gift-fill::before { content: "\f3eb"; } +.bi-gift::before { content: "\f3ec"; } +.bi-github::before { content: "\f3ed"; } +.bi-globe::before { content: "\f3ee"; } +.bi-globe2::before { content: "\f3ef"; } +.bi-google::before { content: "\f3f0"; } +.bi-graph-down::before { content: "\f3f1"; } +.bi-graph-up::before { content: "\f3f2"; } +.bi-grid-1x2-fill::before { content: "\f3f3"; } +.bi-grid-1x2::before { content: "\f3f4"; } +.bi-grid-3x2-gap-fill::before { content: "\f3f5"; } +.bi-grid-3x2-gap::before { content: "\f3f6"; } +.bi-grid-3x2::before { content: "\f3f7"; } +.bi-grid-3x3-gap-fill::before { content: "\f3f8"; } +.bi-grid-3x3-gap::before { content: "\f3f9"; } +.bi-grid-3x3::before { content: "\f3fa"; } +.bi-grid-fill::before { content: "\f3fb"; } +.bi-grid::before { content: "\f3fc"; } +.bi-grip-horizontal::before { content: "\f3fd"; } +.bi-grip-vertical::before { content: "\f3fe"; } +.bi-hammer::before { content: "\f3ff"; } +.bi-hand-index-fill::before { content: "\f400"; } +.bi-hand-index-thumb-fill::before { content: "\f401"; } +.bi-hand-index-thumb::before { content: "\f402"; } +.bi-hand-index::before { content: "\f403"; } +.bi-hand-thumbs-down-fill::before { content: "\f404"; } +.bi-hand-thumbs-down::before { content: "\f405"; } +.bi-hand-thumbs-up-fill::before { content: "\f406"; } +.bi-hand-thumbs-up::before { content: "\f407"; } +.bi-handbag-fill::before { content: "\f408"; } +.bi-handbag::before { content: "\f409"; } +.bi-hash::before { content: "\f40a"; } +.bi-hdd-fill::before { content: "\f40b"; } +.bi-hdd-network-fill::before { content: "\f40c"; } +.bi-hdd-network::before { content: "\f40d"; } +.bi-hdd-rack-fill::before { content: "\f40e"; } +.bi-hdd-rack::before { content: "\f40f"; } +.bi-hdd-stack-fill::before { content: "\f410"; } +.bi-hdd-stack::before { content: "\f411"; } +.bi-hdd::before { content: "\f412"; } +.bi-headphones::before { content: "\f413"; } +.bi-headset::before { content: "\f414"; } +.bi-heart-fill::before { content: "\f415"; } +.bi-heart-half::before { content: "\f416"; } +.bi-heart::before { content: "\f417"; } +.bi-heptagon-fill::before { content: "\f418"; } +.bi-heptagon-half::before { content: "\f419"; } +.bi-heptagon::before { content: "\f41a"; } +.bi-hexagon-fill::before { content: "\f41b"; } +.bi-hexagon-half::before { content: "\f41c"; } +.bi-hexagon::before { content: "\f41d"; } +.bi-hourglass-bottom::before { content: "\f41e"; } +.bi-hourglass-split::before { content: "\f41f"; } +.bi-hourglass-top::before { content: "\f420"; } +.bi-hourglass::before { content: "\f421"; } +.bi-house-door-fill::before { content: "\f422"; } +.bi-house-door::before { content: "\f423"; } +.bi-house-fill::before { content: "\f424"; } +.bi-house::before { content: "\f425"; } +.bi-hr::before { content: "\f426"; } +.bi-hurricane::before { content: "\f427"; } +.bi-image-alt::before { content: "\f428"; } +.bi-image-fill::before { content: "\f429"; } +.bi-image::before { content: "\f42a"; } +.bi-images::before { content: "\f42b"; } +.bi-inbox-fill::before { content: "\f42c"; } +.bi-inbox::before { content: "\f42d"; } +.bi-inboxes-fill::before { content: "\f42e"; } +.bi-inboxes::before { content: "\f42f"; } +.bi-info-circle-fill::before { content: "\f430"; } +.bi-info-circle::before { content: "\f431"; } +.bi-info-square-fill::before { content: "\f432"; } +.bi-info-square::before { content: "\f433"; } +.bi-info::before { content: "\f434"; } +.bi-input-cursor-text::before { content: "\f435"; } +.bi-input-cursor::before { content: "\f436"; } +.bi-instagram::before { content: "\f437"; } +.bi-intersect::before { content: "\f438"; } +.bi-journal-album::before { content: "\f439"; } +.bi-journal-arrow-down::before { content: "\f43a"; } +.bi-journal-arrow-up::before { content: "\f43b"; } +.bi-journal-bookmark-fill::before { content: "\f43c"; } +.bi-journal-bookmark::before { content: "\f43d"; } +.bi-journal-check::before { content: "\f43e"; } +.bi-journal-code::before { content: "\f43f"; } +.bi-journal-medical::before { content: "\f440"; } +.bi-journal-minus::before { content: "\f441"; } +.bi-journal-plus::before { content: "\f442"; } +.bi-journal-richtext::before { content: "\f443"; } +.bi-journal-text::before { content: "\f444"; } +.bi-journal-x::before { content: "\f445"; } +.bi-journal::before { content: "\f446"; } +.bi-journals::before { content: "\f447"; } +.bi-joystick::before { content: "\f448"; } +.bi-justify-left::before { content: "\f449"; } +.bi-justify-right::before { content: "\f44a"; } +.bi-justify::before { content: "\f44b"; } +.bi-kanban-fill::before { content: "\f44c"; } +.bi-kanban::before { content: "\f44d"; } +.bi-key-fill::before { content: "\f44e"; } +.bi-key::before { content: "\f44f"; } +.bi-keyboard-fill::before { content: "\f450"; } +.bi-keyboard::before { content: "\f451"; } +.bi-ladder::before { content: "\f452"; } +.bi-lamp-fill::before { content: "\f453"; } +.bi-lamp::before { content: "\f454"; } +.bi-laptop-fill::before { content: "\f455"; } +.bi-laptop::before { content: "\f456"; } +.bi-layer-backward::before { content: "\f457"; } +.bi-layer-forward::before { content: "\f458"; } +.bi-layers-fill::before { content: "\f459"; } +.bi-layers-half::before { content: "\f45a"; } +.bi-layers::before { content: "\f45b"; } +.bi-layout-sidebar-inset-reverse::before { content: "\f45c"; } +.bi-layout-sidebar-inset::before { content: "\f45d"; } +.bi-layout-sidebar-reverse::before { content: "\f45e"; } +.bi-layout-sidebar::before { content: "\f45f"; } +.bi-layout-split::before { content: "\f460"; } +.bi-layout-text-sidebar-reverse::before { content: "\f461"; } +.bi-layout-text-sidebar::before { content: "\f462"; } +.bi-layout-text-window-reverse::before { content: "\f463"; } +.bi-layout-text-window::before { content: "\f464"; } +.bi-layout-three-columns::before { content: "\f465"; } +.bi-layout-wtf::before { content: "\f466"; } +.bi-life-preserver::before { content: "\f467"; } +.bi-lightbulb-fill::before { content: "\f468"; } +.bi-lightbulb-off-fill::before { content: "\f469"; } +.bi-lightbulb-off::before { content: "\f46a"; } +.bi-lightbulb::before { content: "\f46b"; } +.bi-lightning-charge-fill::before { content: "\f46c"; } +.bi-lightning-charge::before { content: "\f46d"; } +.bi-lightning-fill::before { content: "\f46e"; } +.bi-lightning::before { content: "\f46f"; } +.bi-link-45deg::before { content: "\f470"; } +.bi-link::before { content: "\f471"; } +.bi-linkedin::before { content: "\f472"; } +.bi-list-check::before { content: "\f473"; } +.bi-list-nested::before { content: "\f474"; } +.bi-list-ol::before { content: "\f475"; } +.bi-list-stars::before { content: "\f476"; } +.bi-list-task::before { content: "\f477"; } +.bi-list-ul::before { content: "\f478"; } +.bi-list::before { content: "\f479"; } +.bi-lock-fill::before { content: "\f47a"; } +.bi-lock::before { content: "\f47b"; } +.bi-mailbox::before { content: "\f47c"; } +.bi-mailbox2::before { content: "\f47d"; } +.bi-map-fill::before { content: "\f47e"; } +.bi-map::before { content: "\f47f"; } +.bi-markdown-fill::before { content: "\f480"; } +.bi-markdown::before { content: "\f481"; } +.bi-mask::before { content: "\f482"; } +.bi-megaphone-fill::before { content: "\f483"; } +.bi-megaphone::before { content: "\f484"; } +.bi-menu-app-fill::before { content: "\f485"; } +.bi-menu-app::before { content: "\f486"; } +.bi-menu-button-fill::before { content: "\f487"; } +.bi-menu-button-wide-fill::before { content: "\f488"; } +.bi-menu-button-wide::before { content: "\f489"; } +.bi-menu-button::before { content: "\f48a"; } +.bi-menu-down::before { content: "\f48b"; } +.bi-menu-up::before { content: "\f48c"; } +.bi-mic-fill::before { content: "\f48d"; } +.bi-mic-mute-fill::before { content: "\f48e"; } +.bi-mic-mute::before { content: "\f48f"; } +.bi-mic::before { content: "\f490"; } +.bi-minecart-loaded::before { content: "\f491"; } +.bi-minecart::before { content: "\f492"; } +.bi-moisture::before { content: "\f493"; } +.bi-moon-fill::before { content: "\f494"; } +.bi-moon-stars-fill::before { content: "\f495"; } +.bi-moon-stars::before { content: "\f496"; } +.bi-moon::before { content: "\f497"; } +.bi-mouse-fill::before { content: "\f498"; } +.bi-mouse::before { content: "\f499"; } +.bi-mouse2-fill::before { content: "\f49a"; } +.bi-mouse2::before { content: "\f49b"; } +.bi-mouse3-fill::before { content: "\f49c"; } +.bi-mouse3::before { content: "\f49d"; } +.bi-music-note-beamed::before { content: "\f49e"; } +.bi-music-note-list::before { content: "\f49f"; } +.bi-music-note::before { content: "\f4a0"; } +.bi-music-player-fill::before { content: "\f4a1"; } +.bi-music-player::before { content: "\f4a2"; } +.bi-newspaper::before { content: "\f4a3"; } +.bi-node-minus-fill::before { content: "\f4a4"; } +.bi-node-minus::before { content: "\f4a5"; } +.bi-node-plus-fill::before { content: "\f4a6"; } +.bi-node-plus::before { content: "\f4a7"; } +.bi-nut-fill::before { content: "\f4a8"; } +.bi-nut::before { content: "\f4a9"; } +.bi-octagon-fill::before { content: "\f4aa"; } +.bi-octagon-half::before { content: "\f4ab"; } +.bi-octagon::before { content: "\f4ac"; } +.bi-option::before { content: "\f4ad"; } +.bi-outlet::before { content: "\f4ae"; } +.bi-paint-bucket::before { content: "\f4af"; } +.bi-palette-fill::before { content: "\f4b0"; } +.bi-palette::before { content: "\f4b1"; } +.bi-palette2::before { content: "\f4b2"; } +.bi-paperclip::before { content: "\f4b3"; } +.bi-paragraph::before { content: "\f4b4"; } +.bi-patch-check-fill::before { content: "\f4b5"; } +.bi-patch-check::before { content: "\f4b6"; } +.bi-patch-exclamation-fill::before { content: "\f4b7"; } +.bi-patch-exclamation::before { content: "\f4b8"; } +.bi-patch-minus-fill::before { content: "\f4b9"; } +.bi-patch-minus::before { content: "\f4ba"; } +.bi-patch-plus-fill::before { content: "\f4bb"; } +.bi-patch-plus::before { content: "\f4bc"; } +.bi-patch-question-fill::before { content: "\f4bd"; } +.bi-patch-question::before { content: "\f4be"; } +.bi-pause-btn-fill::before { content: "\f4bf"; } +.bi-pause-btn::before { content: "\f4c0"; } +.bi-pause-circle-fill::before { content: "\f4c1"; } +.bi-pause-circle::before { content: "\f4c2"; } +.bi-pause-fill::before { content: "\f4c3"; } +.bi-pause::before { content: "\f4c4"; } +.bi-peace-fill::before { content: "\f4c5"; } +.bi-peace::before { content: "\f4c6"; } +.bi-pen-fill::before { content: "\f4c7"; } +.bi-pen::before { content: "\f4c8"; } +.bi-pencil-fill::before { content: "\f4c9"; } +.bi-pencil-square::before { content: "\f4ca"; } +.bi-pencil::before { content: "\f4cb"; } +.bi-pentagon-fill::before { content: "\f4cc"; } +.bi-pentagon-half::before { content: "\f4cd"; } +.bi-pentagon::before { content: "\f4ce"; } +.bi-people-fill::before { content: "\f4cf"; } +.bi-people::before { content: "\f4d0"; } +.bi-percent::before { content: "\f4d1"; } +.bi-person-badge-fill::before { content: "\f4d2"; } +.bi-person-badge::before { content: "\f4d3"; } +.bi-person-bounding-box::before { content: "\f4d4"; } +.bi-person-check-fill::before { content: "\f4d5"; } +.bi-person-check::before { content: "\f4d6"; } +.bi-person-circle::before { content: "\f4d7"; } +.bi-person-dash-fill::before { content: "\f4d8"; } +.bi-person-dash::before { content: "\f4d9"; } +.bi-person-fill::before { content: "\f4da"; } +.bi-person-lines-fill::before { content: "\f4db"; } +.bi-person-plus-fill::before { content: "\f4dc"; } +.bi-person-plus::before { content: "\f4dd"; } +.bi-person-square::before { content: "\f4de"; } +.bi-person-x-fill::before { content: "\f4df"; } +.bi-person-x::before { content: "\f4e0"; } +.bi-person::before { content: "\f4e1"; } +.bi-phone-fill::before { content: "\f4e2"; } +.bi-phone-landscape-fill::before { content: "\f4e3"; } +.bi-phone-landscape::before { content: "\f4e4"; } +.bi-phone-vibrate-fill::before { content: "\f4e5"; } +.bi-phone-vibrate::before { content: "\f4e6"; } +.bi-phone::before { content: "\f4e7"; } +.bi-pie-chart-fill::before { content: "\f4e8"; } +.bi-pie-chart::before { content: "\f4e9"; } +.bi-pin-angle-fill::before { content: "\f4ea"; } +.bi-pin-angle::before { content: "\f4eb"; } +.bi-pin-fill::before { content: "\f4ec"; } +.bi-pin::before { content: "\f4ed"; } +.bi-pip-fill::before { content: "\f4ee"; } +.bi-pip::before { content: "\f4ef"; } +.bi-play-btn-fill::before { content: "\f4f0"; } +.bi-play-btn::before { content: "\f4f1"; } +.bi-play-circle-fill::before { content: "\f4f2"; } +.bi-play-circle::before { content: "\f4f3"; } +.bi-play-fill::before { content: "\f4f4"; } +.bi-play::before { content: "\f4f5"; } +.bi-plug-fill::before { content: "\f4f6"; } +.bi-plug::before { content: "\f4f7"; } +.bi-plus-circle-dotted::before { content: "\f4f8"; } +.bi-plus-circle-fill::before { content: "\f4f9"; } +.bi-plus-circle::before { content: "\f4fa"; } +.bi-plus-square-dotted::before { content: "\f4fb"; } +.bi-plus-square-fill::before { content: "\f4fc"; } +.bi-plus-square::before { content: "\f4fd"; } +.bi-plus::before { content: "\f4fe"; } +.bi-power::before { content: "\f4ff"; } +.bi-printer-fill::before { content: "\f500"; } +.bi-printer::before { content: "\f501"; } +.bi-puzzle-fill::before { content: "\f502"; } +.bi-puzzle::before { content: "\f503"; } +.bi-question-circle-fill::before { content: "\f504"; } +.bi-question-circle::before { content: "\f505"; } +.bi-question-diamond-fill::before { content: "\f506"; } +.bi-question-diamond::before { content: "\f507"; } +.bi-question-octagon-fill::before { content: "\f508"; } +.bi-question-octagon::before { content: "\f509"; } +.bi-question-square-fill::before { content: "\f50a"; } +.bi-question-square::before { content: "\f50b"; } +.bi-question::before { content: "\f50c"; } +.bi-rainbow::before { content: "\f50d"; } +.bi-receipt-cutoff::before { content: "\f50e"; } +.bi-receipt::before { content: "\f50f"; } +.bi-reception-0::before { content: "\f510"; } +.bi-reception-1::before { content: "\f511"; } +.bi-reception-2::before { content: "\f512"; } +.bi-reception-3::before { content: "\f513"; } +.bi-reception-4::before { content: "\f514"; } +.bi-record-btn-fill::before { content: "\f515"; } +.bi-record-btn::before { content: "\f516"; } +.bi-record-circle-fill::before { content: "\f517"; } +.bi-record-circle::before { content: "\f518"; } +.bi-record-fill::before { content: "\f519"; } +.bi-record::before { content: "\f51a"; } +.bi-record2-fill::before { content: "\f51b"; } +.bi-record2::before { content: "\f51c"; } +.bi-reply-all-fill::before { content: "\f51d"; } +.bi-reply-all::before { content: "\f51e"; } +.bi-reply-fill::before { content: "\f51f"; } +.bi-reply::before { content: "\f520"; } +.bi-rss-fill::before { content: "\f521"; } +.bi-rss::before { content: "\f522"; } +.bi-rulers::before { content: "\f523"; } +.bi-save-fill::before { content: "\f524"; } +.bi-save::before { content: "\f525"; } +.bi-save2-fill::before { content: "\f526"; } +.bi-save2::before { content: "\f527"; } +.bi-scissors::before { content: "\f528"; } +.bi-screwdriver::before { content: "\f529"; } +.bi-search::before { content: "\f52a"; } +.bi-segmented-nav::before { content: "\f52b"; } +.bi-server::before { content: "\f52c"; } +.bi-share-fill::before { content: "\f52d"; } +.bi-share::before { content: "\f52e"; } +.bi-shield-check::before { content: "\f52f"; } +.bi-shield-exclamation::before { content: "\f530"; } +.bi-shield-fill-check::before { content: "\f531"; } +.bi-shield-fill-exclamation::before { content: "\f532"; } +.bi-shield-fill-minus::before { content: "\f533"; } +.bi-shield-fill-plus::before { content: "\f534"; } +.bi-shield-fill-x::before { content: "\f535"; } +.bi-shield-fill::before { content: "\f536"; } +.bi-shield-lock-fill::before { content: "\f537"; } +.bi-shield-lock::before { content: "\f538"; } +.bi-shield-minus::before { content: "\f539"; } +.bi-shield-plus::before { content: "\f53a"; } +.bi-shield-shaded::before { content: "\f53b"; } +.bi-shield-slash-fill::before { content: "\f53c"; } +.bi-shield-slash::before { content: "\f53d"; } +.bi-shield-x::before { content: "\f53e"; } +.bi-shield::before { content: "\f53f"; } +.bi-shift-fill::before { content: "\f540"; } +.bi-shift::before { content: "\f541"; } +.bi-shop-window::before { content: "\f542"; } +.bi-shop::before { content: "\f543"; } +.bi-shuffle::before { content: "\f544"; } +.bi-signpost-2-fill::before { content: "\f545"; } +.bi-signpost-2::before { content: "\f546"; } +.bi-signpost-fill::before { content: "\f547"; } +.bi-signpost-split-fill::before { content: "\f548"; } +.bi-signpost-split::before { content: "\f549"; } +.bi-signpost::before { content: "\f54a"; } +.bi-sim-fill::before { content: "\f54b"; } +.bi-sim::before { content: "\f54c"; } +.bi-skip-backward-btn-fill::before { content: "\f54d"; } +.bi-skip-backward-btn::before { content: "\f54e"; } +.bi-skip-backward-circle-fill::before { content: "\f54f"; } +.bi-skip-backward-circle::before { content: "\f550"; } +.bi-skip-backward-fill::before { content: "\f551"; } +.bi-skip-backward::before { content: "\f552"; } +.bi-skip-end-btn-fill::before { content: "\f553"; } +.bi-skip-end-btn::before { content: "\f554"; } +.bi-skip-end-circle-fill::before { content: "\f555"; } +.bi-skip-end-circle::before { content: "\f556"; } +.bi-skip-end-fill::before { content: "\f557"; } +.bi-skip-end::before { content: "\f558"; } +.bi-skip-forward-btn-fill::before { content: "\f559"; } +.bi-skip-forward-btn::before { content: "\f55a"; } +.bi-skip-forward-circle-fill::before { content: "\f55b"; } +.bi-skip-forward-circle::before { content: "\f55c"; } +.bi-skip-forward-fill::before { content: "\f55d"; } +.bi-skip-forward::before { content: "\f55e"; } +.bi-skip-start-btn-fill::before { content: "\f55f"; } +.bi-skip-start-btn::before { content: "\f560"; } +.bi-skip-start-circle-fill::before { content: "\f561"; } +.bi-skip-start-circle::before { content: "\f562"; } +.bi-skip-start-fill::before { content: "\f563"; } +.bi-skip-start::before { content: "\f564"; } +.bi-slack::before { content: "\f565"; } +.bi-slash-circle-fill::before { content: "\f566"; } +.bi-slash-circle::before { content: "\f567"; } +.bi-slash-square-fill::before { content: "\f568"; } +.bi-slash-square::before { content: "\f569"; } +.bi-slash::before { content: "\f56a"; } +.bi-sliders::before { content: "\f56b"; } +.bi-smartwatch::before { content: "\f56c"; } +.bi-snow::before { content: "\f56d"; } +.bi-snow2::before { content: "\f56e"; } +.bi-snow3::before { content: "\f56f"; } +.bi-sort-alpha-down-alt::before { content: "\f570"; } +.bi-sort-alpha-down::before { content: "\f571"; } +.bi-sort-alpha-up-alt::before { content: "\f572"; } +.bi-sort-alpha-up::before { content: "\f573"; } +.bi-sort-down-alt::before { content: "\f574"; } +.bi-sort-down::before { content: "\f575"; } +.bi-sort-numeric-down-alt::before { content: "\f576"; } +.bi-sort-numeric-down::before { content: "\f577"; } +.bi-sort-numeric-up-alt::before { content: "\f578"; } +.bi-sort-numeric-up::before { content: "\f579"; } +.bi-sort-up-alt::before { content: "\f57a"; } +.bi-sort-up::before { content: "\f57b"; } +.bi-soundwave::before { content: "\f57c"; } +.bi-speaker-fill::before { content: "\f57d"; } +.bi-speaker::before { content: "\f57e"; } +.bi-speedometer::before { content: "\f57f"; } +.bi-speedometer2::before { content: "\f580"; } +.bi-spellcheck::before { content: "\f581"; } +.bi-square-fill::before { content: "\f582"; } +.bi-square-half::before { content: "\f583"; } +.bi-square::before { content: "\f584"; } +.bi-stack::before { content: "\f585"; } +.bi-star-fill::before { content: "\f586"; } +.bi-star-half::before { content: "\f587"; } +.bi-star::before { content: "\f588"; } +.bi-stars::before { content: "\f589"; } +.bi-stickies-fill::before { content: "\f58a"; } +.bi-stickies::before { content: "\f58b"; } +.bi-sticky-fill::before { content: "\f58c"; } +.bi-sticky::before { content: "\f58d"; } +.bi-stop-btn-fill::before { content: "\f58e"; } +.bi-stop-btn::before { content: "\f58f"; } +.bi-stop-circle-fill::before { content: "\f590"; } +.bi-stop-circle::before { content: "\f591"; } +.bi-stop-fill::before { content: "\f592"; } +.bi-stop::before { content: "\f593"; } +.bi-stoplights-fill::before { content: "\f594"; } +.bi-stoplights::before { content: "\f595"; } +.bi-stopwatch-fill::before { content: "\f596"; } +.bi-stopwatch::before { content: "\f597"; } +.bi-subtract::before { content: "\f598"; } +.bi-suit-club-fill::before { content: "\f599"; } +.bi-suit-club::before { content: "\f59a"; } +.bi-suit-diamond-fill::before { content: "\f59b"; } +.bi-suit-diamond::before { content: "\f59c"; } +.bi-suit-heart-fill::before { content: "\f59d"; } +.bi-suit-heart::before { content: "\f59e"; } +.bi-suit-spade-fill::before { content: "\f59f"; } +.bi-suit-spade::before { content: "\f5a0"; } +.bi-sun-fill::before { content: "\f5a1"; } +.bi-sun::before { content: "\f5a2"; } +.bi-sunglasses::before { content: "\f5a3"; } +.bi-sunrise-fill::before { content: "\f5a4"; } +.bi-sunrise::before { content: "\f5a5"; } +.bi-sunset-fill::before { content: "\f5a6"; } +.bi-sunset::before { content: "\f5a7"; } +.bi-symmetry-horizontal::before { content: "\f5a8"; } +.bi-symmetry-vertical::before { content: "\f5a9"; } +.bi-table::before { content: "\f5aa"; } +.bi-tablet-fill::before { content: "\f5ab"; } +.bi-tablet-landscape-fill::before { content: "\f5ac"; } +.bi-tablet-landscape::before { content: "\f5ad"; } +.bi-tablet::before { content: "\f5ae"; } +.bi-tag-fill::before { content: "\f5af"; } +.bi-tag::before { content: "\f5b0"; } +.bi-tags-fill::before { content: "\f5b1"; } +.bi-tags::before { content: "\f5b2"; } +.bi-telegram::before { content: "\f5b3"; } +.bi-telephone-fill::before { content: "\f5b4"; } +.bi-telephone-forward-fill::before { content: "\f5b5"; } +.bi-telephone-forward::before { content: "\f5b6"; } +.bi-telephone-inbound-fill::before { content: "\f5b7"; } +.bi-telephone-inbound::before { content: "\f5b8"; } +.bi-telephone-minus-fill::before { content: "\f5b9"; } +.bi-telephone-minus::before { content: "\f5ba"; } +.bi-telephone-outbound-fill::before { content: "\f5bb"; } +.bi-telephone-outbound::before { content: "\f5bc"; } +.bi-telephone-plus-fill::before { content: "\f5bd"; } +.bi-telephone-plus::before { content: "\f5be"; } +.bi-telephone-x-fill::before { content: "\f5bf"; } +.bi-telephone-x::before { content: "\f5c0"; } +.bi-telephone::before { content: "\f5c1"; } +.bi-terminal-fill::before { content: "\f5c2"; } +.bi-terminal::before { content: "\f5c3"; } +.bi-text-center::before { content: "\f5c4"; } +.bi-text-indent-left::before { content: "\f5c5"; } +.bi-text-indent-right::before { content: "\f5c6"; } +.bi-text-left::before { content: "\f5c7"; } +.bi-text-paragraph::before { content: "\f5c8"; } +.bi-text-right::before { content: "\f5c9"; } +.bi-textarea-resize::before { content: "\f5ca"; } +.bi-textarea-t::before { content: "\f5cb"; } +.bi-textarea::before { content: "\f5cc"; } +.bi-thermometer-half::before { content: "\f5cd"; } +.bi-thermometer-high::before { content: "\f5ce"; } +.bi-thermometer-low::before { content: "\f5cf"; } +.bi-thermometer-snow::before { content: "\f5d0"; } +.bi-thermometer-sun::before { content: "\f5d1"; } +.bi-thermometer::before { content: "\f5d2"; } +.bi-three-dots-vertical::before { content: "\f5d3"; } +.bi-three-dots::before { content: "\f5d4"; } +.bi-toggle-off::before { content: "\f5d5"; } +.bi-toggle-on::before { content: "\f5d6"; } +.bi-toggle2-off::before { content: "\f5d7"; } +.bi-toggle2-on::before { content: "\f5d8"; } +.bi-toggles::before { content: "\f5d9"; } +.bi-toggles2::before { content: "\f5da"; } +.bi-tools::before { content: "\f5db"; } +.bi-tornado::before { content: "\f5dc"; } +.bi-trash-fill::before { content: "\f5dd"; } +.bi-trash::before { content: "\f5de"; } +.bi-trash2-fill::before { content: "\f5df"; } +.bi-trash2::before { content: "\f5e0"; } +.bi-tree-fill::before { content: "\f5e1"; } +.bi-tree::before { content: "\f5e2"; } +.bi-triangle-fill::before { content: "\f5e3"; } +.bi-triangle-half::before { content: "\f5e4"; } +.bi-triangle::before { content: "\f5e5"; } +.bi-trophy-fill::before { content: "\f5e6"; } +.bi-trophy::before { content: "\f5e7"; } +.bi-tropical-storm::before { content: "\f5e8"; } +.bi-truck-flatbed::before { content: "\f5e9"; } +.bi-truck::before { content: "\f5ea"; } +.bi-tsunami::before { content: "\f5eb"; } +.bi-tv-fill::before { content: "\f5ec"; } +.bi-tv::before { content: "\f5ed"; } +.bi-twitch::before { content: "\f5ee"; } +.bi-twitter::before { content: "\f5ef"; } +.bi-type-bold::before { content: "\f5f0"; } +.bi-type-h1::before { content: "\f5f1"; } +.bi-type-h2::before { content: "\f5f2"; } +.bi-type-h3::before { content: "\f5f3"; } +.bi-type-italic::before { content: "\f5f4"; } +.bi-type-strikethrough::before { content: "\f5f5"; } +.bi-type-underline::before { content: "\f5f6"; } +.bi-type::before { content: "\f5f7"; } +.bi-ui-checks-grid::before { content: "\f5f8"; } +.bi-ui-checks::before { content: "\f5f9"; } +.bi-ui-radios-grid::before { content: "\f5fa"; } +.bi-ui-radios::before { content: "\f5fb"; } +.bi-umbrella-fill::before { content: "\f5fc"; } +.bi-umbrella::before { content: "\f5fd"; } +.bi-union::before { content: "\f5fe"; } +.bi-unlock-fill::before { content: "\f5ff"; } +.bi-unlock::before { content: "\f600"; } +.bi-upc-scan::before { content: "\f601"; } +.bi-upc::before { content: "\f602"; } +.bi-upload::before { content: "\f603"; } +.bi-vector-pen::before { content: "\f604"; } +.bi-view-list::before { content: "\f605"; } +.bi-view-stacked::before { content: "\f606"; } +.bi-vinyl-fill::before { content: "\f607"; } +.bi-vinyl::before { content: "\f608"; } +.bi-voicemail::before { content: "\f609"; } +.bi-volume-down-fill::before { content: "\f60a"; } +.bi-volume-down::before { content: "\f60b"; } +.bi-volume-mute-fill::before { content: "\f60c"; } +.bi-volume-mute::before { content: "\f60d"; } +.bi-volume-off-fill::before { content: "\f60e"; } +.bi-volume-off::before { content: "\f60f"; } +.bi-volume-up-fill::before { content: "\f610"; } +.bi-volume-up::before { content: "\f611"; } +.bi-vr::before { content: "\f612"; } +.bi-wallet-fill::before { content: "\f613"; } +.bi-wallet::before { content: "\f614"; } +.bi-wallet2::before { content: "\f615"; } +.bi-watch::before { content: "\f616"; } +.bi-water::before { content: "\f617"; } +.bi-whatsapp::before { content: "\f618"; } +.bi-wifi-1::before { content: "\f619"; } +.bi-wifi-2::before { content: "\f61a"; } +.bi-wifi-off::before { content: "\f61b"; } +.bi-wifi::before { content: "\f61c"; } +.bi-wind::before { content: "\f61d"; } +.bi-window-dock::before { content: "\f61e"; } +.bi-window-sidebar::before { content: "\f61f"; } +.bi-window::before { content: "\f620"; } +.bi-wrench::before { content: "\f621"; } +.bi-x-circle-fill::before { content: "\f622"; } +.bi-x-circle::before { content: "\f623"; } +.bi-x-diamond-fill::before { content: "\f624"; } +.bi-x-diamond::before { content: "\f625"; } +.bi-x-octagon-fill::before { content: "\f626"; } +.bi-x-octagon::before { content: "\f627"; } +.bi-x-square-fill::before { content: "\f628"; } +.bi-x-square::before { content: "\f629"; } +.bi-x::before { content: "\f62a"; } +.bi-youtube::before { content: "\f62b"; } +.bi-zoom-in::before { content: "\f62c"; } +.bi-zoom-out::before { content: "\f62d"; } +.bi-bank::before { content: "\f62e"; } +.bi-bank2::before { content: "\f62f"; } +.bi-bell-slash-fill::before { content: "\f630"; } +.bi-bell-slash::before { content: "\f631"; } +.bi-cash-coin::before { content: "\f632"; } +.bi-check-lg::before { content: "\f633"; } +.bi-coin::before { content: "\f634"; } +.bi-currency-bitcoin::before { content: "\f635"; } +.bi-currency-dollar::before { content: "\f636"; } +.bi-currency-euro::before { content: "\f637"; } +.bi-currency-exchange::before { content: "\f638"; } +.bi-currency-pound::before { content: "\f639"; } +.bi-currency-yen::before { content: "\f63a"; } +.bi-dash-lg::before { content: "\f63b"; } +.bi-exclamation-lg::before { content: "\f63c"; } +.bi-file-earmark-pdf-fill::before { content: "\f63d"; } +.bi-file-earmark-pdf::before { content: "\f63e"; } +.bi-file-pdf-fill::before { content: "\f63f"; } +.bi-file-pdf::before { content: "\f640"; } +.bi-gender-ambiguous::before { content: "\f641"; } +.bi-gender-female::before { content: "\f642"; } +.bi-gender-male::before { content: "\f643"; } +.bi-gender-trans::before { content: "\f644"; } +.bi-headset-vr::before { content: "\f645"; } +.bi-info-lg::before { content: "\f646"; } +.bi-mastodon::before { content: "\f647"; } +.bi-messenger::before { content: "\f648"; } +.bi-piggy-bank-fill::before { content: "\f649"; } +.bi-piggy-bank::before { content: "\f64a"; } +.bi-pin-map-fill::before { content: "\f64b"; } +.bi-pin-map::before { content: "\f64c"; } +.bi-plus-lg::before { content: "\f64d"; } +.bi-question-lg::before { content: "\f64e"; } +.bi-recycle::before { content: "\f64f"; } +.bi-reddit::before { content: "\f650"; } +.bi-safe-fill::before { content: "\f651"; } +.bi-safe2-fill::before { content: "\f652"; } +.bi-safe2::before { content: "\f653"; } +.bi-sd-card-fill::before { content: "\f654"; } +.bi-sd-card::before { content: "\f655"; } +.bi-skype::before { content: "\f656"; } +.bi-slash-lg::before { content: "\f657"; } +.bi-translate::before { content: "\f658"; } +.bi-x-lg::before { content: "\f659"; } +.bi-safe::before { content: "\f65a"; } +.bi-apple::before { content: "\f65b"; } +.bi-microsoft::before { content: "\f65d"; } +.bi-windows::before { content: "\f65e"; } +.bi-behance::before { content: "\f65c"; } +.bi-dribbble::before { content: "\f65f"; } +.bi-line::before { content: "\f660"; } +.bi-medium::before { content: "\f661"; } +.bi-paypal::before { content: "\f662"; } +.bi-pinterest::before { content: "\f663"; } +.bi-signal::before { content: "\f664"; } +.bi-snapchat::before { content: "\f665"; } +.bi-spotify::before { content: "\f666"; } +.bi-stack-overflow::before { content: "\f667"; } +.bi-strava::before { content: "\f668"; } +.bi-wordpress::before { content: "\f669"; } +.bi-vimeo::before { content: "\f66a"; } +.bi-activity::before { content: "\f66b"; } +.bi-easel2-fill::before { content: "\f66c"; } +.bi-easel2::before { content: "\f66d"; } +.bi-easel3-fill::before { content: "\f66e"; } +.bi-easel3::before { content: "\f66f"; } +.bi-fan::before { content: "\f670"; } +.bi-fingerprint::before { content: "\f671"; } +.bi-graph-down-arrow::before { content: "\f672"; } +.bi-graph-up-arrow::before { content: "\f673"; } +.bi-hypnotize::before { content: "\f674"; } +.bi-magic::before { content: "\f675"; } +.bi-person-rolodex::before { content: "\f676"; } +.bi-person-video::before { content: "\f677"; } +.bi-person-video2::before { content: "\f678"; } +.bi-person-video3::before { content: "\f679"; } +.bi-person-workspace::before { content: "\f67a"; } +.bi-radioactive::before { content: "\f67b"; } +.bi-webcam-fill::before { content: "\f67c"; } +.bi-webcam::before { content: "\f67d"; } +.bi-yin-yang::before { content: "\f67e"; } +.bi-bandaid-fill::before { content: "\f680"; } +.bi-bandaid::before { content: "\f681"; } +.bi-bluetooth::before { content: "\f682"; } +.bi-body-text::before { content: "\f683"; } +.bi-boombox::before { content: "\f684"; } +.bi-boxes::before { content: "\f685"; } +.bi-dpad-fill::before { content: "\f686"; } +.bi-dpad::before { content: "\f687"; } +.bi-ear-fill::before { content: "\f688"; } +.bi-ear::before { content: "\f689"; } +.bi-envelope-check-1::before { content: "\f68a"; } +.bi-envelope-check-fill::before { content: "\f68b"; } +.bi-envelope-check::before { content: "\f68c"; } +.bi-envelope-dash-1::before { content: "\f68d"; } +.bi-envelope-dash-fill::before { content: "\f68e"; } +.bi-envelope-dash::before { content: "\f68f"; } +.bi-envelope-exclamation-1::before { content: "\f690"; } +.bi-envelope-exclamation-fill::before { content: "\f691"; } +.bi-envelope-exclamation::before { content: "\f692"; } +.bi-envelope-plus-fill::before { content: "\f693"; } +.bi-envelope-plus::before { content: "\f694"; } +.bi-envelope-slash-1::before { content: "\f695"; } +.bi-envelope-slash-fill::before { content: "\f696"; } +.bi-envelope-slash::before { content: "\f697"; } +.bi-envelope-x-1::before { content: "\f698"; } +.bi-envelope-x-fill::before { content: "\f699"; } +.bi-envelope-x::before { content: "\f69a"; } +.bi-explicit-fill::before { content: "\f69b"; } +.bi-explicit::before { content: "\f69c"; } +.bi-git::before { content: "\f69d"; } +.bi-infinity::before { content: "\f69e"; } +.bi-list-columns-reverse::before { content: "\f69f"; } +.bi-list-columns::before { content: "\f6a0"; } +.bi-meta::before { content: "\f6a1"; } +.bi-mortorboard-fill::before { content: "\f6a2"; } +.bi-mortorboard::before { content: "\f6a3"; } +.bi-nintendo-switch::before { content: "\f6a4"; } +.bi-pc-display-horizontal::before { content: "\f6a5"; } +.bi-pc-display::before { content: "\f6a6"; } +.bi-pc-horizontal::before { content: "\f6a7"; } +.bi-pc::before { content: "\f6a8"; } +.bi-playstation::before { content: "\f6a9"; } +.bi-plus-slash-minus::before { content: "\f6aa"; } +.bi-projector-fill::before { content: "\f6ab"; } +.bi-projector::before { content: "\f6ac"; } +.bi-qr-code-scan::before { content: "\f6ad"; } +.bi-qr-code::before { content: "\f6ae"; } +.bi-quora::before { content: "\f6af"; } +.bi-quote::before { content: "\f6b0"; } +.bi-robot::before { content: "\f6b1"; } +.bi-send-check-fill::before { content: "\f6b2"; } +.bi-send-check::before { content: "\f6b3"; } +.bi-send-dash-fill::before { content: "\f6b4"; } +.bi-send-dash::before { content: "\f6b5"; } +.bi-send-exclamation-1::before { content: "\f6b6"; } +.bi-send-exclamation-fill::before { content: "\f6b7"; } +.bi-send-exclamation::before { content: "\f6b8"; } +.bi-send-fill::before { content: "\f6b9"; } +.bi-send-plus-fill::before { content: "\f6ba"; } +.bi-send-plus::before { content: "\f6bb"; } +.bi-send-slash-fill::before { content: "\f6bc"; } +.bi-send-slash::before { content: "\f6bd"; } +.bi-send-x-fill::before { content: "\f6be"; } +.bi-send-x::before { content: "\f6bf"; } +.bi-send::before { content: "\f6c0"; } +.bi-steam::before { content: "\f6c1"; } +.bi-terminal-dash-1::before { content: "\f6c2"; } +.bi-terminal-dash::before { content: "\f6c3"; } +.bi-terminal-plus::before { content: "\f6c4"; } +.bi-terminal-split::before { content: "\f6c5"; } +.bi-ticket-detailed-fill::before { content: "\f6c6"; } +.bi-ticket-detailed::before { content: "\f6c7"; } +.bi-ticket-fill::before { content: "\f6c8"; } +.bi-ticket-perforated-fill::before { content: "\f6c9"; } +.bi-ticket-perforated::before { content: "\f6ca"; } +.bi-ticket::before { content: "\f6cb"; } +.bi-tiktok::before { content: "\f6cc"; } +.bi-window-dash::before { content: "\f6cd"; } +.bi-window-desktop::before { content: "\f6ce"; } +.bi-window-fullscreen::before { content: "\f6cf"; } +.bi-window-plus::before { content: "\f6d0"; } +.bi-window-split::before { content: "\f6d1"; } +.bi-window-stack::before { content: "\f6d2"; } +.bi-window-x::before { content: "\f6d3"; } +.bi-xbox::before { content: "\f6d4"; } +.bi-ethernet::before { content: "\f6d5"; } +.bi-hdmi-fill::before { content: "\f6d6"; } +.bi-hdmi::before { content: "\f6d7"; } +.bi-usb-c-fill::before { content: "\f6d8"; } +.bi-usb-c::before { content: "\f6d9"; } +.bi-usb-fill::before { content: "\f6da"; } +.bi-usb-plug-fill::before { content: "\f6db"; } +.bi-usb-plug::before { content: "\f6dc"; } +.bi-usb-symbol::before { content: "\f6dd"; } +.bi-usb::before { content: "\f6de"; } +.bi-boombox-fill::before { content: "\f6df"; } +.bi-displayport-1::before { content: "\f6e0"; } +.bi-displayport::before { content: "\f6e1"; } +.bi-gpu-card::before { content: "\f6e2"; } +.bi-memory::before { content: "\f6e3"; } +.bi-modem-fill::before { content: "\f6e4"; } +.bi-modem::before { content: "\f6e5"; } +.bi-motherboard-fill::before { content: "\f6e6"; } +.bi-motherboard::before { content: "\f6e7"; } +.bi-optical-audio-fill::before { content: "\f6e8"; } +.bi-optical-audio::before { content: "\f6e9"; } +.bi-pci-card::before { content: "\f6ea"; } +.bi-router-fill::before { content: "\f6eb"; } +.bi-router::before { content: "\f6ec"; } +.bi-ssd-fill::before { content: "\f6ed"; } +.bi-ssd::before { content: "\f6ee"; } +.bi-thunderbolt-fill::before { content: "\f6ef"; } +.bi-thunderbolt::before { content: "\f6f0"; } +.bi-usb-drive-fill::before { content: "\f6f1"; } +.bi-usb-drive::before { content: "\f6f2"; } +.bi-usb-micro-fill::before { content: "\f6f3"; } +.bi-usb-micro::before { content: "\f6f4"; } +.bi-usb-mini-fill::before { content: "\f6f5"; } +.bi-usb-mini::before { content: "\f6f6"; } +.bi-cloud-haze2::before { content: "\f6f7"; } +.bi-device-hdd-fill::before { content: "\f6f8"; } +.bi-device-hdd::before { content: "\f6f9"; } +.bi-device-ssd-fill::before { content: "\f6fa"; } +.bi-device-ssd::before { content: "\f6fb"; } +.bi-displayport-fill::before { content: "\f6fc"; } +.bi-mortarboard-fill::before { content: "\f6fd"; } +.bi-mortarboard::before { content: "\f6fe"; } +.bi-terminal-x::before { content: "\f6ff"; } +.bi-arrow-through-heart-fill::before { content: "\f700"; } +.bi-arrow-through-heart::before { content: "\f701"; } +.bi-badge-sd-fill::before { content: "\f702"; } +.bi-badge-sd::before { content: "\f703"; } +.bi-bag-heart-fill::before { content: "\f704"; } +.bi-bag-heart::before { content: "\f705"; } +.bi-balloon-fill::before { content: "\f706"; } +.bi-balloon-heart-fill::before { content: "\f707"; } +.bi-balloon-heart::before { content: "\f708"; } +.bi-balloon::before { content: "\f709"; } +.bi-box2-fill::before { content: "\f70a"; } +.bi-box2-heart-fill::before { content: "\f70b"; } +.bi-box2-heart::before { content: "\f70c"; } +.bi-box2::before { content: "\f70d"; } +.bi-braces-asterisk::before { content: "\f70e"; } +.bi-calendar-heart-fill::before { content: "\f70f"; } +.bi-calendar-heart::before { content: "\f710"; } +.bi-calendar2-heart-fill::before { content: "\f711"; } +.bi-calendar2-heart::before { content: "\f712"; } +.bi-chat-heart-fill::before { content: "\f713"; } +.bi-chat-heart::before { content: "\f714"; } +.bi-chat-left-heart-fill::before { content: "\f715"; } +.bi-chat-left-heart::before { content: "\f716"; } +.bi-chat-right-heart-fill::before { content: "\f717"; } +.bi-chat-right-heart::before { content: "\f718"; } +.bi-chat-square-heart-fill::before { content: "\f719"; } +.bi-chat-square-heart::before { content: "\f71a"; } +.bi-clipboard-check-fill::before { content: "\f71b"; } +.bi-clipboard-data-fill::before { content: "\f71c"; } +.bi-clipboard-fill::before { content: "\f71d"; } +.bi-clipboard-heart-fill::before { content: "\f71e"; } +.bi-clipboard-heart::before { content: "\f71f"; } +.bi-clipboard-minus-fill::before { content: "\f720"; } +.bi-clipboard-plus-fill::before { content: "\f721"; } +.bi-clipboard-pulse::before { content: "\f722"; } +.bi-clipboard-x-fill::before { content: "\f723"; } +.bi-clipboard2-check-fill::before { content: "\f724"; } +.bi-clipboard2-check::before { content: "\f725"; } +.bi-clipboard2-data-fill::before { content: "\f726"; } +.bi-clipboard2-data::before { content: "\f727"; } +.bi-clipboard2-fill::before { content: "\f728"; } +.bi-clipboard2-heart-fill::before { content: "\f729"; } +.bi-clipboard2-heart::before { content: "\f72a"; } +.bi-clipboard2-minus-fill::before { content: "\f72b"; } +.bi-clipboard2-minus::before { content: "\f72c"; } +.bi-clipboard2-plus-fill::before { content: "\f72d"; } +.bi-clipboard2-plus::before { content: "\f72e"; } +.bi-clipboard2-pulse-fill::before { content: "\f72f"; } +.bi-clipboard2-pulse::before { content: "\f730"; } +.bi-clipboard2-x-fill::before { content: "\f731"; } +.bi-clipboard2-x::before { content: "\f732"; } +.bi-clipboard2::before { content: "\f733"; } +.bi-emoji-kiss-fill::before { content: "\f734"; } +.bi-emoji-kiss::before { content: "\f735"; } +.bi-envelope-heart-fill::before { content: "\f736"; } +.bi-envelope-heart::before { content: "\f737"; } +.bi-envelope-open-heart-fill::before { content: "\f738"; } +.bi-envelope-open-heart::before { content: "\f739"; } +.bi-envelope-paper-fill::before { content: "\f73a"; } +.bi-envelope-paper-heart-fill::before { content: "\f73b"; } +.bi-envelope-paper-heart::before { content: "\f73c"; } +.bi-envelope-paper::before { content: "\f73d"; } +.bi-filetype-aac::before { content: "\f73e"; } +.bi-filetype-ai::before { content: "\f73f"; } +.bi-filetype-bmp::before { content: "\f740"; } +.bi-filetype-cs::before { content: "\f741"; } +.bi-filetype-css::before { content: "\f742"; } +.bi-filetype-csv::before { content: "\f743"; } +.bi-filetype-doc::before { content: "\f744"; } +.bi-filetype-docx::before { content: "\f745"; } +.bi-filetype-exe::before { content: "\f746"; } +.bi-filetype-gif::before { content: "\f747"; } +.bi-filetype-heic::before { content: "\f748"; } +.bi-filetype-html::before { content: "\f749"; } +.bi-filetype-java::before { content: "\f74a"; } +.bi-filetype-jpg::before { content: "\f74b"; } +.bi-filetype-js::before { content: "\f74c"; } +.bi-filetype-jsx::before { content: "\f74d"; } +.bi-filetype-key::before { content: "\f74e"; } +.bi-filetype-m4p::before { content: "\f74f"; } +.bi-filetype-md::before { content: "\f750"; } +.bi-filetype-mdx::before { content: "\f751"; } +.bi-filetype-mov::before { content: "\f752"; } +.bi-filetype-mp3::before { content: "\f753"; } +.bi-filetype-mp4::before { content: "\f754"; } +.bi-filetype-otf::before { content: "\f755"; } +.bi-filetype-pdf::before { content: "\f756"; } +.bi-filetype-php::before { content: "\f757"; } +.bi-filetype-png::before { content: "\f758"; } +.bi-filetype-ppt-1::before { content: "\f759"; } +.bi-filetype-ppt::before { content: "\f75a"; } +.bi-filetype-psd::before { content: "\f75b"; } +.bi-filetype-py::before { content: "\f75c"; } +.bi-filetype-raw::before { content: "\f75d"; } +.bi-filetype-rb::before { content: "\f75e"; } +.bi-filetype-sass::before { content: "\f75f"; } +.bi-filetype-scss::before { content: "\f760"; } +.bi-filetype-sh::before { content: "\f761"; } +.bi-filetype-svg::before { content: "\f762"; } +.bi-filetype-tiff::before { content: "\f763"; } +.bi-filetype-tsx::before { content: "\f764"; } +.bi-filetype-ttf::before { content: "\f765"; } +.bi-filetype-txt::before { content: "\f766"; } +.bi-filetype-wav::before { content: "\f767"; } +.bi-filetype-woff::before { content: "\f768"; } +.bi-filetype-xls-1::before { content: "\f769"; } +.bi-filetype-xls::before { content: "\f76a"; } +.bi-filetype-xml::before { content: "\f76b"; } +.bi-filetype-yml::before { content: "\f76c"; } +.bi-heart-arrow::before { content: "\f76d"; } +.bi-heart-pulse-fill::before { content: "\f76e"; } +.bi-heart-pulse::before { content: "\f76f"; } +.bi-heartbreak-fill::before { content: "\f770"; } +.bi-heartbreak::before { content: "\f771"; } +.bi-hearts::before { content: "\f772"; } +.bi-hospital-fill::before { content: "\f773"; } +.bi-hospital::before { content: "\f774"; } +.bi-house-heart-fill::before { content: "\f775"; } +.bi-house-heart::before { content: "\f776"; } +.bi-incognito::before { content: "\f777"; } +.bi-magnet-fill::before { content: "\f778"; } +.bi-magnet::before { content: "\f779"; } +.bi-person-heart::before { content: "\f77a"; } +.bi-person-hearts::before { content: "\f77b"; } +.bi-phone-flip::before { content: "\f77c"; } +.bi-plugin::before { content: "\f77d"; } +.bi-postage-fill::before { content: "\f77e"; } +.bi-postage-heart-fill::before { content: "\f77f"; } +.bi-postage-heart::before { content: "\f780"; } +.bi-postage::before { content: "\f781"; } +.bi-postcard-fill::before { content: "\f782"; } +.bi-postcard-heart-fill::before { content: "\f783"; } +.bi-postcard-heart::before { content: "\f784"; } +.bi-postcard::before { content: "\f785"; } +.bi-search-heart-fill::before { content: "\f786"; } +.bi-search-heart::before { content: "\f787"; } +.bi-sliders2-vertical::before { content: "\f788"; } +.bi-sliders2::before { content: "\f789"; } +.bi-trash3-fill::before { content: "\f78a"; } +.bi-trash3::before { content: "\f78b"; } +.bi-valentine::before { content: "\f78c"; } +.bi-valentine2::before { content: "\f78d"; } +.bi-wrench-adjustable-circle-fill::before { content: "\f78e"; } +.bi-wrench-adjustable-circle::before { content: "\f78f"; } +.bi-wrench-adjustable::before { content: "\f790"; } +.bi-filetype-json::before { content: "\f791"; } +.bi-filetype-pptx::before { content: "\f792"; } +.bi-filetype-xlsx::before { content: "\f793"; } diff --git a/docs/site_libs/bootstrap/bootstrap-icons.woff b/docs/site_libs/bootstrap/bootstrap-icons.woff new file mode 100644 index 0000000..b26ccd1 Binary files /dev/null and b/docs/site_libs/bootstrap/bootstrap-icons.woff differ diff --git a/docs/site_libs/bootstrap/bootstrap.min.css b/docs/site_libs/bootstrap/bootstrap.min.css new file mode 100644 index 0000000..660b489 --- /dev/null +++ b/docs/site_libs/bootstrap/bootstrap.min.css @@ -0,0 +1,10 @@ +/*! + * Bootstrap v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */@import"https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap";:root{--bs-blue: #2c3e50;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #e83e8c;--bs-red: #e74c3c;--bs-orange: #fd7e14;--bs-yellow: #f39c12;--bs-green: #18bc9c;--bs-teal: #20c997;--bs-cyan: #3498db;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #ecf0f1;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #7b8a8b;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-default: #6c757d;--bs-primary: #2c3e50;--bs-secondary: #6c757d;--bs-success: #18bc9c;--bs-info: #3498db;--bs-warning: #f39c12;--bs-danger: #e74c3c;--bs-light: #ecf0f1;--bs-dark: #7b8a8b;--bs-default-rgb: 108, 117, 125;--bs-primary-rgb: 44, 62, 80;--bs-secondary-rgb: 108, 117, 125;--bs-success-rgb: 24, 188, 156;--bs-info-rgb: 52, 152, 219;--bs-warning-rgb: 243, 156, 18;--bs-danger-rgb: 231, 76, 60;--bs-light-rgb: 236, 240, 241;--bs-dark-rgb: 123, 138, 139;--bs-white-rgb: 255, 255, 255;--bs-black-rgb: 0, 0, 0;--bs-body-color-rgb: 33, 37, 41;--bs-body-bg-rgb: 255, 255, 255;--bs-font-sans-serif: Lato, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-root-font-size: 18px;--bs-body-font-family: var(--bs-font-sans-serif);--bs-body-font-size: 1rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}*,*::before,*::after{box-sizing:border-box}:root{font-size:var(--bs-root-font-size)}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h6,.h6,h5,.h5,h4,.h4,h3,.h3,h2,.h2,h1,.h1{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1,.h1{font-size:calc(1.345rem + 1.14vw)}@media(min-width: 1200px){h1,.h1{font-size:2.2rem}}h2,.h2{font-size:calc(1.3rem + 0.6vw)}@media(min-width: 1200px){h2,.h2{font-size:1.75rem}}h3,.h3{font-size:calc(1.275rem + 0.3vw)}@media(min-width: 1200px){h3,.h3{font-size:1.5rem}}h4,.h4{font-size:1.25rem}h5,.h5{font-size:1.1rem}h6,.h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-bs-original-title]{text-decoration:underline dotted;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;-ms-text-decoration:underline dotted;-o-text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem;padding:.625rem 1.25rem;border-left:.25rem solid #ecf0f1}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}b,strong{font-weight:bolder}small,.small{font-size:0.875em}mark,.mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:0.75em;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}a{color:#18bc9c;text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}a:hover{color:#13967d}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr /* rtl:ignore */;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:0.875em;color:#000;background-color:#f6f6f6;padding:.5rem;border:1px solid #dee2e6;border-radius:.25rem}pre code{background-color:transparent;font-size:inherit;color:inherit;word-break:normal}code{font-size:0.875em;color:#9753b8;background-color:#f6f6f6;border-radius:.25rem;padding:.125rem .25rem;word-wrap:break-word}a>code{color:inherit}kbd{padding:.4rem .4rem;font-size:0.875em;color:#fff;background-color:#212529;border-radius:.2em}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button:not(:disabled),[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + 0.3vw);line-height:inherit}@media(min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:0.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:0.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:0.875em;color:#6c757d}.grid{display:grid;grid-template-rows:repeat(var(--bs-rows, 1), 1fr);grid-template-columns:repeat(var(--bs-columns, 12), 1fr);gap:var(--bs-gap, 1.5rem)}.grid .g-col-1{grid-column:auto/span 1}.grid .g-col-2{grid-column:auto/span 2}.grid .g-col-3{grid-column:auto/span 3}.grid .g-col-4{grid-column:auto/span 4}.grid .g-col-5{grid-column:auto/span 5}.grid .g-col-6{grid-column:auto/span 6}.grid .g-col-7{grid-column:auto/span 7}.grid .g-col-8{grid-column:auto/span 8}.grid .g-col-9{grid-column:auto/span 9}.grid .g-col-10{grid-column:auto/span 10}.grid .g-col-11{grid-column:auto/span 11}.grid .g-col-12{grid-column:auto/span 12}.grid .g-start-1{grid-column-start:1}.grid .g-start-2{grid-column-start:2}.grid .g-start-3{grid-column-start:3}.grid .g-start-4{grid-column-start:4}.grid .g-start-5{grid-column-start:5}.grid .g-start-6{grid-column-start:6}.grid .g-start-7{grid-column-start:7}.grid .g-start-8{grid-column-start:8}.grid .g-start-9{grid-column-start:9}.grid .g-start-10{grid-column-start:10}.grid .g-start-11{grid-column-start:11}@media(min-width: 576px){.grid .g-col-sm-1{grid-column:auto/span 1}.grid .g-col-sm-2{grid-column:auto/span 2}.grid .g-col-sm-3{grid-column:auto/span 3}.grid .g-col-sm-4{grid-column:auto/span 4}.grid .g-col-sm-5{grid-column:auto/span 5}.grid .g-col-sm-6{grid-column:auto/span 6}.grid .g-col-sm-7{grid-column:auto/span 7}.grid .g-col-sm-8{grid-column:auto/span 8}.grid .g-col-sm-9{grid-column:auto/span 9}.grid .g-col-sm-10{grid-column:auto/span 10}.grid .g-col-sm-11{grid-column:auto/span 11}.grid .g-col-sm-12{grid-column:auto/span 12}.grid .g-start-sm-1{grid-column-start:1}.grid .g-start-sm-2{grid-column-start:2}.grid .g-start-sm-3{grid-column-start:3}.grid .g-start-sm-4{grid-column-start:4}.grid .g-start-sm-5{grid-column-start:5}.grid .g-start-sm-6{grid-column-start:6}.grid .g-start-sm-7{grid-column-start:7}.grid .g-start-sm-8{grid-column-start:8}.grid .g-start-sm-9{grid-column-start:9}.grid .g-start-sm-10{grid-column-start:10}.grid .g-start-sm-11{grid-column-start:11}}@media(min-width: 768px){.grid .g-col-md-1{grid-column:auto/span 1}.grid .g-col-md-2{grid-column:auto/span 2}.grid .g-col-md-3{grid-column:auto/span 3}.grid .g-col-md-4{grid-column:auto/span 4}.grid .g-col-md-5{grid-column:auto/span 5}.grid .g-col-md-6{grid-column:auto/span 6}.grid .g-col-md-7{grid-column:auto/span 7}.grid .g-col-md-8{grid-column:auto/span 8}.grid .g-col-md-9{grid-column:auto/span 9}.grid .g-col-md-10{grid-column:auto/span 10}.grid .g-col-md-11{grid-column:auto/span 11}.grid .g-col-md-12{grid-column:auto/span 12}.grid .g-start-md-1{grid-column-start:1}.grid .g-start-md-2{grid-column-start:2}.grid .g-start-md-3{grid-column-start:3}.grid .g-start-md-4{grid-column-start:4}.grid .g-start-md-5{grid-column-start:5}.grid .g-start-md-6{grid-column-start:6}.grid .g-start-md-7{grid-column-start:7}.grid .g-start-md-8{grid-column-start:8}.grid .g-start-md-9{grid-column-start:9}.grid .g-start-md-10{grid-column-start:10}.grid .g-start-md-11{grid-column-start:11}}@media(min-width: 992px){.grid .g-col-lg-1{grid-column:auto/span 1}.grid .g-col-lg-2{grid-column:auto/span 2}.grid .g-col-lg-3{grid-column:auto/span 3}.grid .g-col-lg-4{grid-column:auto/span 4}.grid .g-col-lg-5{grid-column:auto/span 5}.grid .g-col-lg-6{grid-column:auto/span 6}.grid .g-col-lg-7{grid-column:auto/span 7}.grid .g-col-lg-8{grid-column:auto/span 8}.grid .g-col-lg-9{grid-column:auto/span 9}.grid .g-col-lg-10{grid-column:auto/span 10}.grid .g-col-lg-11{grid-column:auto/span 11}.grid .g-col-lg-12{grid-column:auto/span 12}.grid .g-start-lg-1{grid-column-start:1}.grid .g-start-lg-2{grid-column-start:2}.grid .g-start-lg-3{grid-column-start:3}.grid .g-start-lg-4{grid-column-start:4}.grid .g-start-lg-5{grid-column-start:5}.grid .g-start-lg-6{grid-column-start:6}.grid .g-start-lg-7{grid-column-start:7}.grid .g-start-lg-8{grid-column-start:8}.grid .g-start-lg-9{grid-column-start:9}.grid .g-start-lg-10{grid-column-start:10}.grid .g-start-lg-11{grid-column-start:11}}@media(min-width: 1200px){.grid .g-col-xl-1{grid-column:auto/span 1}.grid .g-col-xl-2{grid-column:auto/span 2}.grid .g-col-xl-3{grid-column:auto/span 3}.grid .g-col-xl-4{grid-column:auto/span 4}.grid .g-col-xl-5{grid-column:auto/span 5}.grid .g-col-xl-6{grid-column:auto/span 6}.grid .g-col-xl-7{grid-column:auto/span 7}.grid .g-col-xl-8{grid-column:auto/span 8}.grid .g-col-xl-9{grid-column:auto/span 9}.grid .g-col-xl-10{grid-column:auto/span 10}.grid .g-col-xl-11{grid-column:auto/span 11}.grid .g-col-xl-12{grid-column:auto/span 12}.grid .g-start-xl-1{grid-column-start:1}.grid .g-start-xl-2{grid-column-start:2}.grid .g-start-xl-3{grid-column-start:3}.grid .g-start-xl-4{grid-column-start:4}.grid .g-start-xl-5{grid-column-start:5}.grid .g-start-xl-6{grid-column-start:6}.grid .g-start-xl-7{grid-column-start:7}.grid .g-start-xl-8{grid-column-start:8}.grid .g-start-xl-9{grid-column-start:9}.grid .g-start-xl-10{grid-column-start:10}.grid .g-start-xl-11{grid-column-start:11}}@media(min-width: 1400px){.grid .g-col-xxl-1{grid-column:auto/span 1}.grid .g-col-xxl-2{grid-column:auto/span 2}.grid .g-col-xxl-3{grid-column:auto/span 3}.grid .g-col-xxl-4{grid-column:auto/span 4}.grid .g-col-xxl-5{grid-column:auto/span 5}.grid .g-col-xxl-6{grid-column:auto/span 6}.grid .g-col-xxl-7{grid-column:auto/span 7}.grid .g-col-xxl-8{grid-column:auto/span 8}.grid .g-col-xxl-9{grid-column:auto/span 9}.grid .g-col-xxl-10{grid-column:auto/span 10}.grid .g-col-xxl-11{grid-column:auto/span 11}.grid .g-col-xxl-12{grid-column:auto/span 12}.grid .g-start-xxl-1{grid-column-start:1}.grid .g-start-xxl-2{grid-column-start:2}.grid .g-start-xxl-3{grid-column-start:3}.grid .g-start-xxl-4{grid-column-start:4}.grid .g-start-xxl-5{grid-column-start:5}.grid .g-start-xxl-6{grid-column-start:6}.grid .g-start-xxl-7{grid-column-start:7}.grid .g-start-xxl-8{grid-column-start:8}.grid .g-start-xxl-9{grid-column-start:9}.grid .g-start-xxl-10{grid-column-start:10}.grid .g-start-xxl-11{grid-column-start:11}}.table{--bs-table-bg: transparent;--bs-table-accent-bg: transparent;--bs-table-striped-color: #212529;--bs-table-striped-bg: rgba(0, 0, 0, 0.05);--bs-table-active-color: #212529;--bs-table-active-bg: rgba(0, 0, 0, 0.1);--bs-table-hover-color: #212529;--bs-table-hover-bg: rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:#212529;vertical-align:top;border-color:#dee2e6}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg: var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg: var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg: var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg: #2c3e50;--bs-table-striped-bg: #374859;--bs-table-striped-color: #fff;--bs-table-active-bg: #415162;--bs-table-active-color: #fff;--bs-table-hover-bg: #3c4c5d;--bs-table-hover-color: #fff;color:#fff;border-color:#415162}.table-secondary{--bs-table-bg: #6c757d;--bs-table-striped-bg: #737c84;--bs-table-striped-color: #fff;--bs-table-active-bg: #7b838a;--bs-table-active-color: #fff;--bs-table-hover-bg: #777f87;--bs-table-hover-color: #fff;color:#fff;border-color:#7b838a}.table-success{--bs-table-bg: #18bc9c;--bs-table-striped-bg: #24bfa1;--bs-table-striped-color: #fff;--bs-table-active-bg: #2fc3a6;--bs-table-active-color: #fff;--bs-table-hover-bg: #29c1a3;--bs-table-hover-color: #fff;color:#fff;border-color:#2fc3a6}.table-info{--bs-table-bg: #3498db;--bs-table-striped-bg: #3e9ddd;--bs-table-striped-color: #fff;--bs-table-active-bg: #48a2df;--bs-table-active-color: #fff;--bs-table-hover-bg: #43a0de;--bs-table-hover-color: #fff;color:#fff;border-color:#48a2df}.table-warning{--bs-table-bg: #f39c12;--bs-table-striped-bg: #f4a11e;--bs-table-striped-color: #fff;--bs-table-active-bg: #f4a62a;--bs-table-active-color: #000;--bs-table-hover-bg: #f4a324;--bs-table-hover-color: #fff;color:#fff;border-color:#f4a62a}.table-danger{--bs-table-bg: #e74c3c;--bs-table-striped-bg: #e85546;--bs-table-striped-color: #fff;--bs-table-active-bg: #e95e50;--bs-table-active-color: #fff;--bs-table-hover-bg: #e9594b;--bs-table-hover-color: #fff;color:#fff;border-color:#e95e50}.table-light{--bs-table-bg: #ecf0f1;--bs-table-striped-bg: #e0e4e5;--bs-table-striped-color: #000;--bs-table-active-bg: #d4d8d9;--bs-table-active-color: #000;--bs-table-hover-bg: #dadedf;--bs-table-hover-color: #000;color:#000;border-color:#d4d8d9}.table-dark{--bs-table-bg: #7b8a8b;--bs-table-striped-bg: #829091;--bs-table-striped-color: #fff;--bs-table-active-bg: #889697;--bs-table-active-color: #fff;--bs-table-hover-bg: #859394;--bs-table-hover-color: #fff;color:#fff;border-color:#889697}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label,.shiny-input-container .control-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(0.375rem + 1px);padding-bottom:calc(0.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(0.5rem + 1px);padding-bottom:calc(0.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(0.25rem + 1px);padding-bottom:calc(0.25rem + 1px);font-size:0.875rem}.form-text{margin-top:.25rem;font-size:0.875em;color:#6c757d}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#212529;background-color:#fff;border-color:#969fa8;outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#ecf0f1;opacity:1}.form-control::file-selector-button{padding:.375rem .75rem;margin:-0.375rem -0.75rem;margin-inline-end:.75rem;color:#212529;background-color:#ecf0f1;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#e0e4e5}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-0.375rem -0.75rem;margin-inline-end:.75rem;color:#212529;background-color:#ecf0f1;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control::-webkit-file-upload-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#e0e4e5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + 0.5rem + 2px);padding:.25rem .5rem;font-size:0.875rem;border-radius:.2em}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-0.25rem -0.5rem;margin-inline-end:.5rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-0.25rem -0.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-0.5rem -1rem;margin-inline-end:1rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-0.5rem -1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + 0.75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + 0.5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:auto;padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.5em;border-radius:.25rem}.form-control-color::-webkit-color-swatch{height:1.5em;border-radius:.25rem}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}@media(prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#969fa8;outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#ecf0f1}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #212529}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:0.875rem;border-radius:.2em}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.3rem}.form-check,.shiny-input-container .checkbox,.shiny-input-container .radio{display:block;min-height:1.5rem;padding-left:0;margin-bottom:.125rem}.form-check .form-check-input,.form-check .shiny-input-container .checkbox input,.form-check .shiny-input-container .radio input,.shiny-input-container .checkbox .form-check-input,.shiny-input-container .checkbox .shiny-input-container .checkbox input,.shiny-input-container .checkbox .shiny-input-container .radio input,.shiny-input-container .radio .form-check-input,.shiny-input-container .radio .shiny-input-container .checkbox input,.shiny-input-container .radio .shiny-input-container .radio input{float:left;margin-left:0}.form-check-input,.shiny-input-container .checkbox input,.shiny-input-container .checkbox-inline input,.shiny-input-container .radio input,.shiny-input-container .radio-inline input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,.25);appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;color-adjust:exact;-webkit-print-color-adjust:exact}.form-check-input[type=checkbox],.shiny-input-container .checkbox input[type=checkbox],.shiny-input-container .checkbox-inline input[type=checkbox],.shiny-input-container .radio input[type=checkbox],.shiny-input-container .radio-inline input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio],.shiny-input-container .checkbox input[type=radio],.shiny-input-container .checkbox-inline input[type=radio],.shiny-input-container .radio input[type=radio],.shiny-input-container .radio-inline input[type=radio]{border-radius:50%}.form-check-input:active,.shiny-input-container .checkbox input:active,.shiny-input-container .checkbox-inline input:active,.shiny-input-container .radio input:active,.shiny-input-container .radio-inline input:active{filter:brightness(90%)}.form-check-input:focus,.shiny-input-container .checkbox input:focus,.shiny-input-container .checkbox-inline input:focus,.shiny-input-container .radio input:focus,.shiny-input-container .radio-inline input:focus{border-color:#969fa8;outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.form-check-input:checked,.shiny-input-container .checkbox input:checked,.shiny-input-container .checkbox-inline input:checked,.shiny-input-container .radio input:checked,.shiny-input-container .radio-inline input:checked{background-color:#2c3e50;border-color:#2c3e50}.form-check-input:checked[type=checkbox],.shiny-input-container .checkbox input:checked[type=checkbox],.shiny-input-container .checkbox-inline input:checked[type=checkbox],.shiny-input-container .radio input:checked[type=checkbox],.shiny-input-container .radio-inline input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio],.shiny-input-container .checkbox input:checked[type=radio],.shiny-input-container .checkbox-inline input:checked[type=radio],.shiny-input-container .radio input:checked[type=radio],.shiny-input-container .radio-inline input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate,.shiny-input-container .checkbox input[type=checkbox]:indeterminate,.shiny-input-container .checkbox-inline input[type=checkbox]:indeterminate,.shiny-input-container .radio input[type=checkbox]:indeterminate,.shiny-input-container .radio-inline input[type=checkbox]:indeterminate{background-color:#2c3e50;border-color:#2c3e50;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled,.shiny-input-container .checkbox input:disabled,.shiny-input-container .checkbox-inline input:disabled,.shiny-input-container .radio input:disabled,.shiny-input-container .radio-inline input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled]~.form-check-label,.form-check-input[disabled]~span,.form-check-input:disabled~.form-check-label,.form-check-input:disabled~span,.shiny-input-container .checkbox input[disabled]~.form-check-label,.shiny-input-container .checkbox input[disabled]~span,.shiny-input-container .checkbox input:disabled~.form-check-label,.shiny-input-container .checkbox input:disabled~span,.shiny-input-container .checkbox-inline input[disabled]~.form-check-label,.shiny-input-container .checkbox-inline input[disabled]~span,.shiny-input-container .checkbox-inline input:disabled~.form-check-label,.shiny-input-container .checkbox-inline input:disabled~span,.shiny-input-container .radio input[disabled]~.form-check-label,.shiny-input-container .radio input[disabled]~span,.shiny-input-container .radio input:disabled~.form-check-label,.shiny-input-container .radio input:disabled~span,.shiny-input-container .radio-inline input[disabled]~.form-check-label,.shiny-input-container .radio-inline input[disabled]~span,.shiny-input-container .radio-inline input:disabled~.form-check-label,.shiny-input-container .radio-inline input:disabled~span{opacity:.5}.form-check-label,.shiny-input-container .checkbox label,.shiny-input-container .checkbox-inline label,.shiny-input-container .radio label,.shiny-input-container .radio-inline label{cursor:pointer}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23969fa8'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-check-inline,.shiny-input-container .checkbox-inline,.shiny-input-container .radio-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(44,62,80,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(44,62,80,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-0.25rem;background-color:#2c3e50;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}@media(prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#c0c5cb}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#2c3e50;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}@media(prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#c0c5cb}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .75rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media(prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .75rem}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.input-group{position:relative;display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:stretch;-webkit-align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:center;white-space:nowrap;background-color:#ecf0f1;border:1px solid #ced4da;border-radius:.25rem}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:.25rem .5rem;font-size:0.875rem;border-radius:.2em}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu),.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#18bc9c}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;color:#fff;background-color:rgba(24,188,156,.9);border-radius:.25rem}.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip,.is-valid~.valid-feedback,.is-valid~.valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#18bc9c;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2318bc9c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#18bc9c;box-shadow:0 0 0 .25rem rgba(24,188,156,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .form-select:valid,.form-select.is-valid{border-color:#18bc9c}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2318bc9c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#18bc9c;box-shadow:0 0 0 .25rem rgba(24,188,156,.25)}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#18bc9c}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#18bc9c}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 .25rem rgba(24,188,156,.25)}.was-validated .form-check-input:valid~.form-check-label,.form-check-input.is-valid~.form-check-label{color:#18bc9c}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.was-validated .input-group .form-control:valid,.input-group .form-control.is-valid,.was-validated .input-group .form-select:valid,.input-group .form-select.is-valid{z-index:1}.was-validated .input-group .form-control:valid:focus,.input-group .form-control.is-valid:focus,.was-validated .input-group .form-select:valid:focus,.input-group .form-select.is-valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#e74c3c}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;color:#fff;background-color:rgba(231,76,60,.9);border-radius:.25rem}.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip,.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#e74c3c;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#e74c3c}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#e74c3c}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#e74c3c}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.was-validated .form-check-input:invalid~.form-check-label,.form-check-input.is-invalid~.form-check-label{color:#e74c3c}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.was-validated .input-group .form-control:invalid,.input-group .form-control.is-invalid,.was-validated .input-group .form-select:invalid,.input-group .form-select.is-invalid{z-index:2}.was-validated .input-group .form-control:invalid:focus,.input-group .form-control.is-invalid:focus,.was-validated .input-group .form-select:invalid:focus,.input-group .form-select.is-invalid:focus{z-index:3}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#212529;text-align:center;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{pointer-events:none;opacity:.65}.btn-default{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-default:hover{color:#fff;background-color:#5c636a;border-color:#565e64}.btn-check:focus+.btn-default,.btn-default:focus{color:#fff;background-color:#5c636a;border-color:#565e64;box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-check:checked+.btn-default,.btn-check:active+.btn-default,.btn-default:active,.btn-default.active,.show>.btn-default.dropdown-toggle{color:#fff;background-color:#565e64;border-color:#51585e}.btn-check:checked+.btn-default:focus,.btn-check:active+.btn-default:focus,.btn-default:active:focus,.btn-default.active:focus,.show>.btn-default.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-default:disabled,.btn-default.disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-primary{color:#fff;background-color:#2c3e50;border-color:#2c3e50}.btn-primary:hover{color:#fff;background-color:#253544;border-color:#233240}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#fff;background-color:#253544;border-color:#233240;box-shadow:0 0 0 .25rem rgba(76,91,106,.5)}.btn-check:checked+.btn-primary,.btn-check:active+.btn-primary,.btn-primary:active,.btn-primary.active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#233240;border-color:#212f3c}.btn-check:checked+.btn-primary:focus,.btn-check:active+.btn-primary:focus,.btn-primary:active:focus,.btn-primary.active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(76,91,106,.5)}.btn-primary:disabled,.btn-primary.disabled{color:#fff;background-color:#2c3e50;border-color:#2c3e50}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5c636a;border-color:#565e64}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#5c636a;border-color:#565e64;box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-check:checked+.btn-secondary,.btn-check:active+.btn-secondary,.btn-secondary:active,.btn-secondary.active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#565e64;border-color:#51585e}.btn-check:checked+.btn-secondary:focus,.btn-check:active+.btn-secondary:focus,.btn-secondary:active:focus,.btn-secondary.active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-secondary:disabled,.btn-secondary.disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-success{color:#fff;background-color:#18bc9c;border-color:#18bc9c}.btn-success:hover{color:#fff;background-color:#14a085;border-color:#13967d}.btn-check:focus+.btn-success,.btn-success:focus{color:#fff;background-color:#14a085;border-color:#13967d;box-shadow:0 0 0 .25rem rgba(59,198,171,.5)}.btn-check:checked+.btn-success,.btn-check:active+.btn-success,.btn-success:active,.btn-success.active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#13967d;border-color:#128d75}.btn-check:checked+.btn-success:focus,.btn-check:active+.btn-success:focus,.btn-success:active:focus,.btn-success.active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(59,198,171,.5)}.btn-success:disabled,.btn-success.disabled{color:#fff;background-color:#18bc9c;border-color:#18bc9c}.btn-info{color:#fff;background-color:#3498db;border-color:#3498db}.btn-info:hover{color:#fff;background-color:#2c81ba;border-color:#2a7aaf}.btn-check:focus+.btn-info,.btn-info:focus{color:#fff;background-color:#2c81ba;border-color:#2a7aaf;box-shadow:0 0 0 .25rem rgba(82,167,224,.5)}.btn-check:checked+.btn-info,.btn-check:active+.btn-info,.btn-info:active,.btn-info.active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#2a7aaf;border-color:#2772a4}.btn-check:checked+.btn-info:focus,.btn-check:active+.btn-info:focus,.btn-info:active:focus,.btn-info.active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(82,167,224,.5)}.btn-info:disabled,.btn-info.disabled{color:#fff;background-color:#3498db;border-color:#3498db}.btn-warning{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-warning:hover{color:#fff;background-color:#cf850f;border-color:#c27d0e}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#fff;background-color:#cf850f;border-color:#c27d0e;box-shadow:0 0 0 .25rem rgba(245,171,54,.5)}.btn-check:checked+.btn-warning,.btn-check:active+.btn-warning,.btn-warning:active,.btn-warning.active,.show>.btn-warning.dropdown-toggle{color:#fff;background-color:#c27d0e;border-color:#b6750e}.btn-check:checked+.btn-warning:focus,.btn-check:active+.btn-warning:focus,.btn-warning:active:focus,.btn-warning.active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(245,171,54,.5)}.btn-warning:disabled,.btn-warning.disabled{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-danger{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-danger:hover{color:#fff;background-color:#c44133;border-color:#b93d30}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#fff;background-color:#c44133;border-color:#b93d30;box-shadow:0 0 0 .25rem rgba(235,103,89,.5)}.btn-check:checked+.btn-danger,.btn-check:active+.btn-danger,.btn-danger:active,.btn-danger.active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#b93d30;border-color:#ad392d}.btn-check:checked+.btn-danger:focus,.btn-check:active+.btn-danger:focus,.btn-danger:active:focus,.btn-danger.active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(235,103,89,.5)}.btn-danger:disabled,.btn-danger.disabled{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-light{color:#000;background-color:#ecf0f1;border-color:#ecf0f1}.btn-light:hover{color:#000;background-color:#eff2f3;border-color:#eef2f2}.btn-check:focus+.btn-light,.btn-light:focus{color:#000;background-color:#eff2f3;border-color:#eef2f2;box-shadow:0 0 0 .25rem rgba(201,204,205,.5)}.btn-check:checked+.btn-light,.btn-check:active+.btn-light,.btn-light:active,.btn-light.active,.show>.btn-light.dropdown-toggle{color:#000;background-color:#f0f3f4;border-color:#eef2f2}.btn-check:checked+.btn-light:focus,.btn-check:active+.btn-light:focus,.btn-light:active:focus,.btn-light.active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(201,204,205,.5)}.btn-light:disabled,.btn-light.disabled{color:#000;background-color:#ecf0f1;border-color:#ecf0f1}.btn-dark{color:#fff;background-color:#7b8a8b;border-color:#7b8a8b}.btn-dark:hover{color:#fff;background-color:#697576;border-color:#626e6f}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#697576;border-color:#626e6f;box-shadow:0 0 0 .25rem rgba(143,156,156,.5)}.btn-check:checked+.btn-dark,.btn-check:active+.btn-dark,.btn-dark:active,.btn-dark.active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#626e6f;border-color:#5c6868}.btn-check:checked+.btn-dark:focus,.btn-check:active+.btn-dark:focus,.btn-dark:active:focus,.btn-dark.active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(143,156,156,.5)}.btn-dark:disabled,.btn-dark.disabled{color:#fff;background-color:#7b8a8b;border-color:#7b8a8b}.btn-outline-default{color:#6c757d;border-color:#6c757d;background-color:transparent}.btn-outline-default:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:focus+.btn-outline-default,.btn-outline-default:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-check:checked+.btn-outline-default,.btn-check:active+.btn-outline-default,.btn-outline-default:active,.btn-outline-default.active,.btn-outline-default.dropdown-toggle.show{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:checked+.btn-outline-default:focus,.btn-check:active+.btn-outline-default:focus,.btn-outline-default:active:focus,.btn-outline-default.active:focus,.btn-outline-default.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-outline-default:disabled,.btn-outline-default.disabled{color:#6c757d;background-color:transparent}.btn-outline-primary{color:#2c3e50;border-color:#2c3e50;background-color:transparent}.btn-outline-primary:hover{color:#fff;background-color:#2c3e50;border-color:#2c3e50}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 .25rem rgba(44,62,80,.5)}.btn-check:checked+.btn-outline-primary,.btn-check:active+.btn-outline-primary,.btn-outline-primary:active,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show{color:#fff;background-color:#2c3e50;border-color:#2c3e50}.btn-check:checked+.btn-outline-primary:focus,.btn-check:active+.btn-outline-primary:focus,.btn-outline-primary:active:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(44,62,80,.5)}.btn-outline-primary:disabled,.btn-outline-primary.disabled{color:#2c3e50;background-color:transparent}.btn-outline-secondary{color:#6c757d;border-color:#6c757d;background-color:transparent}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-check:checked+.btn-outline-secondary,.btn-check:active+.btn-outline-secondary,.btn-outline-secondary:active,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:checked+.btn-outline-secondary:focus,.btn-check:active+.btn-outline-secondary:focus,.btn-outline-secondary:active:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-outline-secondary:disabled,.btn-outline-secondary.disabled{color:#6c757d;background-color:transparent}.btn-outline-success{color:#18bc9c;border-color:#18bc9c;background-color:transparent}.btn-outline-success:hover{color:#fff;background-color:#18bc9c;border-color:#18bc9c}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 .25rem rgba(24,188,156,.5)}.btn-check:checked+.btn-outline-success,.btn-check:active+.btn-outline-success,.btn-outline-success:active,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show{color:#fff;background-color:#18bc9c;border-color:#18bc9c}.btn-check:checked+.btn-outline-success:focus,.btn-check:active+.btn-outline-success:focus,.btn-outline-success:active:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(24,188,156,.5)}.btn-outline-success:disabled,.btn-outline-success.disabled{color:#18bc9c;background-color:transparent}.btn-outline-info{color:#3498db;border-color:#3498db;background-color:transparent}.btn-outline-info:hover{color:#fff;background-color:#3498db;border-color:#3498db}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 .25rem rgba(52,152,219,.5)}.btn-check:checked+.btn-outline-info,.btn-check:active+.btn-outline-info,.btn-outline-info:active,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show{color:#fff;background-color:#3498db;border-color:#3498db}.btn-check:checked+.btn-outline-info:focus,.btn-check:active+.btn-outline-info:focus,.btn-outline-info:active:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(52,152,219,.5)}.btn-outline-info:disabled,.btn-outline-info.disabled{color:#3498db;background-color:transparent}.btn-outline-warning{color:#f39c12;border-color:#f39c12;background-color:transparent}.btn-outline-warning:hover{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 .25rem rgba(243,156,18,.5)}.btn-check:checked+.btn-outline-warning,.btn-check:active+.btn-outline-warning,.btn-outline-warning:active,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-check:checked+.btn-outline-warning:focus,.btn-check:active+.btn-outline-warning:focus,.btn-outline-warning:active:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(243,156,18,.5)}.btn-outline-warning:disabled,.btn-outline-warning.disabled{color:#f39c12;background-color:transparent}.btn-outline-danger{color:#e74c3c;border-color:#e74c3c;background-color:transparent}.btn-outline-danger:hover{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 .25rem rgba(231,76,60,.5)}.btn-check:checked+.btn-outline-danger,.btn-check:active+.btn-outline-danger,.btn-outline-danger:active,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-check:checked+.btn-outline-danger:focus,.btn-check:active+.btn-outline-danger:focus,.btn-outline-danger:active:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(231,76,60,.5)}.btn-outline-danger:disabled,.btn-outline-danger.disabled{color:#e74c3c;background-color:transparent}.btn-outline-light{color:#ecf0f1;border-color:#ecf0f1;background-color:transparent}.btn-outline-light:hover{color:#000;background-color:#ecf0f1;border-color:#ecf0f1}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 .25rem rgba(236,240,241,.5)}.btn-check:checked+.btn-outline-light,.btn-check:active+.btn-outline-light,.btn-outline-light:active,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show{color:#000;background-color:#ecf0f1;border-color:#ecf0f1}.btn-check:checked+.btn-outline-light:focus,.btn-check:active+.btn-outline-light:focus,.btn-outline-light:active:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(236,240,241,.5)}.btn-outline-light:disabled,.btn-outline-light.disabled{color:#ecf0f1;background-color:transparent}.btn-outline-dark{color:#7b8a8b;border-color:#7b8a8b;background-color:transparent}.btn-outline-dark:hover{color:#fff;background-color:#7b8a8b;border-color:#7b8a8b}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 .25rem rgba(123,138,139,.5)}.btn-check:checked+.btn-outline-dark,.btn-check:active+.btn-outline-dark,.btn-outline-dark:active,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show{color:#fff;background-color:#7b8a8b;border-color:#7b8a8b}.btn-check:checked+.btn-outline-dark:focus,.btn-check:active+.btn-outline-dark:focus,.btn-outline-dark:active:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(123,138,139,.5)}.btn-outline-dark:disabled,.btn-outline-dark.disabled{color:#7b8a8b;background-color:transparent}.btn-link{font-weight:400;color:#18bc9c;text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}.btn-link:hover{color:#13967d}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.btn-sm,.btn-group-sm>.btn{padding:.25rem .5rem;font-size:0.875rem;border-radius:.2em}.fade{transition:opacity .15s linear}@media(prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .2s ease}@media(prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media(prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}.dropup,.dropend,.dropdown,.dropstart{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:.5rem 0;margin:0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media(min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid rgba(0,0,0,.15)}.dropdown-item{display:block;width:100%;padding:.25rem 1rem;clear:both;font-weight:400;color:#7b8a8b;text-align:inherit;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:hover,.dropdown-item:focus{color:#fff;background-color:#2c3e50}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#2c3e50}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:0.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#7b8a8b}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:hover,.dropdown-menu-dark .dropdown-item:focus{color:#fff;background-color:rgba(255,255,255,.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:#fff;background-color:#2c3e50}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;justify-content:flex-start;-webkit-justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn,.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;-webkit-flex-direction:column;align-items:flex-start;-webkit-align-items:flex-start;justify-content:center;-webkit-justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn~.btn,.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 2rem;color:#18bc9c;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media(prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:#13967d}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #ecf0f1}.nav-tabs .nav-link{margin-bottom:-1px;background:none;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:#ecf0f1 #ecf0f1 #ecf0f1;isolation:isolate}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:#7b8a8b;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:none;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#2c3e50}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;-webkit-flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;-webkit-flex-basis:0;flex-grow:1;-webkit-flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding-top:1rem;padding-bottom:1rem}.navbar>.container-xxl,.navbar>.container-xl,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container,.navbar>.container-fluid{display:flex;display:-webkit-flex;flex-wrap:inherit;-webkit-flex-wrap:inherit;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between}.navbar-brand{padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;-webkit-flex-basis:100%;flex-grow:1;-webkit-flex-grow:1;align-items:center;-webkit-align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem;transition:box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 .25rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media(min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-top,.navbar-expand-sm .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-top,.navbar-expand-md .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-top,.navbar-expand-lg .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-top,.navbar-expand-xl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-top,.navbar-expand-xxl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-top,.navbar-expand .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}.navbar-light{background-color:#2c3e50}.navbar-light .navbar-brand{color:#ccd1d5}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:#fff}.navbar-light .navbar-nav .nav-link{color:#ccd1d5}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:rgba(255,255,255,.8)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(204,209,213,.75)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .nav-link.active{color:#fff}.navbar-light .navbar-toggler{color:#ccd1d5;border-color:rgba(204,209,213,.4)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23ccd1d5' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:#ccd1d5}.navbar-light .navbar-text a,.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:#fff}.navbar-dark{background-color:#2c3e50}.navbar-dark .navbar-brand{color:#ccd1d5}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:#fff}.navbar-dark .navbar-nav .nav-link{color:#ccd1d5}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:rgba(255,255,255,.8)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(204,209,213,.75)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active{color:#fff}.navbar-dark .navbar-toggler{color:#ccd1d5;border-color:rgba(204,209,213,.4)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23ccd1d5' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:#ccd1d5}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:#fff}.card{position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(0.25rem - 1px);border-bottom-left-radius:calc(0.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;-webkit-flex:1 1 auto;padding:1rem 1rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-0.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1rem}.card-header{padding:.5rem 1rem;margin-bottom:0;background-color:#adb5bd;border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.card-footer{padding:.5rem 1rem;background-color:#adb5bd;border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-img,.card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(0.25rem - 1px);border-bottom-left-radius:calc(0.25rem - 1px)}.card-group>.card{margin-bottom:.75rem}@media(min-width: 576px){.card-group{display:flex;display:-webkit-flex;flex-flow:row wrap;-webkit-flex-flow:row wrap}.card-group>.card{flex:1 0 0%;-webkit-flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.accordion-button{position:relative;display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;width:100%;padding:1rem 1.25rem;font-size:1rem;color:#212529;text-align:left;background-color:#fff;border:0;border-radius:0;overflow-anchor:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,border-radius .15s ease}@media(prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:#283848;background-color:#eaecee;box-shadow:inset 0 -1px 0 rgba(0,0,0,.125)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23283848'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;-webkit-flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform .2s ease-in-out}@media(prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#969fa8;outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:#fff;border:1px solid rgba(0,0,0,.125)}.accordion-item:first-of-type{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.accordion-item:first-of-type .accordion-button{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:calc(0.25rem - 1px);border-bottom-left-radius:calc(0.25rem - 1px)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.breadcrumb{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;padding:.375rem .75rem;margin-bottom:1rem;list-style:none;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;display:-webkit-flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:#fff;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:#18bc9c;border:0 solid transparent;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:#fff;background-color:#0f7864;border-color:transparent}.page-link:focus{z-index:3;color:#13967d;background-color:#ecf0f1;outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item.active .page-link{z-index:3;color:#fff;background-color:#0f7864;border-color:transparent}.page-item.disabled .page-link{color:#ecf0f1;pointer-events:none;background-color:#3be6c4;border-color:transparent}.page-link{padding:.375rem .75rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:0.875rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2em;border-bottom-left-radius:.2em}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2em;border-bottom-right-radius:.2em}.badge{display:inline-block;padding:.35em .65em;font-size:0.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{position:relative;padding:1rem 1rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-default{color:#41464b;background-color:#e2e3e5;border-color:#d3d6d8}.alert-default .alert-link{color:#34383c}.alert-primary{color:#1a2530;background-color:#d5d8dc;border-color:#c0c5cb}.alert-primary .alert-link{color:#151e26}.alert-secondary{color:#41464b;background-color:#e2e3e5;border-color:#d3d6d8}.alert-secondary .alert-link{color:#34383c}.alert-success{color:#0e715e;background-color:#d1f2eb;border-color:#baebe1}.alert-success .alert-link{color:#0b5a4b}.alert-info{color:#1f5b83;background-color:#d6eaf8;border-color:#c2e0f4}.alert-info .alert-link{color:#194969}.alert-warning{color:#925e0b;background-color:#fdebd0;border-color:#fbe1b8}.alert-warning .alert-link{color:#754b09}.alert-danger{color:#8b2e24;background-color:#fadbd8;border-color:#f8c9c5}.alert-danger .alert-link{color:#6f251d}.alert-light{color:#8e9091;background-color:#fbfcfc;border-color:#f9fbfb}.alert-light .alert-link{color:#727374}.alert-dark{color:#4a5353;background-color:#e5e8e8;border-color:#d7dcdc}.alert-dark .alert-link{color:#3b4242}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{display:flex;display:-webkit-flex;height:1rem;overflow:hidden;font-size:0.75rem;background-color:#ecf0f1;border-radius:.25rem}.progress-bar{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;justify-content:center;-webkit-justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#2c3e50;transition:width .6s ease}@media(prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-size:1rem 1rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media(prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.list-group{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:#7b8a8b;text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:#7b8a8b;text-decoration:none;background-color:#ecf0f1}.list-group-item-action:active{color:#212529;background-color:#ecf0f1}.list-group-item{position:relative;display:block;padding:.5rem 1rem;color:#212529;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#ecf0f1}.list-group-item.active{z-index:2;color:#fff;background-color:#2c3e50;border-color:#2c3e50}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media(min-width: 576px){.list-group-horizontal-sm{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 768px){.list-group-horizontal-md{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 992px){.list-group-horizontal-lg{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 1200px){.list-group-horizontal-xl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-default{color:#41464b;background-color:#e2e3e5}.list-group-item-default.list-group-item-action:hover,.list-group-item-default.list-group-item-action:focus{color:#41464b;background-color:#cbccce}.list-group-item-default.list-group-item-action.active{color:#fff;background-color:#41464b;border-color:#41464b}.list-group-item-primary{color:#1a2530;background-color:#d5d8dc}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#1a2530;background-color:#c0c2c6}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#1a2530;border-color:#1a2530}.list-group-item-secondary{color:#41464b;background-color:#e2e3e5}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#41464b;background-color:#cbccce}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#41464b;border-color:#41464b}.list-group-item-success{color:#0e715e;background-color:#d1f2eb}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#0e715e;background-color:#bcdad4}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#0e715e;border-color:#0e715e}.list-group-item-info{color:#1f5b83;background-color:#d6eaf8}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#1f5b83;background-color:#c1d3df}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#1f5b83;border-color:#1f5b83}.list-group-item-warning{color:#925e0b;background-color:#fdebd0}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#925e0b;background-color:#e4d4bb}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#925e0b;border-color:#925e0b}.list-group-item-danger{color:#8b2e24;background-color:#fadbd8}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#8b2e24;background-color:#e1c5c2}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#8b2e24;border-color:#8b2e24}.list-group-item-light{color:#8e9091;background-color:#fbfcfc}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#8e9091;background-color:#e2e3e3}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#8e9091;border-color:#8e9091}.list-group-item-dark{color:#4a5353;background-color:#e5e8e8}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#4a5353;background-color:#ced1d1}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#4a5353;border-color:#4a5353}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#fff;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.4}.btn-close:hover{color:#fff;text-decoration:none;opacity:1}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25);opacity:1}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{width:350px;max-width:100%;font-size:0.875rem;pointer-events:auto;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.15);border-radius:.25rem}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{width:max-content;width:-webkit-max-content;width:-moz-max-content;width:-ms-max-content;width:-o-max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:.75rem}.toast-header{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;padding:.5rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.toast-header .btn-close{margin-right:-0.375rem;margin-left:.75rem}.toast-body{padding:.75rem;word-wrap:break-word}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0, -50px)}@media(prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;display:-webkit-flex;flex-shrink:0;-webkit-flex-shrink:0;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(0.3rem - 1px);border-top-right-radius:calc(0.3rem - 1px)}.modal-header .btn-close{padding:.5rem .5rem;margin:-0.5rem -0.5rem -0.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto;padding:1rem}.modal-footer{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-shrink:0;-webkit-flex-shrink:0;align-items:center;-webkit-align-items:center;justify-content:flex-end;-webkit-justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(0.3rem - 1px);border-bottom-left-radius:calc(0.3rem - 1px)}.modal-footer>*{margin:.25rem}@media(min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media(min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media(min-width: 1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media(max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media(max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media(max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media(max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media(max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[data-popper-placement^=top]{padding:.4rem 0}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow{bottom:0}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-end,.bs-tooltip-auto[data-popper-placement^=right]{padding:0 .4rem}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-bottom,.bs-tooltip-auto[data-popper-placement^=bottom]{padding:.4rem 0}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow{top:0}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-start,.bs-tooltip-auto[data-popper-placement^=left]{padding:0 .4rem}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0 /* rtl:ignore */;z-index:1070;display:block;max-width:276px;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow{bottom:calc(-0.5rem - 1px)}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow{left:calc(-0.5rem - 1px);width:.5rem;height:1rem}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow{top:calc(-0.5rem - 1px)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-0.5rem;content:"";border-bottom:1px solid #f0f0f0}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow{right:calc(-0.5rem - 1px);width:.5rem;height:1rem}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem 1rem;margin-bottom:0;font-size:1rem;background-color:#f0f0f0;border-bottom:1px solid rgba(0,0,0,.2);border-top-left-radius:calc(0.3rem - 1px);border-top-right-radius:calc(0.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y;-webkit-touch-action:pan-y;-moz-touch-action:pan-y;-ms-touch-action:pan-y;-o-touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;transition:transform .6s ease-in-out}@media(prefers-reduced-motion: reduce){.carousel-item{transition:none}}.carousel-item.active,.carousel-item-next,.carousel-item-prev{display:block}.carousel-item-next:not(.carousel-item-start),.active.carousel-item-end{transform:translateX(100%)}.carousel-item-prev:not(.carousel-item-end),.active.carousel-item-start{transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item.active,.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end{z-index:1;opacity:1}.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{z-index:0;opacity:0;transition:opacity 0s .6s}@media(prefers-reduced-motion: reduce){.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{transition:none}}.carousel-control-prev,.carousel-control-next{position:absolute;top:0;bottom:0;z-index:1;display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;justify-content:center;-webkit-justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:none;border:0;opacity:.5;transition:opacity .15s ease}@media(prefers-reduced-motion: reduce){.carousel-control-prev,.carousel-control-next{transition:none}}.carousel-control-prev:hover,.carousel-control-prev:focus,.carousel-control-next:hover,.carousel-control-next:focus{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-prev-icon,.carousel-control-next-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;display:-webkit-flex;justify-content:center;-webkit-justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;-webkit-flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media(prefers-reduced-motion: reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-prev-icon,.carousel-dark .carousel-control-next-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-0.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-0.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media(prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s;-webkit-animation-duration:1.5s;-moz-animation-duration:1.5s;-ms-animation-duration:1.5s;-o-animation-duration:1.5s}}.offcanvas{position:fixed;bottom:0;z-index:1045;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;visibility:hidden;background-color:#fff;background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media(prefers-reduced-motion: reduce){.offcanvas{transition:none}}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:1rem 1rem}.offcanvas-header .btn-close{padding:.5rem .5rem;margin-top:-0.5rem;margin-right:-0.5rem;margin-bottom:-0.5rem}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;-webkit-flex-grow:1;padding:1rem 1rem;overflow-y:auto}.offcanvas-start{top:0;left:0;width:400px;border-right:1px solid rgba(0,0,0,.2);transform:translateX(-100%)}.offcanvas-end{top:0;right:0;width:400px;border-left:1px solid rgba(0,0,0,.2);transform:translateX(100%)}.offcanvas-top{top:0;right:0;left:0;height:30vh;max-height:100%;border-bottom:1px solid rgba(0,0,0,.2);transform:translateY(-100%)}.offcanvas-bottom{right:0;left:0;height:30vh;max-height:100%;border-top:1px solid rgba(0,0,0,.2);transform:translateY(100%)}.offcanvas.show{transform:none}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentColor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{mask-image:linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);-webkit-mask-image:linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);mask-size:200% 100%;-webkit-mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{mask-position:-200% 0%;-webkit-mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.link-default{color:#6c757d}.link-default:hover,.link-default:focus{color:#565e64}.link-primary{color:#2c3e50}.link-primary:hover,.link-primary:focus{color:#233240}.link-secondary{color:#6c757d}.link-secondary:hover,.link-secondary:focus{color:#565e64}.link-success{color:#18bc9c}.link-success:hover,.link-success:focus{color:#13967d}.link-info{color:#3498db}.link-info:hover,.link-info:focus{color:#2a7aaf}.link-warning{color:#f39c12}.link-warning:hover,.link-warning:focus{color:#c27d0e}.link-danger{color:#e74c3c}.link-danger:hover,.link-danger:focus{color:#b93d30}.link-light{color:#ecf0f1}.link-light:hover,.link-light:focus{color:#f0f3f4}.link-dark{color:#7b8a8b}.link-dark:hover,.link-dark:focus{color:#626e6f}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio: calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio: calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}@media(min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}}@media(min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}}@media(min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}}@media(min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}}@media(min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}}.hstack{display:flex;display:-webkit-flex;flex-direction:row;-webkit-flex-direction:row;align-items:center;-webkit-align-items:center;align-self:stretch;-webkit-align-self:stretch}.vstack{display:flex;display:-webkit-flex;flex:1 1 auto;-webkit-flex:1 1 auto;flex-direction:column;-webkit-flex-direction:column;align-self:stretch;-webkit-align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;-webkit-align-self:stretch;width:1px;min-height:1em;background-color:currentColor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15) !important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175) !important}.shadow-none{box-shadow:none !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-top-0{border-top:0 !important}.border-end{border-right:1px solid #dee2e6 !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:1px solid #dee2e6 !important}.border-start-0{border-left:0 !important}.border-default{border-color:#6c757d !important}.border-primary{border-color:#2c3e50 !important}.border-secondary{border-color:#6c757d !important}.border-success{border-color:#18bc9c !important}.border-info{border-color:#3498db !important}.border-warning{border-color:#f39c12 !important}.border-danger{border-color:#e74c3c !important}.border-light{border-color:#ecf0f1 !important}.border-dark{border-color:#7b8a8b !important}.border-white{border-color:#fff !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.345rem + 1.14vw) !important}.fs-2{font-size:calc(1.3rem + 0.6vw) !important}.fs-3{font-size:calc(1.275rem + 0.3vw) !important}.fs-4{font-size:1.25rem !important}.fs-5{font-size:1.1rem !important}.fs-6{font-size:1rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-light{font-weight:300 !important}.fw-lighter{font-weight:lighter !important}.fw-normal{font-weight:400 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-default{--bs-text-opacity: 1;color:rgba(var(--bs-default-rgb), var(--bs-text-opacity)) !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:#6c757d !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,.5) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: 0.25}.text-opacity-50{--bs-text-opacity: 0.5}.text-opacity-75{--bs-text-opacity: 0.75}.text-opacity-100{--bs-text-opacity: 1}.bg-default{--bs-bg-opacity: 1;background-color:rgba(var(--bs-default-rgb), var(--bs-bg-opacity)) !important}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:transparent !important}.bg-opacity-10{--bs-bg-opacity: 0.1}.bg-opacity-25{--bs-bg-opacity: 0.25}.bg-opacity-50{--bs-bg-opacity: 0.5}.bg-opacity-75{--bs-bg-opacity: 0.75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:.25rem !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:.2em !important}.rounded-2{border-radius:.25rem !important}.rounded-3{border-radius:.3rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-end{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-start{border-bottom-left-radius:.25rem !important;border-top-left-radius:.25rem !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media(min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media(min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media(min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media(min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media(min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}.bg-default{color:#fff}.bg-primary{color:#fff}.bg-secondary{color:#fff}.bg-success{color:#fff}.bg-info{color:#fff}.bg-warning{color:#fff}.bg-danger{color:#fff}.bg-light{color:#000}.bg-dark{color:#fff}@media(min-width: 1200px){.fs-1{font-size:2.2rem !important}.fs-2{font-size:1.75rem !important}.fs-3{font-size:1.5rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}.quarto-container{min-height:calc(100vh - 132px)}footer.footer .nav-footer,#quarto-header nav{padding-left:1em;padding-right:1em}nav[role=doc-toc]{padding-left:.5em}#quarto-content>*{padding-top:14px}@media(max-width: 991.98px){#quarto-content>*{padding-top:0}#quarto-content .subtitle{padding-top:14px}#quarto-content section:first-of-type h2:first-of-type,#quarto-content section:first-of-type .h2:first-of-type{margin-top:1rem}}.headroom-target,header.headroom{will-change:transform;transition:transform 200ms linear;transition:position 200ms linear}header.headroom--pinned{transform:translateY(0%)}header.headroom--unpinned{transform:translateY(-100%)}.navbar-container{width:100%}.navbar-brand{overflow:hidden;text-overflow:ellipsis}.navbar-brand-container{max-width:calc(100% - 85px);min-width:0;display:flex;align-items:center;margin-right:1em}.navbar-brand.navbar-brand-logo{margin-right:4px;display:inline-flex}.navbar-toggler{flex-basis:content;flex-shrink:0}.navbar-logo{max-height:24px;width:auto;padding-right:4px}nav .nav-item:not(.compact){padding-top:1px}nav .nav-link i,nav .dropdown-item i{padding-right:1px}.navbar-expand-lg .navbar-nav .nav-link{padding-left:.6rem;padding-right:.6rem}nav .nav-item.compact .nav-link{padding-left:.5rem;padding-right:.5rem;font-size:1.1rem}.navbar-nav .dropdown-menu{min-width:220px;font-size:.9rem}.navbar .navbar-nav .nav-link.dropdown-toggle::after{opacity:.75;vertical-align:.175em}.navbar ul.dropdown-menu{padding-top:0;padding-bottom:0}.navbar .dropdown-header{text-transform:uppercase;font-size:.8rem;padding:0 .5rem}.navbar .dropdown-item{padding:.4rem .5rem}.navbar .dropdown-item>i.bi{margin-left:.1rem;margin-right:.25em}.sidebar #quarto-search{margin-top:-1px}.sidebar #quarto-search svg.aa-SubmitIcon{width:16px;height:16px}.sidebar-navigation a{color:inherit}.sidebar-title{margin-top:.25rem;padding-bottom:.5rem;font-size:1.3rem;line-height:1.6rem;visibility:visible}.sidebar-title>a{font-size:inherit;text-decoration:none}.sidebar-title .sidebar-tools-main{margin-top:-6px}.sidebar-header-stacked .sidebar-title{margin-top:.6rem}.sidebar-logo{max-width:90%;padding-bottom:.5rem}.sidebar-logo-link{text-decoration:none}.sidebar-navigation li a{text-decoration:none}.sidebar-navigation .sidebar-tool{opacity:.7;font-size:.875rem}#quarto-sidebar>nav>.sidebar-tools-main{margin-left:14px}.sidebar-tools-main{margin-left:0px}.sidebar-tools-main:not(.tools-wide){display:inline-block;vertical-align:middle}.sidebar-tools-main.tools-wide{padding-top:.3em}.sidebar-navigation .sidebar-tool.dropdown-toggle::after{display:none}.sidebar.sidebar-navigation>*{padding-top:1em}.sidebar-item{margin-bottom:.2em}.sidebar-section{margin-top:.2em;padding-left:.5em;padding-bottom:.2em}.sidebar-item .sidebar-item-container{display:flex;justify-content:space-between}.sidebar-item .sidebar-item-toggle .bi{font-size:.7rem;text-align:center}.sidebar-navigation .sidebar-divider{margin-left:0;margin-right:0;margin-top:.5rem;margin-bottom:.5rem}@media(max-width: 767.98px){.quarto-secondary-nav{display:block}}@media(min-width: 992px){.quarto-secondary-nav{display:none}}.quarto-secondary-nav .quarto-btn-toggle{color:#595959;padding-right:0}.quarto-secondary-nav[aria-expanded=false] .quarto-btn-toggle .bi-chevron-right::before{transform:none}.quarto-secondary-nav[aria-expanded=true] .quarto-btn-toggle .bi-chevron-right::before{transform:rotate(90deg)}.quarto-secondary-nav .quarto-btn-toggle .bi-chevron-right::before{transition:transform 200ms ease}.quarto-secondary-nav{cursor:pointer}.quarto-secondary-nav-title{margin-top:.3em;color:#595959;padding-top:4px}div.sidebar-item-container{color:#595959}div.sidebar-item-container:hover,div.sidebar-item-container:focus{color:rgba(13,100,83,.8)}div.sidebar-item-container.disabled{color:rgba(89,89,89,.75)}div.sidebar-item-container .active,div.sidebar-item-container .show>.nav-link,div.sidebar-item-container .sidebar-link>code{color:#0d6453}div.sidebar.sidebar-navigation.rollup.quarto-sidebar-toggle-contents,nav.sidebar.sidebar-navigation:not(.rollup){background-color:#fff}@media(max-width: 991.98px){.sidebar-navigation .sidebar-item a,.nav-page .nav-page-text,.sidebar-navigation{font-size:1rem}.sidebar-navigation ul.sidebar-section.depth1 .sidebar-section-item{font-size:1.1rem}.sidebar-logo{display:none}.sidebar.sidebar-navigation{position:static;border-bottom:1px solid #dee2e6}.sidebar.sidebar-navigation.collapsing{position:fixed;z-index:1000}.sidebar.sidebar-navigation.show{position:fixed;z-index:1000}.sidebar.sidebar-navigation{transition:height .15s linear;width:100%}nav.quarto-secondary-nav{background-color:#fff;border-bottom:1px solid #dee2e6}.sidebar .sidebar-footer{visibility:visible;padding-top:1rem;position:inherit}.sidebar-tools-collapse{display:block}}@media(min-width: 992px){#quarto-sidebar{display:flex;flex-direction:column}.nav-page .nav-page-text,.sidebar-navigation .sidebar-section .sidebar-item{font-size:.875rem}.sidebar-navigation .sidebar-item{font-size:.925rem}.sidebar.sidebar-navigation{display:block;position:sticky}.sidebar-search{width:100%}.sidebar .sidebar-footer{visibility:visible}}.sidebar .sidebar-footer{padding:.5rem 1rem;align-self:flex-end;color:#6c757d;width:100%}#quarto-sidebar{width:100%;padding-right:1em;color:#595959}.quarto-sidebar-footer{font-size:.875em}.sidebar-section .bi-chevron-right{vertical-align:middle}.sidebar-section a .bi-chevron-right::before{transform:rotate(90deg)}.sidebar-section a.collapsed .bi-chevron-right::before{transform:none}.sidebar-section .bi-chevron-right::before{font-size:.9em;transition:transform 200ms ease}.notransition{-webkit-transition:none !important;-moz-transition:none !important;-o-transition:none !important;transition:none !important}.btn:focus:not(:focus-visible){box-shadow:none}.page-navigation{display:flex;justify-content:space-between}.nav-page{padding-bottom:.75em}.nav-page .bi{font-size:1.8rem;vertical-align:middle}.nav-page .nav-page-text{padding-left:.25em;padding-right:.25em}.nav-page a{color:#6c757d;text-decoration:none;display:flex;align-items:center}.nav-page a:hover{color:#13967d}.toc-actions{display:flex}.toc-actions p{margin-block-start:0;margin-block-end:0}.toc-actions a{text-decoration:none;color:inherit;font-weight:400}.toc-actions a:hover{color:#13967d}.toc-actions .action-links{margin-left:4px}.sidebar nav[role=doc-toc] .toc-actions .bi{margin-left:-4px;font-size:.7rem;color:#6c757d}.sidebar nav[role=doc-toc] .toc-actions .bi:before{padding-top:3px}#quarto-margin-sidebar .toc-actions .bi:before{margin-top:.3rem;font-size:.7rem;color:#6c757d;vertical-align:top}.sidebar nav[role=doc-toc] .toc-actions>div:first-of-type{margin-top:-3px}#quarto-margin-sidebar .toc-actions p,.sidebar nav[role=doc-toc] .toc-actions p{font-size:.875rem}.nav-footer{display:flex;justify-content:center;align-items:center;text-align:center;padding-top:.5rem;padding-bottom:.5rem;background-color:#fff}body.nav-fixed{padding-top:82px}.nav-footer-contents{color:#6c757d;margin-top:.25rem}.nav-footer{min-height:3.5em;color:#757575}.nav-footer a{color:#757575}.nav-footer .nav-footer-left{font-size:.825em}.nav-footer .nav-footer-center{font-size:.825em}.nav-footer .nav-footer-right{font-size:.825em}.nav-footer-left .footer-items,.nav-footer-center .footer-items,.nav-footer-right .footer-items{display:flex;padding-top:.3em;padding-bottom:.3em;margin-bottom:0em}.nav-footer-left .footer-items .nav-link,.nav-footer-center .footer-items .nav-link,.nav-footer-right .footer-items .nav-link{padding-left:.6em;padding-right:.6em}.nav-footer-left{margin-right:auto}.nav-footer-center{min-height:3em;position:absolute;text-align:center}.nav-footer-center .footer-items{justify-content:center}@media(max-width: 767.98px){.nav-footer-center{margin-top:3em}}.nav-footer-right{margin-left:auto}.navbar .quarto-reader-toggle{padding-left:.4em;padding-right:0}.navbar .quarto-reader-toggle.reader .quarto-reader-toggle-btn{background-color:#ccd1d5;border-radius:3px}.quarto-reader-toggle.reader.sidebar-tool .quarto-reader-toggle-btn{background-color:#595959;border-radius:3px}.quarto-reader-toggle.sidebar-tool{padding-left:.3em}.quarto-reader-toggle .quarto-reader-toggle-btn{display:inline-flex;padding-left:.1em;padding-right:.3em;text-align:center}.navbar .quarto-reader-toggle:not(.reader) .bi::before{background-image:url('data:image/svg+xml,')}.navbar .quarto-reader-toggle.reader .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-reader-toggle:not(.reader) .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-reader-toggle.reader .bi::before{background-image:url('data:image/svg+xml,')}.aa-DetachedOverlay ul.aa-List,#quarto-search-results ul.aa-List{list-style:none;padding-left:0}.aa-DetachedOverlay .aa-Panel,#quarto-search-results .aa-Panel{background-color:#fff;position:absolute;z-index:2000}#quarto-search-results .aa-Panel{max-width:400px}#quarto-search input{font-size:.925rem}@media(min-width: 992px){.navbar #quarto-search{margin-left:1rem}}#quarto-sidebar .sidebar-search .aa-Autocomplete{width:100%}.navbar .aa-Autocomplete .aa-Form{width:180px}.navbar #quarto-search.type-overlay .aa-Autocomplete{width:40px}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form{background-color:inherit;border:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form:focus-within{box-shadow:none;outline:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-InputWrapper{display:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-InputWrapper:focus-within{display:inherit}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-Label svg,.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-LoadingIndicator svg{width:26px;height:26px;color:#ccd1d5;opacity:1}.navbar #quarto-search.type-overlay .aa-Autocomplete svg.aa-SubmitIcon{width:26px;height:26px;color:#ccd1d5;opacity:1}.aa-Autocomplete .aa-Form,.aa-DetachedFormContainer .aa-Form{align-items:center;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;color:#212529;display:flex;line-height:1em;margin:0;position:relative;width:100%}.aa-Autocomplete .aa-Form:focus-within,.aa-DetachedFormContainer .aa-Form:focus-within{box-shadow:rgba(44,62,80,.6) 0 0 0 1px;outline:currentColor none medium}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix{align-items:center;display:flex;flex-shrink:0;order:1}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-Label,.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-Label,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator{cursor:initial;flex-shrink:0;padding:0;text-align:left}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-Label svg,.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-Label svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator svg{color:#212529;opacity:.5}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-SubmitButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-SubmitButton{appearance:none;background:none;border:0;margin:0}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator{align-items:center;display:flex;justify-content:center}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator[hidden]{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapper,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper{order:3;position:relative;width:100%}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input{appearance:none;background:none;border:0;color:#212529;font:inherit;height:calc(1.5em + (0.1rem + 2px));padding:0;width:100%}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::placeholder,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::placeholder{color:#212529;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input:focus{border-color:none;box-shadow:none;outline:none}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-decoration,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-cancel-button,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-button,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-decoration,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-decoration,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-cancel-button,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-button,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-decoration{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix{align-items:center;display:flex;order:4}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton{align-items:center;background:none;border:0;color:#212529;opacity:.8;cursor:pointer;display:flex;margin:0;width:calc(1.5em + (0.1rem + 2px))}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:hover,.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:hover,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:focus{color:#212529;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton[hidden]{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton svg{width:calc(1.5em + 0.75rem + 2px)}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton{border:none;align-items:center;background:none;color:#212529;opacity:.4;font-size:.7rem;cursor:pointer;display:none;margin:0;width:calc(1em + (0.1rem + 2px))}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:hover,.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:hover,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:focus{color:#212529;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton[hidden]{display:none}#quarto-search-results .aa-Panel{border:solid #ced4da 1px}#quarto-search-results .aa-SourceNoResults{width:398px}.aa-DetachedOverlay .aa-Panel,#quarto-search-results .aa-Panel{max-height:65vh;overflow-y:auto;font-size:.925rem}.aa-DetachedOverlay .aa-SourceNoResults,#quarto-search-results .aa-SourceNoResults{height:60px;display:flex;justify-content:center;align-items:center}.aa-DetachedOverlay .search-error,#quarto-search-results .search-error{padding-top:10px;padding-left:20px;padding-right:20px;cursor:default}.aa-DetachedOverlay .search-error .search-error-title,#quarto-search-results .search-error .search-error-title{font-size:1.1rem;margin-bottom:.5rem}.aa-DetachedOverlay .search-error .search-error-title .search-error-icon,#quarto-search-results .search-error .search-error-title .search-error-icon{margin-right:8px}.aa-DetachedOverlay .search-error .search-error-text,#quarto-search-results .search-error .search-error-text{font-weight:300}.aa-DetachedOverlay .search-result-text,#quarto-search-results .search-result-text{font-weight:300;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.2rem;max-height:2.4rem}.aa-DetachedOverlay .aa-SourceHeader .search-result-header,#quarto-search-results .aa-SourceHeader .search-result-header{font-size:.875rem;background-color:#f2f2f2;padding-left:14px;padding-bottom:4px;padding-top:4px}.aa-DetachedOverlay .aa-SourceHeader .search-result-header-no-results,#quarto-search-results .aa-SourceHeader .search-result-header-no-results{display:none}.aa-DetachedOverlay .aa-SourceFooter .algolia-search-logo,#quarto-search-results .aa-SourceFooter .algolia-search-logo{width:110px;opacity:.85;margin:8px;float:right}.aa-DetachedOverlay .search-result-section,#quarto-search-results .search-result-section{font-size:.925em}.aa-DetachedOverlay a.search-result-link,#quarto-search-results a.search-result-link{color:inherit;text-decoration:none}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item,#quarto-search-results li.aa-Item[aria-selected=true] .search-item{background-color:#2c3e50}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item.search-result-more,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-section,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-text,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-title-container,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-text-container,#quarto-search-results li.aa-Item[aria-selected=true] .search-item.search-result-more,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-section,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-text,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-title-container,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-text-container{color:#fff;background-color:#2c3e50}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item mark.search-match,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-match.mark,#quarto-search-results li.aa-Item[aria-selected=true] .search-item mark.search-match,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-match.mark{color:#fff;background-color:#3a526a}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item,#quarto-search-results li.aa-Item[aria-selected=false] .search-item{background-color:#fff}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item.search-result-more,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-section,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-text,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-title-container,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-text-container,#quarto-search-results li.aa-Item[aria-selected=false] .search-item.search-result-more,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-section,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-text,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-title-container,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-text-container{color:#212529}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item mark.search-match,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-match.mark,#quarto-search-results li.aa-Item[aria-selected=false] .search-item mark.search-match,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-match.mark{color:inherit;background-color:#90a9c2}.aa-DetachedOverlay .aa-Item .search-result-doc:not(.document-selectable) .search-result-title-container,#quarto-search-results .aa-Item .search-result-doc:not(.document-selectable) .search-result-title-container{background-color:#fff;color:#212529}.aa-DetachedOverlay .aa-Item .search-result-doc:not(.document-selectable) .search-result-text-container,#quarto-search-results .aa-Item .search-result-doc:not(.document-selectable) .search-result-text-container{padding-top:0px}.aa-DetachedOverlay li.aa-Item .search-result-doc.document-selectable .search-result-text-container,#quarto-search-results li.aa-Item .search-result-doc.document-selectable .search-result-text-container{margin-top:-4px}.aa-DetachedOverlay .aa-Item,#quarto-search-results .aa-Item{cursor:pointer}.aa-DetachedOverlay .aa-Item .search-item,#quarto-search-results .aa-Item .search-item{border-left:none;border-right:none;border-top:none;background-color:#fff;border-color:#ced4da;color:#212529}.aa-DetachedOverlay .aa-Item .search-item p,#quarto-search-results .aa-Item .search-item p{margin-top:0;margin-bottom:0}.aa-DetachedOverlay .aa-Item .search-item i.bi,#quarto-search-results .aa-Item .search-item i.bi{padding-left:8px;padding-right:8px;font-size:1.3em}.aa-DetachedOverlay .aa-Item .search-item .search-result-title,#quarto-search-results .aa-Item .search-item .search-result-title{margin-top:.3em;margin-bottom:.1rem}.aa-DetachedOverlay .aa-Item .search-result-title-container,#quarto-search-results .aa-Item .search-result-title-container{font-size:1em;display:flex;padding:6px 4px 6px 4px}.aa-DetachedOverlay .aa-Item .search-result-text-container,#quarto-search-results .aa-Item .search-result-text-container{padding-bottom:8px;padding-right:8px;margin-left:44px}.aa-DetachedOverlay .aa-Item .search-result-doc-section,.aa-DetachedOverlay .aa-Item .search-result-more,#quarto-search-results .aa-Item .search-result-doc-section,#quarto-search-results .aa-Item .search-result-more{padding-top:8px;padding-bottom:8px;padding-left:44px}.aa-DetachedOverlay .aa-Item .search-result-more,#quarto-search-results .aa-Item .search-result-more{font-size:.8em;font-weight:400}.aa-DetachedOverlay .aa-Item .search-result-doc,#quarto-search-results .aa-Item .search-result-doc{border-top:1px solid #ced4da}.aa-DetachedSearchButton{background:none;border:none}.aa-DetachedSearchButton .aa-DetachedSearchButtonPlaceholder{display:none}.navbar .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon{color:#ccd1d5}.sidebar-tools-collapse #quarto-search,.sidebar-tools-main #quarto-search{display:inline}.sidebar-tools-collapse #quarto-search .aa-Autocomplete,.sidebar-tools-main #quarto-search .aa-Autocomplete{display:inline}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton{padding-left:4px;padding-right:4px}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon{color:#595959}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon .aa-SubmitIcon,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon .aa-SubmitIcon{margin-top:-3px}.aa-DetachedContainer{background:rgba(255,255,255,.65);width:90%;bottom:0;box-shadow:rgba(206,212,218,.6) 0 0 0 1px;outline:currentColor none medium;display:flex;flex-direction:column;left:0;margin:0;overflow:hidden;padding:0;position:fixed;right:0;top:0;z-index:1101}.aa-DetachedContainer::after{height:32px}.aa-DetachedContainer .aa-SourceHeader{margin:var(--aa-spacing-half) 0 var(--aa-spacing-half) 2px}.aa-DetachedContainer .aa-Panel{background-color:#fff;border-radius:0;box-shadow:none;flex-grow:1;margin:0;padding:0;position:relative}.aa-DetachedContainer .aa-PanelLayout{bottom:0;box-shadow:none;left:0;margin:0;max-height:none;overflow-y:auto;position:absolute;right:0;top:0;width:100%}.aa-DetachedFormContainer{background-color:#fff;border-bottom:1px solid #ced4da;display:flex;flex-direction:row;justify-content:space-between;margin:0;padding:.5em}.aa-DetachedCancelButton{background:none;font-size:.8em;border:0;border-radius:3px;color:#212529;cursor:pointer;margin:0 0 0 .5em;padding:0 .5em}.aa-DetachedCancelButton:hover,.aa-DetachedCancelButton:focus{box-shadow:rgba(44,62,80,.6) 0 0 0 1px;outline:currentColor none medium}.aa-DetachedContainer--modal{border-radius:6px;bottom:inherit;height:auto;margin:0 auto;max-width:850px;position:absolute;top:100px}.aa-DetachedContainer--modal .aa-PanelLayout{max-height:var(--aa-detached-modal-max-height);padding-bottom:var(--aa-spacing-half);position:static}.aa-Detached{height:100vh;overflow:hidden}.aa-DetachedOverlay{background-color:rgba(33,37,41,.4);position:fixed;left:0;right:0;top:0;margin:0;padding:0;height:100vh;z-index:1100}.quarto-listing{padding-bottom:1em}.listing-pagination{padding-top:.5em}ul.pagination{float:right;padding-left:8px;padding-top:.5em}ul.pagination li{padding-right:.75em}ul.pagination li.disabled a,ul.pagination li.active a{color:#212529;text-decoration:none}ul.pagination li:last-of-type{padding-right:0}.listing-actions-group{display:flex}.quarto-listing-filter{margin-bottom:1em;width:200px;margin-left:auto}.quarto-listing-sort{margin-bottom:1em;margin-right:auto;width:auto}.quarto-listing-sort .input-group-text{font-size:.8em}.input-group-text{border-right:none}.quarto-listing-sort select.form-select{font-size:.8em}.listing-no-matching{text-align:center;padding-top:2em;padding-bottom:3em;font-size:1em}#quarto-margin-sidebar .quarto-listing-category{padding-top:0;font-size:1rem}#quarto-margin-sidebar .quarto-listing-category-title{cursor:pointer;font-weight:600;font-size:1rem}.quarto-listing-category .category{cursor:pointer}.quarto-listing-category .category.active{font-weight:600}.quarto-listing-category.category-cloud{display:flex;flex-wrap:wrap;align-items:baseline}.quarto-listing-category.category-cloud .category{padding-right:5px}.quarto-listing-category.category-cloud .category-cloud-1{font-size:.75em}.quarto-listing-category.category-cloud .category-cloud-2{font-size:.95em}.quarto-listing-category.category-cloud .category-cloud-3{font-size:1.15em}.quarto-listing-category.category-cloud .category-cloud-4{font-size:1.35em}.quarto-listing-category.category-cloud .category-cloud-5{font-size:1.55em}.quarto-listing-category.category-cloud .category-cloud-6{font-size:1.75em}.quarto-listing-category.category-cloud .category-cloud-7{font-size:1.95em}.quarto-listing-category.category-cloud .category-cloud-8{font-size:2.15em}.quarto-listing-category.category-cloud .category-cloud-9{font-size:2.35em}.quarto-listing-category.category-cloud .category-cloud-10{font-size:2.55em}.quarto-listing-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-1{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-2{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-3{grid-template-columns:repeat(3, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-3{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-3{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-4{grid-template-columns:repeat(4, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-4{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-4{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-5{grid-template-columns:repeat(5, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-5{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-5{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-6{grid-template-columns:repeat(6, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-6{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-6{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-7{grid-template-columns:repeat(7, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-7{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-7{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-8{grid-template-columns:repeat(8, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-8{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-8{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-9{grid-template-columns:repeat(9, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-9{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-9{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-10{grid-template-columns:repeat(10, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-10{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-10{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-11{grid-template-columns:repeat(11, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-11{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-11{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-12{grid-template-columns:repeat(12, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-12{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-12{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-grid{gap:1.5em}.quarto-grid-item.borderless{border:none}.quarto-grid-item.borderless .listing-categories .listing-category:last-of-type,.quarto-grid-item.borderless .listing-categories .listing-category:first-of-type{padding-left:0}.quarto-grid-item.borderless .listing-categories .listing-category{border:0}.quarto-grid-link{text-decoration:none;color:inherit}.quarto-grid-link:hover{text-decoration:none;color:inherit}.quarto-grid-item h5.title,.quarto-grid-item .title.h5{margin-top:0;margin-bottom:0}.quarto-grid-item .card-footer{display:flex;justify-content:space-between;font-size:.8em}.quarto-grid-item .card-footer p{margin-bottom:0}.quarto-grid-item p.card-img-top{margin-bottom:0}.quarto-grid-item img.thumbnail-image{object-fit:cover}.quarto-grid-item .card-other-values{margin-top:.5em;font-size:.8em}.quarto-grid-item .card-other-values tr{margin-bottom:.5em}.quarto-grid-item .card-other-values tr>td:first-of-type{font-weight:600;padding-right:1em;padding-left:1em;vertical-align:top}.quarto-grid-item div.post-contents{display:flex;flex-direction:column;text-decoration:none;height:100%}.quarto-grid-item div.card-img-bg{background-color:#adb5bd;flex-shrink:0}.quarto-grid-item .card-attribution{padding-top:1em;display:flex;gap:1em;text-transform:uppercase;color:#6c757d;font-weight:500;flex-grow:10;align-items:flex-end}.quarto-grid-item .description{padding-bottom:1em}.quarto-grid-item .card-attribution .date{align-self:flex-end}.quarto-grid-item .card-attribution.justify{justify-content:space-between}.quarto-grid-item .card-attribution.start{justify-content:flex-start}.quarto-grid-item .card-attribution.end{justify-content:flex-end}.quarto-grid-item .card-title{margin-bottom:.1em}.quarto-grid-item .card-subtitle{padding-top:.25em}.quarto-grid-item .card-text{font-size:.9em}.quarto-grid-item .listing-reading-time{padding-bottom:.25em}.quarto-grid-item .card-text-small{font-size:.8em}.quarto-grid-item .card-subtitle.subtitle{font-size:.9em;font-weight:600;padding-bottom:.5em}.quarto-grid-item .listing-categories{display:flex;flex-wrap:wrap;padding-bottom:5px}.quarto-grid-item .listing-categories .listing-category{color:#6c757d;border:solid 1px #dee2e6;border-radius:.25rem;text-transform:uppercase;font-size:.65em;padding-left:.5em;padding-right:.5em;padding-top:.15em;padding-bottom:.15em;cursor:pointer;margin-right:4px;margin-bottom:4px}.quarto-grid-item.card-right{text-align:right}.quarto-grid-item.card-right .listing-categories{justify-content:flex-end}.quarto-grid-item.card-left{text-align:left}.quarto-grid-item.card-center{text-align:center}.quarto-grid-item.card-center .listing-description{text-align:justify}.quarto-grid-item.card-center .listing-categories{justify-content:center}table.quarto-listing-table td.image{padding:0px}table.quarto-listing-table td.image img{width:100%;max-width:50px;object-fit:contain}table.quarto-listing-table a{text-decoration:none}table.quarto-listing-table th a{color:inherit}table.quarto-listing-table th a.asc:after{margin-bottom:-2px;margin-left:5px;display:inline-block;height:1rem;width:1rem;background-repeat:no-repeat;background-size:1rem 1rem;background-image:url('data:image/svg+xml,');content:""}table.quarto-listing-table th a.desc:after{margin-bottom:-2px;margin-left:5px;display:inline-block;height:1rem;width:1rem;background-repeat:no-repeat;background-size:1rem 1rem;background-image:url('data:image/svg+xml,');content:""}table.quarto-listing-table.table-hover td{cursor:pointer}.quarto-post.image-left{flex-direction:row}.quarto-post.image-right{flex-direction:row-reverse}@media(max-width: 767.98px){.quarto-post.image-right,.quarto-post.image-left{gap:0em;flex-direction:column}.quarto-post .metadata{padding-bottom:1em;order:2}.quarto-post .body{order:1}.quarto-post .thumbnail{order:3}}.list.quarto-listing-default div:last-of-type{border-bottom:none}@media(min-width: 992px){.quarto-listing-container-default{margin-right:2em}}div.quarto-post{display:flex;gap:2em;margin-bottom:1.5em;border-bottom:1px solid #dee2e6}@media(max-width: 767.98px){div.quarto-post{padding-bottom:1em}}div.quarto-post .metadata{flex-basis:20%;flex-grow:0;margin-top:.2em;flex-shrink:10}div.quarto-post .thumbnail{flex-basis:30%;flex-grow:0;flex-shrink:0}div.quarto-post .thumbnail img{margin-top:.4em;width:100%;object-fit:cover}div.quarto-post .body{flex-basis:45%;flex-grow:1;flex-shrink:0}div.quarto-post .body h3.listing-title,div.quarto-post .body .listing-title.h3{margin-top:0px;margin-bottom:0px;border-bottom:none}div.quarto-post .body .listing-subtitle{font-size:.875em;margin-bottom:.5em;margin-top:.2em}div.quarto-post .body .description{font-size:.9em}div.quarto-post a{color:#212529;display:flex;flex-direction:column;text-decoration:none}div.quarto-post a div.description{flex-shrink:0}div.quarto-post .metadata{display:flex;flex-direction:column;font-size:.8em;font-family:var(--bs-font-sans-serif);flex-basis:33%}div.quarto-post .listing-categories{display:flex;flex-wrap:wrap;padding-bottom:5px}div.quarto-post .listing-categories .listing-category{color:#6c757d;border:solid 1px #dee2e6;border-radius:.25rem;text-transform:uppercase;font-size:.65em;padding-left:.5em;padding-right:.5em;padding-top:.15em;padding-bottom:.15em;cursor:pointer;margin-right:4px;margin-bottom:4px}div.quarto-post .listing-description{margin-bottom:.5em}div.quarto-about-jolla{display:flex !important;flex-direction:column;align-items:center;margin-top:10%;padding-bottom:1em}div.quarto-about-jolla .about-image{object-fit:cover;margin-left:auto;margin-right:auto;margin-bottom:1.5em}div.quarto-about-jolla img.round{border-radius:50%}div.quarto-about-jolla img.rounded{border-radius:10px}div.quarto-about-jolla .quarto-title h1.title,div.quarto-about-jolla .quarto-title .title.h1{text-align:center}div.quarto-about-jolla .quarto-title .description{text-align:center}div.quarto-about-jolla h2,div.quarto-about-jolla .h2{border-bottom:none}div.quarto-about-jolla .about-sep{width:60%}div.quarto-about-jolla main{text-align:center}div.quarto-about-jolla .about-links{display:flex}@media(min-width: 992px){div.quarto-about-jolla .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-jolla .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-jolla .about-link{color:#4e5862;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-jolla .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-jolla .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-jolla .about-link:hover{color:#18bc9c}div.quarto-about-jolla .about-link i.bi{margin-right:.15em}div.quarto-about-solana{display:flex !important;flex-direction:column;padding-top:3em !important;padding-bottom:1em}div.quarto-about-solana .about-entity{display:flex !important;align-items:start;justify-content:space-between}@media(min-width: 992px){div.quarto-about-solana .about-entity{flex-direction:row}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity{flex-direction:column-reverse;align-items:center;text-align:center}}div.quarto-about-solana .about-entity .entity-contents{display:flex;flex-direction:column}@media(max-width: 767.98px){div.quarto-about-solana .about-entity .entity-contents{width:100%}}div.quarto-about-solana .about-entity .about-image{object-fit:cover}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-image{margin-bottom:1.5em}}div.quarto-about-solana .about-entity img.round{border-radius:50%}div.quarto-about-solana .about-entity img.rounded{border-radius:10px}div.quarto-about-solana .about-entity .about-links{display:flex;justify-content:left;padding-bottom:1.2em}@media(min-width: 992px){div.quarto-about-solana .about-entity .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-solana .about-entity .about-link{color:#4e5862;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-solana .about-entity .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-solana .about-entity .about-link:hover{color:#18bc9c}div.quarto-about-solana .about-entity .about-link i.bi{margin-right:.15em}div.quarto-about-solana .about-contents{padding-right:1.5em;flex-basis:0;flex-grow:1}div.quarto-about-solana .about-contents main.content{margin-top:0}div.quarto-about-solana .about-contents h2,div.quarto-about-solana .about-contents .h2{border-bottom:none}div.quarto-about-trestles{display:flex !important;flex-direction:row;padding-top:3em !important;padding-bottom:1em}@media(max-width: 991.98px){div.quarto-about-trestles{flex-direction:column;padding-top:0em !important}}div.quarto-about-trestles .about-entity{display:flex !important;flex-direction:column;align-items:center;text-align:center;padding-right:1em}@media(min-width: 992px){div.quarto-about-trestles .about-entity{flex:0 0 42%}}div.quarto-about-trestles .about-entity .about-image{object-fit:cover;margin-bottom:1.5em}div.quarto-about-trestles .about-entity img.round{border-radius:50%}div.quarto-about-trestles .about-entity img.rounded{border-radius:10px}div.quarto-about-trestles .about-entity .about-links{display:flex;justify-content:center}@media(min-width: 992px){div.quarto-about-trestles .about-entity .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-trestles .about-entity .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-trestles .about-entity .about-link{color:#4e5862;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-trestles .about-entity .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-trestles .about-entity .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-trestles .about-entity .about-link:hover{color:#18bc9c}div.quarto-about-trestles .about-entity .about-link i.bi{margin-right:.15em}div.quarto-about-trestles .about-contents{flex-basis:0;flex-grow:1}div.quarto-about-trestles .about-contents h2,div.quarto-about-trestles .about-contents .h2{border-bottom:none}@media(min-width: 992px){div.quarto-about-trestles .about-contents{border-left:solid 1px #dee2e6;padding-left:1.5em}}div.quarto-about-trestles .about-contents main.content{margin-top:0}div.quarto-about-marquee{padding-bottom:1em}div.quarto-about-marquee .about-contents{display:flex;flex-direction:column}div.quarto-about-marquee .about-image{max-height:550px;margin-bottom:1.5em;object-fit:cover}div.quarto-about-marquee img.round{border-radius:50%}div.quarto-about-marquee img.rounded{border-radius:10px}div.quarto-about-marquee h2,div.quarto-about-marquee .h2{border-bottom:none}div.quarto-about-marquee .about-links{display:flex;justify-content:center;padding-top:1.5em}@media(min-width: 992px){div.quarto-about-marquee .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-marquee .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-marquee .about-link{color:#4e5862;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-marquee .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-marquee .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-marquee .about-link:hover{color:#18bc9c}div.quarto-about-marquee .about-link i.bi{margin-right:.15em}@media(min-width: 992px){div.quarto-about-marquee .about-link{border:none}}div.quarto-about-broadside{display:flex;flex-direction:column;padding-bottom:1em}div.quarto-about-broadside .about-main{display:flex !important;padding-top:0 !important}@media(min-width: 992px){div.quarto-about-broadside .about-main{flex-direction:row;align-items:flex-start}}@media(max-width: 991.98px){div.quarto-about-broadside .about-main{flex-direction:column}}@media(max-width: 991.98px){div.quarto-about-broadside .about-main .about-entity{flex-shrink:0;width:100%;height:450px;margin-bottom:1.5em;background-size:cover;background-repeat:no-repeat}}@media(min-width: 992px){div.quarto-about-broadside .about-main .about-entity{flex:0 10 50%;margin-right:1.5em;width:100%;height:100%;background-size:100%;background-repeat:no-repeat}}div.quarto-about-broadside .about-main .about-contents{padding-top:14px;flex:0 0 50%}div.quarto-about-broadside h2,div.quarto-about-broadside .h2{border-bottom:none}div.quarto-about-broadside .about-sep{margin-top:1.5em;width:60%;align-self:center}div.quarto-about-broadside .about-links{display:flex;justify-content:center;column-gap:20px;padding-top:1.5em}@media(min-width: 992px){div.quarto-about-broadside .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-broadside .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-broadside .about-link{color:#4e5862;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-broadside .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-broadside .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-broadside .about-link:hover{color:#18bc9c}div.quarto-about-broadside .about-link i.bi{margin-right:.15em}@media(min-width: 992px){div.quarto-about-broadside .about-link{border:none}}.tippy-box[data-theme~=quarto]{background-color:#fff;color:#212529;border-radius:.25rem;border:solid 1px #dee2e6;font-size:.875rem}.tippy-box[data-theme~=quarto] .tippy-arrow{color:#dee2e6}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:-1px}.tippy-box[data-placement^=bottom]>.tippy-content{padding:.75em 1em;z-index:1}.top-right{position:absolute;top:1em;right:1em}.hidden{display:none !important}.zindex-bottom{z-index:-1 !important}.quarto-layout-panel{margin-bottom:1em}.quarto-layout-panel>figure{width:100%}.quarto-layout-panel>figure>figcaption,.quarto-layout-panel>.panel-caption{margin-top:10pt}.quarto-layout-panel>.table-caption{margin-top:0px}.table-caption p{margin-bottom:.5em}.quarto-layout-row{display:flex;flex-direction:row;align-items:flex-start}.quarto-layout-valign-top{align-items:flex-start}.quarto-layout-valign-bottom{align-items:flex-end}.quarto-layout-valign-center{align-items:center}.quarto-layout-cell{position:relative;margin-right:20px}.quarto-layout-cell:last-child{margin-right:0}.quarto-layout-cell figure,.quarto-layout-cell>p{margin:.2em}.quarto-layout-cell img{max-width:100%}.quarto-layout-cell .html-widget{width:100% !important}.quarto-layout-cell div figure p{margin:0}.quarto-layout-cell figure{display:inline-block;margin-inline-start:0;margin-inline-end:0}.quarto-layout-cell table{display:inline-table}.quarto-layout-cell-subref figcaption,figure .quarto-layout-row figure figcaption{text-align:center;font-style:italic}.quarto-figure{position:relative;margin-bottom:1em}.quarto-figure>figure{width:100%;margin-bottom:0}.quarto-figure-left>figure>p{text-align:left}.quarto-figure-center>figure>p{text-align:center}.quarto-figure-right>figure>p{text-align:right}figure>p:empty{display:none}figure>p:first-child{margin-top:0;margin-bottom:0}figure>figcaption{margin-top:.5em}div[id^=tbl-]{position:relative}.quarto-figure>.anchorjs-link,div[id^=tbl-]>.anchorjs-link{position:absolute;top:0;right:0}.quarto-figure:hover>.anchorjs-link,div[id^=tbl-]:hover>.anchorjs-link,h2:hover>.anchorjs-link,.h2:hover>.anchorjs-link,h3:hover>.anchorjs-link,.h3:hover>.anchorjs-link,h4:hover>.anchorjs-link,.h4:hover>.anchorjs-link,h5:hover>.anchorjs-link,.h5:hover>.anchorjs-link,h6:hover>.anchorjs-link,.h6:hover>.anchorjs-link,.reveal-anchorjs-link>.anchorjs-link{opacity:1}#title-block-header{margin-block-end:1rem;position:relative;margin-top:-1px}#title-block-header .abstract{margin-block-start:1rem}#title-block-header .abstract .abstract-title{font-weight:600}#title-block-header a{text-decoration:none}#title-block-header .author,#title-block-header .date,#title-block-header .doi{margin-block-end:.2rem}#title-block-header .quarto-title-block>div{display:flex}#title-block-header .quarto-title-block>div>h1,#title-block-header .quarto-title-block>div>.h1{flex-grow:1}#title-block-header .quarto-title-block>div>button{flex-shrink:0;height:2.25rem;margin-top:0}@media(min-width: 992px){#title-block-header .quarto-title-block>div>button{margin-top:5px}}tr.header>th>p:last-of-type{margin-bottom:0px}table,.table{caption-side:top;margin-bottom:1.5rem}caption,.table-caption{padding-top:.5rem;padding-bottom:.5rem;text-align:center}.utterances{max-width:none;margin-left:-8px}iframe{margin-bottom:1em}details{margin-bottom:1em}details[show]{margin-bottom:0}details>summary{color:#6c757d}details>summary>p:only-child{display:inline}pre.sourceCode,code.sourceCode{position:relative}p code:not(.sourceCode){white-space:pre-wrap}code{white-space:pre}@media print{code{white-space:pre-wrap}}pre>code{display:block}pre>code.sourceCode{white-space:pre}pre>code.sourceCode>span>a:first-child::before{text-decoration:none}pre.code-overflow-wrap>code.sourceCode{white-space:pre-wrap}pre.code-overflow-scroll>code.sourceCode{white-space:pre}code a:any-link{color:inherit;text-decoration:none}code a:hover{color:inherit;text-decoration:underline}ul.task-list{padding-left:1em}[data-tippy-root]{display:inline-block}.tippy-content .footnote-back{display:none}.quarto-embedded-source-code{display:none}.quarto-unresolved-ref{font-weight:600}.quarto-cover-image{max-width:35%;float:right;margin-left:30px}.cell-output-display .widget-subarea{margin-bottom:1em}.cell-output-display:not(.no-overflow-x){overflow-x:auto}.panel-input{margin-bottom:1em}.panel-input>div,.panel-input>div>div{display:inline-block;vertical-align:top;padding-right:12px}.panel-input>p:last-child{margin-bottom:0}.layout-sidebar{margin-bottom:1em}.layout-sidebar .tab-content{border:none}.tab-content>.page-columns.active{display:grid}div.sourceCode>iframe{width:100%;height:300px;margin-bottom:-0.5em}div.ansi-escaped-output{font-family:monospace;display:block}/*! +* +* ansi colors from IPython notebook's +* +*/.ansi-black-fg{color:#3e424d}.ansi-black-bg{background-color:#3e424d}.ansi-black-intense-fg{color:#282c36}.ansi-black-intense-bg{background-color:#282c36}.ansi-red-fg{color:#e75c58}.ansi-red-bg{background-color:#e75c58}.ansi-red-intense-fg{color:#b22b31}.ansi-red-intense-bg{background-color:#b22b31}.ansi-green-fg{color:#00a250}.ansi-green-bg{background-color:#00a250}.ansi-green-intense-fg{color:#007427}.ansi-green-intense-bg{background-color:#007427}.ansi-yellow-fg{color:#ddb62b}.ansi-yellow-bg{background-color:#ddb62b}.ansi-yellow-intense-fg{color:#b27d12}.ansi-yellow-intense-bg{background-color:#b27d12}.ansi-blue-fg{color:#208ffb}.ansi-blue-bg{background-color:#208ffb}.ansi-blue-intense-fg{color:#0065ca}.ansi-blue-intense-bg{background-color:#0065ca}.ansi-magenta-fg{color:#d160c4}.ansi-magenta-bg{background-color:#d160c4}.ansi-magenta-intense-fg{color:#a03196}.ansi-magenta-intense-bg{background-color:#a03196}.ansi-cyan-fg{color:#60c6c8}.ansi-cyan-bg{background-color:#60c6c8}.ansi-cyan-intense-fg{color:#258f8f}.ansi-cyan-intense-bg{background-color:#258f8f}.ansi-white-fg{color:#c5c1b4}.ansi-white-bg{background-color:#c5c1b4}.ansi-white-intense-fg{color:#a1a6b2}.ansi-white-intense-bg{background-color:#a1a6b2}.ansi-default-inverse-fg{color:#fff}.ansi-default-inverse-bg{background-color:#000}.ansi-bold{font-weight:bold}.ansi-underline{text-decoration:underline}:root{--quarto-body-bg: #fff;--quarto-body-color: #212529;--quarto-text-muted: #6c757d;--quarto-border-color: #dee2e6;--quarto-border-width: 1px;--quarto-border-radius: 0.25rem}table.gt_table{color:var(--quarto-body-color);font-size:1em;width:100%;background-color:transparent;border-top-width:inherit;border-bottom-width:inherit;border-color:var(--quarto-border-color)}table.gt_table th.gt_column_spanner_outer{color:var(--quarto-body-color);background-color:transparent;border-top-width:inherit;border-bottom-width:inherit;border-color:var(--quarto-border-color)}table.gt_table th.gt_col_heading{color:var(--quarto-body-color);font-weight:bold;background-color:transparent}table.gt_table thead.gt_col_headings{border-bottom:1px solid currentColor;border-top-width:inherit;border-top-color:var(--quarto-border-color)}table.gt_table thead.gt_col_headings:not(:first-child){border-top-width:1px;border-top-color:var(--quarto-border-color)}table.gt_table td.gt_row{border-bottom-width:1px;border-bottom-color:var(--quarto-border-color);border-top-width:0px}table.gt_table tbody.gt_table_body{border-top-width:1px;border-bottom-width:1px;border-bottom-color:var(--quarto-border-color);border-top-color:currentColor}div.columns{display:initial;gap:initial}div.column{display:inline-block;overflow-x:initial;vertical-align:top;width:50%}@media print{:root{font-size:11pt}#quarto-sidebar,#TOC,.nav-page{display:none}.page-columns .content{grid-column-start:page-start}.fixed-top{position:relative}.panel-caption,.figure-caption,figcaption{color:#666}}.code-copy-button{position:absolute;top:0;right:0;border:0;margin-top:5px;margin-right:5px;background-color:transparent}.code-copy-button:focus{outline:none}.code-copy-button-tooltip{font-size:.75em}pre.sourceCode:hover>.code-copy-button>.bi::before{display:inline-block;height:1rem;width:1rem;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:1rem 1rem}pre.sourceCode:hover>.code-copy-button-checked>.bi::before{background-image:url('data:image/svg+xml,')}pre.sourceCode:hover>.code-copy-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}pre.sourceCode:hover>.code-copy-button-checked:hover>.bi::before{background-image:url('data:image/svg+xml,')}main ol ol,main ul ul,main ol ul,main ul ol{margin-bottom:1em}body{margin:0}main.page-columns>header>h1.title,main.page-columns>header>.title.h1{margin-bottom:0}@media(min-width: 992px){body .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.fullcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] 35px [page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.slimcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.listing:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(1200px - 3em)) [body-content-end] 3em [body-end] 50px [body-end-outset] minmax(0px, 250px) [page-end-inset] 50px [page-end] 1fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 175px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 175px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] minmax(25px, 50px) [page-start-inset] minmax(50px, 150px) [body-start-outset] minmax(25px, 50px) [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] minmax(25px, 50px) [body-end-outset] minmax(50px, 150px) [page-end-inset] minmax(25px, 50px) [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc( 1000px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 100px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc( 1000px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 50px [page-start-inset] minmax(50px, 150px) [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(450px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc( 1000px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 100px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 50px [page-start-inset] minmax(50px, 150px) [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(450px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(50px, 150px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] minmax(25px, 50px) [page-start-inset] minmax(50px, 150px) [body-start-outset] minmax(25px, 50px) [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] minmax(25px, 50px) [body-end-outset] minmax(50px, 150px) [page-end-inset] minmax(25px, 50px) [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}}@media(max-width: 991.98px){body .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.fullcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.slimcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.listing:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(1200px - 3em)) [body-content-end body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 145px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(750px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 145px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(750px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(75px, 150px) [page-end-inset] 25px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc( 1000px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 4fr [screen-end-inset] 1.5em [screen-end]}body.floating.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(75px, 150px) [page-end-inset] 25px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}}@media(max-width: 767.98px){body .page-columns,body.fullcontent:not(.floating):not(.docked) .page-columns,body.slimcontent:not(.floating):not(.docked) .page-columns,body.docked .page-columns,body.docked.slimcontent .page-columns,body.docked.fullcontent .page-columns,body.floating .page-columns,body.floating.slimcontent .page-columns,body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}nav[role=doc-toc]{display:none}}body,.page-row-navigation{grid-template-rows:[page-top] max-content [contents-top] max-content [contents-bottom] max-content [page-bottom]}.page-rows-contents{grid-template-rows:[content-top] minmax(max-content, 1fr) [content-bottom] minmax(60px, max-content) [page-bottom]}.page-full{grid-column:screen-start/screen-end !important}.page-columns>*{grid-column:body-content-start/body-content-end}.page-columns.column-page>*{grid-column:page-start/page-end}.page-columns.column-page-left>*{grid-column:page-start/body-content-end}.page-columns.column-page-right>*{grid-column:body-content-start/page-end}.page-rows{grid-auto-rows:auto}.header{grid-column:screen-start/screen-end;grid-row:page-top/contents-top}#quarto-content{padding:0;grid-column:screen-start/screen-end;grid-row:contents-top/contents-bottom}body.floating .sidebar.sidebar-navigation{grid-column:page-start/body-start;grid-row:content-top/page-bottom}body.docked .sidebar.sidebar-navigation{grid-column:screen-start/body-start;grid-row:content-top/page-bottom}.sidebar.toc-left{grid-column:page-start/body-start;grid-row:content-top/page-bottom}.sidebar.margin-sidebar{grid-column:body-end/page-end;grid-row:content-top/page-bottom}.page-columns .content{grid-column:body-content-start/body-content-end;grid-row:content-top/content-bottom;align-content:flex-start}.page-columns .page-navigation{grid-column:body-content-start/body-content-end;grid-row:content-bottom/page-bottom}.page-columns .footer{grid-column:screen-start/screen-end;grid-row:contents-bottom/page-bottom}.page-columns .column-body{grid-column:body-content-start/body-content-end}.page-columns .column-body-fullbleed{grid-column:body-start/body-end}.page-columns .column-body-outset{grid-column:body-start-outset/body-end-outset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-body-outset table{background:#fff}.page-columns .column-body-outset-left{grid-column:body-start-outset/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-body-outset-left table{background:#fff}.page-columns .column-body-outset-right{grid-column:body-content-start/body-end-outset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-body-outset-right table{background:#fff}.page-columns .column-page{grid-column:page-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page table{background:#fff}.page-columns .column-page-inset{grid-column:page-start-inset/page-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-inset table{background:#fff}.page-columns .column-page-inset-left{grid-column:page-start-inset/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-inset-left table{background:#fff}.page-columns .column-page-inset-right{grid-column:body-content-start/page-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-inset-right figcaption table{background:#fff}.page-columns .column-page-left{grid-column:page-start/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-left table{background:#fff}.page-columns .column-page-right{grid-column:body-content-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-right figcaption table{background:#fff}#quarto-content.page-columns #quarto-margin-sidebar,#quarto-content.page-columns #quarto-sidebar{z-index:1}@media(max-width: 991.98px){#quarto-content.page-columns #quarto-margin-sidebar.collapse,#quarto-content.page-columns #quarto-sidebar.collapse{z-index:1055}}#quarto-content.page-columns main.column-page,#quarto-content.page-columns main.column-page-right,#quarto-content.page-columns main.column-page-left{z-index:0}.page-columns .column-screen-inset{grid-column:screen-start-inset/screen-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset table{background:#fff}.page-columns .column-screen-inset-left{grid-column:screen-start-inset/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-left table{background:#fff}.page-columns .column-screen-inset-right{grid-column:body-content-start/screen-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:screen-start/screen-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:screen-start/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/screen-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-right table{background:#fff}.page-columns .column-screen-inset-shaded{grid-column:screen-start/screen-end;padding:1em;background:#ecf0f1;z-index:998;transform:translate3d(0, 0, 0);margin-bottom:1em}.zindex-content{z-index:998;transform:translate3d(0, 0, 0)}.zindex-modal{z-index:1055;transform:translate3d(0, 0, 0)}.zindex-over-content{z-index:999;transform:translate3d(0, 0, 0)}img.img-fluid.column-screen,img.img-fluid.column-screen-inset-shaded,img.img-fluid.column-screen-inset,img.img-fluid.column-screen-inset-left,img.img-fluid.column-screen-inset-right,img.img-fluid.column-screen-left,img.img-fluid.column-screen-right{width:100%}@media(min-width: 992px){.margin-caption,div.aside,aside,.column-margin{grid-column:body-end/page-end !important;z-index:998}.column-sidebar{grid-column:page-start/body-start !important;z-index:998}.column-leftmargin{grid-column:screen-start-inset/body-start !important;z-index:998}.no-row-height{height:1em;overflow:visible}}@media(max-width: 991.98px){.margin-caption,div.aside,aside,.column-margin{grid-column:body-end/page-end !important;z-index:998}.no-row-height{height:1em;overflow:visible}.page-columns.page-full{overflow:visible}.page-columns.toc-left .margin-caption,.page-columns.toc-left div.aside,.page-columns.toc-left aside,.page-columns.toc-left .column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;transform:translate3d(0, 0, 0)}.page-columns.toc-left .no-row-height{height:initial;overflow:initial}}@media(max-width: 767.98px){.margin-caption,div.aside,aside,.column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;transform:translate3d(0, 0, 0)}.no-row-height{height:initial;overflow:initial}#quarto-margin-sidebar{display:none}.hidden-sm{display:none}}.panel-grid{display:grid;grid-template-rows:repeat(1, 1fr);grid-template-columns:repeat(24, 1fr);gap:1em}.panel-grid .g-col-1{grid-column:auto/span 1}.panel-grid .g-col-2{grid-column:auto/span 2}.panel-grid .g-col-3{grid-column:auto/span 3}.panel-grid .g-col-4{grid-column:auto/span 4}.panel-grid .g-col-5{grid-column:auto/span 5}.panel-grid .g-col-6{grid-column:auto/span 6}.panel-grid .g-col-7{grid-column:auto/span 7}.panel-grid .g-col-8{grid-column:auto/span 8}.panel-grid .g-col-9{grid-column:auto/span 9}.panel-grid .g-col-10{grid-column:auto/span 10}.panel-grid .g-col-11{grid-column:auto/span 11}.panel-grid .g-col-12{grid-column:auto/span 12}.panel-grid .g-col-13{grid-column:auto/span 13}.panel-grid .g-col-14{grid-column:auto/span 14}.panel-grid .g-col-15{grid-column:auto/span 15}.panel-grid .g-col-16{grid-column:auto/span 16}.panel-grid .g-col-17{grid-column:auto/span 17}.panel-grid .g-col-18{grid-column:auto/span 18}.panel-grid .g-col-19{grid-column:auto/span 19}.panel-grid .g-col-20{grid-column:auto/span 20}.panel-grid .g-col-21{grid-column:auto/span 21}.panel-grid .g-col-22{grid-column:auto/span 22}.panel-grid .g-col-23{grid-column:auto/span 23}.panel-grid .g-col-24{grid-column:auto/span 24}.panel-grid .g-start-1{grid-column-start:1}.panel-grid .g-start-2{grid-column-start:2}.panel-grid .g-start-3{grid-column-start:3}.panel-grid .g-start-4{grid-column-start:4}.panel-grid .g-start-5{grid-column-start:5}.panel-grid .g-start-6{grid-column-start:6}.panel-grid .g-start-7{grid-column-start:7}.panel-grid .g-start-8{grid-column-start:8}.panel-grid .g-start-9{grid-column-start:9}.panel-grid .g-start-10{grid-column-start:10}.panel-grid .g-start-11{grid-column-start:11}.panel-grid .g-start-12{grid-column-start:12}.panel-grid .g-start-13{grid-column-start:13}.panel-grid .g-start-14{grid-column-start:14}.panel-grid .g-start-15{grid-column-start:15}.panel-grid .g-start-16{grid-column-start:16}.panel-grid .g-start-17{grid-column-start:17}.panel-grid .g-start-18{grid-column-start:18}.panel-grid .g-start-19{grid-column-start:19}.panel-grid .g-start-20{grid-column-start:20}.panel-grid .g-start-21{grid-column-start:21}.panel-grid .g-start-22{grid-column-start:22}.panel-grid .g-start-23{grid-column-start:23}@media(min-width: 576px){.panel-grid .g-col-sm-1{grid-column:auto/span 1}.panel-grid .g-col-sm-2{grid-column:auto/span 2}.panel-grid .g-col-sm-3{grid-column:auto/span 3}.panel-grid .g-col-sm-4{grid-column:auto/span 4}.panel-grid .g-col-sm-5{grid-column:auto/span 5}.panel-grid .g-col-sm-6{grid-column:auto/span 6}.panel-grid .g-col-sm-7{grid-column:auto/span 7}.panel-grid .g-col-sm-8{grid-column:auto/span 8}.panel-grid .g-col-sm-9{grid-column:auto/span 9}.panel-grid .g-col-sm-10{grid-column:auto/span 10}.panel-grid .g-col-sm-11{grid-column:auto/span 11}.panel-grid .g-col-sm-12{grid-column:auto/span 12}.panel-grid .g-col-sm-13{grid-column:auto/span 13}.panel-grid .g-col-sm-14{grid-column:auto/span 14}.panel-grid .g-col-sm-15{grid-column:auto/span 15}.panel-grid .g-col-sm-16{grid-column:auto/span 16}.panel-grid .g-col-sm-17{grid-column:auto/span 17}.panel-grid .g-col-sm-18{grid-column:auto/span 18}.panel-grid .g-col-sm-19{grid-column:auto/span 19}.panel-grid .g-col-sm-20{grid-column:auto/span 20}.panel-grid .g-col-sm-21{grid-column:auto/span 21}.panel-grid .g-col-sm-22{grid-column:auto/span 22}.panel-grid .g-col-sm-23{grid-column:auto/span 23}.panel-grid .g-col-sm-24{grid-column:auto/span 24}.panel-grid .g-start-sm-1{grid-column-start:1}.panel-grid .g-start-sm-2{grid-column-start:2}.panel-grid .g-start-sm-3{grid-column-start:3}.panel-grid .g-start-sm-4{grid-column-start:4}.panel-grid .g-start-sm-5{grid-column-start:5}.panel-grid .g-start-sm-6{grid-column-start:6}.panel-grid .g-start-sm-7{grid-column-start:7}.panel-grid .g-start-sm-8{grid-column-start:8}.panel-grid .g-start-sm-9{grid-column-start:9}.panel-grid .g-start-sm-10{grid-column-start:10}.panel-grid .g-start-sm-11{grid-column-start:11}.panel-grid .g-start-sm-12{grid-column-start:12}.panel-grid .g-start-sm-13{grid-column-start:13}.panel-grid .g-start-sm-14{grid-column-start:14}.panel-grid .g-start-sm-15{grid-column-start:15}.panel-grid .g-start-sm-16{grid-column-start:16}.panel-grid .g-start-sm-17{grid-column-start:17}.panel-grid .g-start-sm-18{grid-column-start:18}.panel-grid .g-start-sm-19{grid-column-start:19}.panel-grid .g-start-sm-20{grid-column-start:20}.panel-grid .g-start-sm-21{grid-column-start:21}.panel-grid .g-start-sm-22{grid-column-start:22}.panel-grid .g-start-sm-23{grid-column-start:23}}@media(min-width: 768px){.panel-grid .g-col-md-1{grid-column:auto/span 1}.panel-grid .g-col-md-2{grid-column:auto/span 2}.panel-grid .g-col-md-3{grid-column:auto/span 3}.panel-grid .g-col-md-4{grid-column:auto/span 4}.panel-grid .g-col-md-5{grid-column:auto/span 5}.panel-grid .g-col-md-6{grid-column:auto/span 6}.panel-grid .g-col-md-7{grid-column:auto/span 7}.panel-grid .g-col-md-8{grid-column:auto/span 8}.panel-grid .g-col-md-9{grid-column:auto/span 9}.panel-grid .g-col-md-10{grid-column:auto/span 10}.panel-grid .g-col-md-11{grid-column:auto/span 11}.panel-grid .g-col-md-12{grid-column:auto/span 12}.panel-grid .g-col-md-13{grid-column:auto/span 13}.panel-grid .g-col-md-14{grid-column:auto/span 14}.panel-grid .g-col-md-15{grid-column:auto/span 15}.panel-grid .g-col-md-16{grid-column:auto/span 16}.panel-grid .g-col-md-17{grid-column:auto/span 17}.panel-grid .g-col-md-18{grid-column:auto/span 18}.panel-grid .g-col-md-19{grid-column:auto/span 19}.panel-grid .g-col-md-20{grid-column:auto/span 20}.panel-grid .g-col-md-21{grid-column:auto/span 21}.panel-grid .g-col-md-22{grid-column:auto/span 22}.panel-grid .g-col-md-23{grid-column:auto/span 23}.panel-grid .g-col-md-24{grid-column:auto/span 24}.panel-grid .g-start-md-1{grid-column-start:1}.panel-grid .g-start-md-2{grid-column-start:2}.panel-grid .g-start-md-3{grid-column-start:3}.panel-grid .g-start-md-4{grid-column-start:4}.panel-grid .g-start-md-5{grid-column-start:5}.panel-grid .g-start-md-6{grid-column-start:6}.panel-grid .g-start-md-7{grid-column-start:7}.panel-grid .g-start-md-8{grid-column-start:8}.panel-grid .g-start-md-9{grid-column-start:9}.panel-grid .g-start-md-10{grid-column-start:10}.panel-grid .g-start-md-11{grid-column-start:11}.panel-grid .g-start-md-12{grid-column-start:12}.panel-grid .g-start-md-13{grid-column-start:13}.panel-grid .g-start-md-14{grid-column-start:14}.panel-grid .g-start-md-15{grid-column-start:15}.panel-grid .g-start-md-16{grid-column-start:16}.panel-grid .g-start-md-17{grid-column-start:17}.panel-grid .g-start-md-18{grid-column-start:18}.panel-grid .g-start-md-19{grid-column-start:19}.panel-grid .g-start-md-20{grid-column-start:20}.panel-grid .g-start-md-21{grid-column-start:21}.panel-grid .g-start-md-22{grid-column-start:22}.panel-grid .g-start-md-23{grid-column-start:23}}@media(min-width: 992px){.panel-grid .g-col-lg-1{grid-column:auto/span 1}.panel-grid .g-col-lg-2{grid-column:auto/span 2}.panel-grid .g-col-lg-3{grid-column:auto/span 3}.panel-grid .g-col-lg-4{grid-column:auto/span 4}.panel-grid .g-col-lg-5{grid-column:auto/span 5}.panel-grid .g-col-lg-6{grid-column:auto/span 6}.panel-grid .g-col-lg-7{grid-column:auto/span 7}.panel-grid .g-col-lg-8{grid-column:auto/span 8}.panel-grid .g-col-lg-9{grid-column:auto/span 9}.panel-grid .g-col-lg-10{grid-column:auto/span 10}.panel-grid .g-col-lg-11{grid-column:auto/span 11}.panel-grid .g-col-lg-12{grid-column:auto/span 12}.panel-grid .g-col-lg-13{grid-column:auto/span 13}.panel-grid .g-col-lg-14{grid-column:auto/span 14}.panel-grid .g-col-lg-15{grid-column:auto/span 15}.panel-grid .g-col-lg-16{grid-column:auto/span 16}.panel-grid .g-col-lg-17{grid-column:auto/span 17}.panel-grid .g-col-lg-18{grid-column:auto/span 18}.panel-grid .g-col-lg-19{grid-column:auto/span 19}.panel-grid .g-col-lg-20{grid-column:auto/span 20}.panel-grid .g-col-lg-21{grid-column:auto/span 21}.panel-grid .g-col-lg-22{grid-column:auto/span 22}.panel-grid .g-col-lg-23{grid-column:auto/span 23}.panel-grid .g-col-lg-24{grid-column:auto/span 24}.panel-grid .g-start-lg-1{grid-column-start:1}.panel-grid .g-start-lg-2{grid-column-start:2}.panel-grid .g-start-lg-3{grid-column-start:3}.panel-grid .g-start-lg-4{grid-column-start:4}.panel-grid .g-start-lg-5{grid-column-start:5}.panel-grid .g-start-lg-6{grid-column-start:6}.panel-grid .g-start-lg-7{grid-column-start:7}.panel-grid .g-start-lg-8{grid-column-start:8}.panel-grid .g-start-lg-9{grid-column-start:9}.panel-grid .g-start-lg-10{grid-column-start:10}.panel-grid .g-start-lg-11{grid-column-start:11}.panel-grid .g-start-lg-12{grid-column-start:12}.panel-grid .g-start-lg-13{grid-column-start:13}.panel-grid .g-start-lg-14{grid-column-start:14}.panel-grid .g-start-lg-15{grid-column-start:15}.panel-grid .g-start-lg-16{grid-column-start:16}.panel-grid .g-start-lg-17{grid-column-start:17}.panel-grid .g-start-lg-18{grid-column-start:18}.panel-grid .g-start-lg-19{grid-column-start:19}.panel-grid .g-start-lg-20{grid-column-start:20}.panel-grid .g-start-lg-21{grid-column-start:21}.panel-grid .g-start-lg-22{grid-column-start:22}.panel-grid .g-start-lg-23{grid-column-start:23}}@media(min-width: 1200px){.panel-grid .g-col-xl-1{grid-column:auto/span 1}.panel-grid .g-col-xl-2{grid-column:auto/span 2}.panel-grid .g-col-xl-3{grid-column:auto/span 3}.panel-grid .g-col-xl-4{grid-column:auto/span 4}.panel-grid .g-col-xl-5{grid-column:auto/span 5}.panel-grid .g-col-xl-6{grid-column:auto/span 6}.panel-grid .g-col-xl-7{grid-column:auto/span 7}.panel-grid .g-col-xl-8{grid-column:auto/span 8}.panel-grid .g-col-xl-9{grid-column:auto/span 9}.panel-grid .g-col-xl-10{grid-column:auto/span 10}.panel-grid .g-col-xl-11{grid-column:auto/span 11}.panel-grid .g-col-xl-12{grid-column:auto/span 12}.panel-grid .g-col-xl-13{grid-column:auto/span 13}.panel-grid .g-col-xl-14{grid-column:auto/span 14}.panel-grid .g-col-xl-15{grid-column:auto/span 15}.panel-grid .g-col-xl-16{grid-column:auto/span 16}.panel-grid .g-col-xl-17{grid-column:auto/span 17}.panel-grid .g-col-xl-18{grid-column:auto/span 18}.panel-grid .g-col-xl-19{grid-column:auto/span 19}.panel-grid .g-col-xl-20{grid-column:auto/span 20}.panel-grid .g-col-xl-21{grid-column:auto/span 21}.panel-grid .g-col-xl-22{grid-column:auto/span 22}.panel-grid .g-col-xl-23{grid-column:auto/span 23}.panel-grid .g-col-xl-24{grid-column:auto/span 24}.panel-grid .g-start-xl-1{grid-column-start:1}.panel-grid .g-start-xl-2{grid-column-start:2}.panel-grid .g-start-xl-3{grid-column-start:3}.panel-grid .g-start-xl-4{grid-column-start:4}.panel-grid .g-start-xl-5{grid-column-start:5}.panel-grid .g-start-xl-6{grid-column-start:6}.panel-grid .g-start-xl-7{grid-column-start:7}.panel-grid .g-start-xl-8{grid-column-start:8}.panel-grid .g-start-xl-9{grid-column-start:9}.panel-grid .g-start-xl-10{grid-column-start:10}.panel-grid .g-start-xl-11{grid-column-start:11}.panel-grid .g-start-xl-12{grid-column-start:12}.panel-grid .g-start-xl-13{grid-column-start:13}.panel-grid .g-start-xl-14{grid-column-start:14}.panel-grid .g-start-xl-15{grid-column-start:15}.panel-grid .g-start-xl-16{grid-column-start:16}.panel-grid .g-start-xl-17{grid-column-start:17}.panel-grid .g-start-xl-18{grid-column-start:18}.panel-grid .g-start-xl-19{grid-column-start:19}.panel-grid .g-start-xl-20{grid-column-start:20}.panel-grid .g-start-xl-21{grid-column-start:21}.panel-grid .g-start-xl-22{grid-column-start:22}.panel-grid .g-start-xl-23{grid-column-start:23}}@media(min-width: 1400px){.panel-grid .g-col-xxl-1{grid-column:auto/span 1}.panel-grid .g-col-xxl-2{grid-column:auto/span 2}.panel-grid .g-col-xxl-3{grid-column:auto/span 3}.panel-grid .g-col-xxl-4{grid-column:auto/span 4}.panel-grid .g-col-xxl-5{grid-column:auto/span 5}.panel-grid .g-col-xxl-6{grid-column:auto/span 6}.panel-grid .g-col-xxl-7{grid-column:auto/span 7}.panel-grid .g-col-xxl-8{grid-column:auto/span 8}.panel-grid .g-col-xxl-9{grid-column:auto/span 9}.panel-grid .g-col-xxl-10{grid-column:auto/span 10}.panel-grid .g-col-xxl-11{grid-column:auto/span 11}.panel-grid .g-col-xxl-12{grid-column:auto/span 12}.panel-grid .g-col-xxl-13{grid-column:auto/span 13}.panel-grid .g-col-xxl-14{grid-column:auto/span 14}.panel-grid .g-col-xxl-15{grid-column:auto/span 15}.panel-grid .g-col-xxl-16{grid-column:auto/span 16}.panel-grid .g-col-xxl-17{grid-column:auto/span 17}.panel-grid .g-col-xxl-18{grid-column:auto/span 18}.panel-grid .g-col-xxl-19{grid-column:auto/span 19}.panel-grid .g-col-xxl-20{grid-column:auto/span 20}.panel-grid .g-col-xxl-21{grid-column:auto/span 21}.panel-grid .g-col-xxl-22{grid-column:auto/span 22}.panel-grid .g-col-xxl-23{grid-column:auto/span 23}.panel-grid .g-col-xxl-24{grid-column:auto/span 24}.panel-grid .g-start-xxl-1{grid-column-start:1}.panel-grid .g-start-xxl-2{grid-column-start:2}.panel-grid .g-start-xxl-3{grid-column-start:3}.panel-grid .g-start-xxl-4{grid-column-start:4}.panel-grid .g-start-xxl-5{grid-column-start:5}.panel-grid .g-start-xxl-6{grid-column-start:6}.panel-grid .g-start-xxl-7{grid-column-start:7}.panel-grid .g-start-xxl-8{grid-column-start:8}.panel-grid .g-start-xxl-9{grid-column-start:9}.panel-grid .g-start-xxl-10{grid-column-start:10}.panel-grid .g-start-xxl-11{grid-column-start:11}.panel-grid .g-start-xxl-12{grid-column-start:12}.panel-grid .g-start-xxl-13{grid-column-start:13}.panel-grid .g-start-xxl-14{grid-column-start:14}.panel-grid .g-start-xxl-15{grid-column-start:15}.panel-grid .g-start-xxl-16{grid-column-start:16}.panel-grid .g-start-xxl-17{grid-column-start:17}.panel-grid .g-start-xxl-18{grid-column-start:18}.panel-grid .g-start-xxl-19{grid-column-start:19}.panel-grid .g-start-xxl-20{grid-column-start:20}.panel-grid .g-start-xxl-21{grid-column-start:21}.panel-grid .g-start-xxl-22{grid-column-start:22}.panel-grid .g-start-xxl-23{grid-column-start:23}}main{margin-top:1em;margin-bottom:1em}h1,.h1,h2,.h2{margin-top:2rem;margin-bottom:1rem}h1.title,.title.h1{margin-top:0}h2,.h2{border-bottom:1px solid #dee2e6;padding-bottom:.5rem}h3,.h3,h4,.h4{margin-top:1.5rem}.header-section-number{color:#5a6570}.nav-link.active .header-section-number{color:inherit}mark,.mark{padding:0em}.panel-caption,caption,.figure-caption{font-size:1rem}.panel-caption,.figure-caption,figcaption{color:#5a6570}.table-caption,caption{color:#212529}.quarto-layout-cell[data-ref-parent] caption{color:#5a6570}.column-margin figcaption,.margin-caption,div.aside,aside,.column-margin{color:#5a6570;font-size:.825rem}.panel-caption.margin-caption{text-align:inherit}.column-margin.column-container p{margin-bottom:0}.column-margin.column-container>*:not(.collapse){padding-top:.5em;padding-bottom:.5em;display:block}.column-margin.column-container>*.collapse:not(.show){display:none}@media(min-width: 768px){.column-margin.column-container .callout-margin-content:first-child{margin-top:4.5em}.column-margin.column-container .callout-margin-content-simple:first-child{margin-top:3.5em}}.margin-caption>*{padding-top:.5em;padding-bottom:.5em}@media(max-width: 767.98px){.quarto-layout-row{flex-direction:column}}.tab-content{margin-top:0px;border-left:#dee2e6 1px solid;border-right:#dee2e6 1px solid;border-bottom:#dee2e6 1px solid;margin-left:0;padding:1em;margin-bottom:1em}@media(max-width: 767.98px){.layout-sidebar{margin-left:0;margin-right:0}}.panel-sidebar,.panel-sidebar .form-control,.panel-input,.panel-input .form-control,.selectize-dropdown{font-size:.9rem}.panel-sidebar .form-control,.panel-input .form-control{padding-top:.1rem}.tab-pane div.sourceCode{margin-top:0px}.tab-pane>p{padding-top:1em}.tab-content>.tab-pane:not(.active){display:none !important}div.sourceCode{background-color:rgba(236,240,241,.65);border:1px solid rgba(236,240,241,.65);border-radius:.25rem}pre.sourceCode{background-color:transparent}pre.sourceCode{border:none;font-size:.875em;overflow:visible !important;padding:.4em}.callout pre.sourceCode{padding-left:0}div.sourceCode{overflow-y:hidden}.callout div.sourceCode{margin-left:initial}.blockquote{font-size:inherit;padding-left:1rem;padding-right:1.5rem;color:#5a6570}.blockquote h1:first-child,.blockquote .h1:first-child,.blockquote h2:first-child,.blockquote .h2:first-child,.blockquote h3:first-child,.blockquote .h3:first-child,.blockquote h4:first-child,.blockquote .h4:first-child,.blockquote h5:first-child,.blockquote .h5:first-child{margin-top:0}pre{background-color:initial;padding:initial;border:initial}p code:not(.sourceCode),li code:not(.sourceCode){background-color:#f6f6f6;padding:.2em}nav p code:not(.sourceCode),nav li code:not(.sourceCode){background-color:transparent;padding:0}#quarto-embedded-source-code-modal>.modal-dialog{max-width:1000px;padding-left:1.75rem;padding-right:1.75rem}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-body{padding:0}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-body div.sourceCode{margin:0;padding:.2rem .2rem;border-radius:0px;border:none}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-header{padding:.7rem}.code-tools-button{font-size:1rem;padding:.15rem .15rem;margin-left:5px;color:#6c757d;background-color:transparent;transition:initial;cursor:pointer}.code-tools-button>.bi::before{display:inline-block;height:1rem;width:1rem;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:1rem 1rem}.code-tools-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}#quarto-embedded-source-code-modal .code-copy-button>.bi::before{background-image:url('data:image/svg+xml,')}#quarto-embedded-source-code-modal .code-copy-button-checked>.bi::before{background-image:url('data:image/svg+xml,')}.sidebar{will-change:top;transition:top 200ms linear;position:sticky;overflow-y:auto;padding-top:1.2em;max-height:100vh}.sidebar.toc-left,.sidebar.margin-sidebar{top:0px;padding-top:1em}.sidebar.toc-left>*,.sidebar.margin-sidebar>*{padding-top:.5em}.sidebar.quarto-banner-title-block-sidebar>*{padding-top:1.65em}.sidebar nav[role=doc-toc]>h2,.sidebar nav[role=doc-toc]>.h2{font-size:.875rem;font-weight:400;margin-bottom:.5rem;margin-top:.3rem;font-family:inherit;border-bottom:0;padding-bottom:0;padding-top:0px}.sidebar nav[role=doc-toc]>ul a{border-left:1px solid #ecf0f1;padding-left:.6rem}.sidebar nav[role=doc-toc]>ul a:empty{display:none}.sidebar nav[role=doc-toc] ul{padding-left:0;list-style:none;font-size:.875rem;font-weight:300}.sidebar nav[role=doc-toc]>ul li a{line-height:1.1rem;padding-bottom:.2rem;padding-top:.2rem;color:inherit}.sidebar nav[role=doc-toc] ul>li>ul>li>a{padding-left:1.2em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>a{padding-left:2.4em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>a{padding-left:3.6em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>ul>li>a{padding-left:4.8em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>ul>li>ul>li>a{padding-left:6em}.sidebar nav[role=doc-toc] ul>li>ul>li>a.active{border-left:1px solid #18bc9c;color:#18bc9c !important}.sidebar nav[role=doc-toc] ul>li>a.active{border-left:1px solid #18bc9c;color:#18bc9c !important}kbd,.kbd{color:#212529;background-color:#f8f9fa;border:1px solid;border-radius:5px;border-color:#dee2e6}div.hanging-indent{margin-left:1em;text-indent:-1em}.citation a,.footnote-ref{text-decoration:none}.footnotes ol{padding-left:1em}.tippy-content>*{margin-bottom:.7em}.tippy-content>*:last-child{margin-bottom:0}.table a{word-break:break-word}.table>:not(:first-child){border-top-width:1px;border-top-color:#dee2e6}.table>thead{border-bottom:1px solid currentColor}.table>tbody{border-top:1px solid #dee2e6}.callout{margin-top:1.25rem;margin-bottom:1.25rem;border-radius:.25rem}.callout.callout-style-simple{padding:.4em .7em;border-left:5px solid;border-right:1px solid #dee2e6;border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.callout.callout-style-default{border-left:5px solid;border-right:1px solid #dee2e6;border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.callout .callout-body-container{flex-grow:1}.callout.callout-style-simple .callout-body{font-size:.9rem;font-weight:400}.callout.callout-style-default .callout-body{font-size:.9rem;font-weight:400}.callout.callout-captioned .callout-body{margin-top:.2em}.callout:not(.no-icon).callout-captioned.callout-style-simple .callout-body{padding-left:1.6em}.callout.callout-captioned>.callout-header{padding-top:.2em;margin-bottom:-0.2em}.callout.callout-style-simple>div.callout-header{border-bottom:none;font-size:.9rem;font-weight:600;opacity:75%}.callout.callout-style-default>div.callout-header{border-bottom:none;font-weight:600;opacity:85%;font-size:.9rem;padding-left:.5em;padding-right:.5em}.callout.callout-style-default div.callout-body{padding-left:.5em;padding-right:.5em}.callout.callout-style-default div.callout-body>:first-child{margin-top:.5em}.callout>div.callout-header[data-bs-toggle=collapse]{cursor:pointer}.callout.callout-style-default .callout-header[aria-expanded=false],.callout.callout-style-default .callout-header[aria-expanded=true]{padding-top:0px;margin-bottom:0px;align-items:center}.callout.callout-captioned .callout-body>:last-child:not(.sourceCode),.callout.callout-captioned .callout-body>div>:last-child:not(.sourceCode){margin-bottom:.5rem}.callout:not(.callout-captioned) .callout-body>:first-child,.callout:not(.callout-captioned) .callout-body>div>:first-child{margin-top:.25rem}.callout:not(.callout-captioned) .callout-body>:last-child,.callout:not(.callout-captioned) .callout-body>div>:last-child{margin-bottom:.2rem}.callout.callout-style-simple .callout-icon::before,.callout.callout-style-simple .callout-toggle::before{height:1rem;width:1rem;display:inline-block;content:"";background-repeat:no-repeat;background-size:1rem 1rem}.callout.callout-style-default .callout-icon::before,.callout.callout-style-default .callout-toggle::before{height:.9rem;width:.9rem;display:inline-block;content:"";background-repeat:no-repeat;background-size:.9rem .9rem}.callout.callout-style-default .callout-toggle::before{margin-top:5px}.callout .callout-btn-toggle .callout-toggle::before{transition:transform .2s linear}.callout .callout-header[aria-expanded=false] .callout-toggle::before{transform:rotate(-90deg)}.callout .callout-header[aria-expanded=true] .callout-toggle::before{transform:none}.callout.callout-style-simple:not(.no-icon) div.callout-icon-container{padding-top:.2em;padding-right:.55em}.callout.callout-style-default:not(.no-icon) div.callout-icon-container{padding-top:.1em;padding-right:.35em}.callout.callout-style-default:not(.no-icon) div.callout-caption-container{margin-top:-1px}.callout.callout-style-default.callout-caution:not(.no-icon) div.callout-icon-container{padding-top:.3em;padding-right:.35em}.callout>.callout-body>.callout-icon-container>.no-icon,.callout>.callout-header>.callout-icon-container>.no-icon{display:none}div.callout.callout{border-left-color:#6c757d}div.callout.callout-style-default>.callout-header{background-color:#6c757d}div.callout-note.callout{border-left-color:#2c3e50}div.callout-note.callout-style-default>.callout-header{background-color:#eaecee}div.callout-note:not(.callout-captioned) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-note.callout-captioned .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-note .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-tip.callout{border-left-color:#18bc9c}div.callout-tip.callout-style-default>.callout-header{background-color:#e8f8f5}div.callout-tip:not(.callout-captioned) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-tip.callout-captioned .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-tip .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-warning.callout{border-left-color:#f39c12}div.callout-warning.callout-style-default>.callout-header{background-color:#fef5e7}div.callout-warning:not(.callout-captioned) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-warning.callout-captioned .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-warning .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-caution.callout{border-left-color:#fd7e14}div.callout-caution.callout-style-default>.callout-header{background-color:#fff2e8}div.callout-caution:not(.callout-captioned) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-caution.callout-captioned .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-caution .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-important.callout{border-left-color:#e74c3c}div.callout-important.callout-style-default>.callout-header{background-color:#fdedec}div.callout-important:not(.callout-captioned) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-important.callout-captioned .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-important .callout-toggle::before{background-image:url('data:image/svg+xml,')}.quarto-toggle-container{display:flex;align-items:center}@media(min-width: 992px){.navbar .quarto-color-scheme-toggle{padding-left:.5rem;padding-right:.5rem}}@media(max-width: 767.98px){.navbar .quarto-color-scheme-toggle{padding-left:0;padding-right:0;padding-bottom:.5em}}.quarto-reader-toggle .bi::before,.quarto-color-scheme-toggle .bi::before{display:inline-block;height:1rem;width:1rem;content:"";background-repeat:no-repeat;background-size:1rem 1rem}.navbar-collapse .quarto-color-scheme-toggle{padding-left:.6rem;padding-right:0;margin-top:-12px}.sidebar-navigation{padding-left:20px}.sidebar-navigation .quarto-color-scheme-toggle .bi::before{padding-top:.2rem;margin-bottom:-0.2rem}.sidebar-tools-main .quarto-color-scheme-toggle .bi::before{padding-top:.2rem;margin-bottom:-0.2rem}.navbar .quarto-color-scheme-toggle .bi::before{padding-top:7px;margin-bottom:-7px;padding-left:2px;margin-right:2px}.navbar .quarto-color-scheme-toggle:not(.alternate) .bi::before{background-image:url('data:image/svg+xml,')}.navbar .quarto-color-scheme-toggle.alternate .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-color-scheme-toggle:not(.alternate) .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-color-scheme-toggle.alternate .bi::before{background-image:url('data:image/svg+xml,')}.quarto-sidebar-toggle{border-color:#dee2e6;border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem;border-style:solid;border-width:1px;overflow:hidden;border-top-width:0px;padding-top:0px !important}.quarto-sidebar-toggle-title{cursor:pointer;padding-bottom:2px;margin-left:.25em;text-align:center;font-weight:400;font-size:.775em}#quarto-content .quarto-sidebar-toggle{background:#fafafa}#quarto-content .quarto-sidebar-toggle-title{color:#212529}.quarto-sidebar-toggle-icon{color:#dee2e6;margin-right:.5em;float:right;transition:transform .2s ease}.quarto-sidebar-toggle-icon::before{padding-top:5px}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-icon{transform:rotate(-180deg)}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-title{border-bottom:solid #dee2e6 1px}.quarto-sidebar-toggle-contents{background-color:#fff;padding-right:10px;padding-left:10px;margin-top:0px !important;transition:max-height .5s ease}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-contents{padding-top:1em;padding-bottom:10px}.quarto-sidebar-toggle:not(.expanded) .quarto-sidebar-toggle-contents{padding-top:0px !important;padding-bottom:0px}nav[role=doc-toc]{z-index:1020}#quarto-sidebar>*,nav[role=doc-toc]>*{transition:opacity .1s ease,border .1s ease}#quarto-sidebar.slow>*,nav[role=doc-toc].slow>*{transition:opacity .4s ease,border .4s ease}.quarto-color-scheme-toggle:not(.alternate).top-right .bi::before{background-image:url('data:image/svg+xml,')}.quarto-color-scheme-toggle.alternate.top-right .bi::before{background-image:url('data:image/svg+xml,')}#quarto-appendix.default{border-top:1px solid #dee2e6}#quarto-appendix.default{background-color:#fff;padding-top:1.5em;margin-top:2em;z-index:998}#quarto-appendix.default .quarto-appendix-heading{margin-top:0;line-height:1.4em;font-weight:600;opacity:.9;border-bottom:none;margin-bottom:0}#quarto-appendix.default .footnotes ol,#quarto-appendix.default .footnotes ol li>p:last-of-type,#quarto-appendix.default .quarto-appendix-contents>p:last-of-type{margin-bottom:0}#quarto-appendix.default .quarto-appendix-secondary-label{margin-bottom:.4em}#quarto-appendix.default .quarto-appendix-bibtex{font-size:.7em;padding:1em;border:solid 1px #dee2e6;margin-bottom:1em}#quarto-appendix.default .quarto-appendix-bibtex code.sourceCode{white-space:pre-wrap}#quarto-appendix.default .quarto-appendix-citeas{font-size:.9em;padding:1em;border:solid 1px #dee2e6;margin-bottom:1em}#quarto-appendix.default .quarto-appendix-heading{font-size:1em !important}#quarto-appendix.default *[role=doc-endnotes]>ol,#quarto-appendix.default .quarto-appendix-contents>*:not(h2):not(.h2){font-size:.9em}#quarto-appendix.default section{padding-bottom:1.5em}#quarto-appendix.default section *[role=doc-endnotes],#quarto-appendix.default section>*:not(a){opacity:.9;word-wrap:break-word}.btn.btn-quarto,div.cell-output-display .btn-quarto{color:#fefefe;background-color:#6c757d;border-color:#6c757d}.btn.btn-quarto:hover,div.cell-output-display .btn-quarto:hover{color:#fefefe;background-color:#828a91;border-color:#7b838a}.btn-check:focus+.btn.btn-quarto,.btn.btn-quarto:focus,.btn-check:focus+div.cell-output-display .btn-quarto,div.cell-output-display .btn-quarto:focus{color:#fefefe;background-color:#828a91;border-color:#7b838a;box-shadow:0 0 0 .25rem rgba(130,138,144,.5)}.btn-check:checked+.btn.btn-quarto,.btn-check:active+.btn.btn-quarto,.btn.btn-quarto:active,.btn.btn-quarto.active,.show>.btn.btn-quarto.dropdown-toggle,.btn-check:checked+div.cell-output-display .btn-quarto,.btn-check:active+div.cell-output-display .btn-quarto,div.cell-output-display .btn-quarto:active,div.cell-output-display .btn-quarto.active,.show>div.cell-output-display .btn-quarto.dropdown-toggle{color:#fff;background-color:#899197;border-color:#7b838a}.btn-check:checked+.btn.btn-quarto:focus,.btn-check:active+.btn.btn-quarto:focus,.btn.btn-quarto:active:focus,.btn.btn-quarto.active:focus,.show>.btn.btn-quarto.dropdown-toggle:focus,.btn-check:checked+div.cell-output-display .btn-quarto:focus,.btn-check:active+div.cell-output-display .btn-quarto:focus,div.cell-output-display .btn-quarto:active:focus,div.cell-output-display .btn-quarto.active:focus,.show>div.cell-output-display .btn-quarto.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(130,138,144,.5)}.btn.btn-quarto:disabled,.btn.btn-quarto.disabled,div.cell-output-display .btn-quarto:disabled,div.cell-output-display .btn-quarto.disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}nav.quarto-secondary-nav.color-navbar{background-color:#2c3e50;color:#ccd1d5}nav.quarto-secondary-nav.color-navbar h1,nav.quarto-secondary-nav.color-navbar .h1,nav.quarto-secondary-nav.color-navbar .quarto-btn-toggle{color:#ccd1d5}@media(max-width: 991.98px){body.nav-sidebar .quarto-title-banner,body.nav-sidebar .quarto-title-banner{display:none}}p.subtitle{margin-top:.25em;margin-bottom:.5em}code a:any-link{color:inherit;text-decoration-color:#6c757d}/*! light */div.observablehq table thead tr th{background-color:var(--bs-body-bg)}input,button,select,optgroup,textarea{background-color:var(--bs-body-bg)}@media print{.page-columns .column-screen-inset{grid-column:page-start-inset/page-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset table{background:#fff}.page-columns .column-screen-inset-left{grid-column:page-start-inset/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-left table{background:#fff}.page-columns .column-screen-inset-right{grid-column:body-content-start/page-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:page-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:page-start/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-right table{background:#fff}.page-columns .column-screen-inset-shaded{grid-column:page-start-inset/page-end-inset;padding:1em;background:#ecf0f1;z-index:998;transform:translate3d(0, 0, 0);margin-bottom:1em}}.quarto-video{margin-bottom:1em}a.external:after{display:inline-block;height:.75rem;width:.75rem;margin-bottom:.15em;margin-left:.25em;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:.75rem .75rem}a.external:after:hover{cursor:pointer}.quarto-ext-icon{display:inline-block;font-size:.75em;padding-left:.3em}.code-with-filename .code-with-filename-file{margin-bottom:0;padding-bottom:2px;padding-top:2px;padding-left:.7em;border:var(--quarto-border-width) solid var(--quarto-border-color);border-radius:var(--quarto-border-radius);border-bottom:0;border-bottom-left-radius:0%;border-bottom-right-radius:0%}.code-with-filename div.sourceCode,.reveal .code-with-filename div.sourceCode{margin-top:0;border-top-left-radius:0%;border-top-right-radius:0%}.code-with-filename .code-with-filename-file pre{margin-bottom:0}.code-with-filename .code-with-filename-file,.code-with-filename .code-with-filename-file pre{background-color:rgba(219,219,219,.8)}.quarto-dark .code-with-filename .code-with-filename-file,.quarto-dark .code-with-filename .code-with-filename-file pre{background-color:#555}.code-with-filename .code-with-filename-file strong{font-weight:400}.quarto-title-banner{margin-bottom:1em;color:#ccd1d5;background:#2c3e50}.quarto-title-banner .code-tools-button{color:#949fa7}.quarto-title-banner .code-tools-button:hover{color:#ccd1d5}.quarto-title-banner .code-tools-button>.bi::before{background-image:url('data:image/svg+xml,')}.quarto-title-banner .code-tools-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}.quarto-title-banner .quarto-title .title{font-weight:600}.quarto-title-banner .quarto-categories{margin-top:.75em}@media(min-width: 992px){.quarto-title-banner{padding-top:2.5em;padding-bottom:2.5em}}@media(max-width: 991.98px){.quarto-title-banner{padding-top:1em;padding-bottom:1em}}main.quarto-banner-title-block section:first-of-type h2:first-of-type,main.quarto-banner-title-block section:first-of-type .h2:first-of-type,main.quarto-banner-title-block section:first-of-type h3:first-of-type,main.quarto-banner-title-block section:first-of-type .h3:first-of-type,main.quarto-banner-title-block section:first-of-type h4:first-of-type,main.quarto-banner-title-block section:first-of-type .h4:first-of-type{margin-top:0}.quarto-title .quarto-categories{display:flex;column-gap:.4em;padding-bottom:.5em;margin-top:.75em}.quarto-title .quarto-categories .quarto-category{padding:.25em .75em;font-size:.65em;text-transform:uppercase;border:solid 1px;border-radius:.25rem;opacity:.6}.quarto-title .quarto-categories .quarto-category a{color:inherit}#title-block-header.quarto-title-block.default .quarto-title-meta{display:grid;grid-template-columns:repeat(2, 1fr)}#title-block-header.quarto-title-block.default .quarto-title .title{margin-bottom:0}#title-block-header.quarto-title-block.default .quarto-title-author-orcid img{margin-top:-5px}#title-block-header.quarto-title-block.default .quarto-description p:last-of-type{margin-bottom:0}#title-block-header.quarto-title-block.default .quarto-title-meta-contents p,#title-block-header.quarto-title-block.default .quarto-title-authors p,#title-block-header.quarto-title-block.default .quarto-title-affiliations p{margin-bottom:.1em}#title-block-header.quarto-title-block.default .quarto-title-meta-heading{text-transform:uppercase;margin-top:1em;font-size:.8em;opacity:.8;font-weight:400}#title-block-header.quarto-title-block.default .quarto-title-meta-contents{font-size:.9em}#title-block-header.quarto-title-block.default .quarto-title-meta-contents a{color:#212529}#title-block-header.quarto-title-block.default .quarto-title-meta-contents p.affiliation:last-of-type{margin-bottom:.7em}#title-block-header.quarto-title-block.default p.affiliation{margin-bottom:.1em}#title-block-header.quarto-title-block.default .description,#title-block-header.quarto-title-block.default .abstract{margin-top:0}#title-block-header.quarto-title-block.default .description>p,#title-block-header.quarto-title-block.default .abstract>p{font-size:.9em}#title-block-header.quarto-title-block.default .description>p:last-of-type,#title-block-header.quarto-title-block.default .abstract>p:last-of-type{margin-bottom:0}#title-block-header.quarto-title-block.default .description .abstract-title,#title-block-header.quarto-title-block.default .abstract .abstract-title{margin-top:1em;text-transform:uppercase;font-size:.8em;opacity:.8;font-weight:400}#title-block-header.quarto-title-block.default .quarto-title-meta-author{display:grid;grid-template-columns:1fr 1fr}.bg-primary .navbar-nav .show>.nav-link,.bg-primary .navbar-nav .nav-link.active,.bg-primary .navbar-nav .nav-link:hover,.bg-primary .navbar-nav .nav-link:focus{color:#18bc9c !important}.nav-tabs .nav-link.active,.nav-tabs .nav-link.active:focus,.nav-tabs .nav-link.active:hover,.nav-tabs .nav-item.open .nav-link,.nav-tabs .nav-item.open .nav-link:focus,.nav-tabs .nav-item.open .nav-link:hover{color:#2c3e50}.pagination a:hover{text-decoration:none}.badge.bg-light{color:#7b8a8b}.alert{border:none;color:#fff}.alert a,.alert .alert-link{color:#fff;text-decoration:underline}.alert-default{background-color:#6c757d}.alert-primary{background-color:#2c3e50}.alert-secondary{background-color:#6c757d}.alert-success{background-color:#18bc9c}.alert-info{background-color:#3498db}.alert-warning{background-color:#f39c12}.alert-danger{background-color:#e74c3c}.alert-light{background-color:#ecf0f1}.alert-dark{background-color:#7b8a8b}.alert-light,.alert-light a,.alert-light .alert-link{color:#212529}.modal .btn-close,.toast .btn-close{background-image:url("data:image/svg+xml,")}/*# sourceMappingURL=d6b77e37a12f878a50f9f8a85e535bdc.css.map */ diff --git a/docs/site_libs/bootstrap/bootstrap.min.js b/docs/site_libs/bootstrap/bootstrap.min.js new file mode 100644 index 0000000..cc0a255 --- /dev/null +++ b/docs/site_libs/bootstrap/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t="transitionend",e=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e},i=t=>{const i=e(t);return i&&document.querySelector(i)?i:null},n=t=>{const i=e(t);return i?document.querySelector(i):null},s=e=>{e.dispatchEvent(new Event(t))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(t):null,a=(t,e,i)=>{Object.keys(i).forEach((n=>{const s=i[n],r=e[n],a=r&&o(r)?"element":null==(l=r)?`${l}`:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();var l;if(!new RegExp(s).test(a))throw new TypeError(`${t.toUpperCase()}: Option "${n}" provided type "${a}" but expected type "${s}".`)}))},l=t=>!(!o(t)||0===t.getClientRects().length)&&"visible"===getComputedStyle(t).getPropertyValue("visibility"),c=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),h=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?h(t.parentNode):null},d=()=>{},u=t=>{t.offsetHeight},f=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},p=[],m=()=>"rtl"===document.documentElement.dir,g=t=>{var e;e=()=>{const e=f();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(p.length||document.addEventListener("DOMContentLoaded",(()=>{p.forEach((t=>t()))})),p.push(e)):e()},_=t=>{"function"==typeof t&&t()},b=(e,i,n=!0)=>{if(!n)return void _(e);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(i)+5;let r=!1;const a=({target:n})=>{n===i&&(r=!0,i.removeEventListener(t,a),_(e))};i.addEventListener(t,a),setTimeout((()=>{r||s(i)}),o)},v=(t,e,i,n)=>{let s=t.indexOf(e);if(-1===s)return t[!i&&n?t.length-1:0];const o=t.length;return s+=i?1:-1,n&&(s=(s+o)%o),t[Math.max(0,Math.min(s,o-1))]},y=/[^.]*(?=\..*)\.|.*/,w=/\..*/,E=/::\d+$/,A={};let T=1;const O={mouseenter:"mouseover",mouseleave:"mouseout"},C=/^(mouseenter|mouseleave)/i,k=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function L(t,e){return e&&`${e}::${T++}`||t.uidEvent||T++}function x(t){const e=L(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function D(t,e,i=null){const n=Object.keys(t);for(let s=0,o=n.length;sfunction(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};n?n=t(n):i=t(i)}const[o,r,a]=S(e,i,n),l=x(t),c=l[a]||(l[a]={}),h=D(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=L(r,e.replace(y,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(let a=o.length;a--;)if(o[a]===r)return s.delegateTarget=r,n.oneOff&&j.off(t,s.type,e,i),i.apply(r,[s]);return null}}(t,i,n):function(t,e){return function i(n){return n.delegateTarget=t,i.oneOff&&j.off(t,n.type,e),e.apply(t,[n])}}(t,i);u.delegationSelector=o?i:null,u.originalHandler=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function I(t,e,i,n,s){const o=D(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function P(t){return t=t.replace(w,""),O[t]||t}const j={on(t,e,i,n){N(t,e,i,n,!1)},one(t,e,i,n){N(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=S(e,i,n),a=r!==e,l=x(t),c=e.startsWith(".");if(void 0!==o){if(!l||!l[r])return;return void I(t,l,r,o,s?i:null)}c&&Object.keys(l).forEach((i=>{!function(t,e,i,n){const s=e[i]||{};Object.keys(s).forEach((o=>{if(o.includes(n)){const n=s[o];I(t,e,i,n.originalHandler,n.delegationSelector)}}))}(t,l,i,e.slice(1))}));const h=l[r]||{};Object.keys(h).forEach((i=>{const n=i.replace(E,"");if(!a||e.includes(n)){const e=h[i];I(t,l,r,e.originalHandler,e.delegationSelector)}}))},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=f(),s=P(e),o=e!==s,r=k.has(s);let a,l=!0,c=!0,h=!1,d=null;return o&&n&&(a=n.Event(e,i),n(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),h=a.isDefaultPrevented()),r?(d=document.createEvent("HTMLEvents"),d.initEvent(s,l,!0)):d=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==i&&Object.keys(i).forEach((t=>{Object.defineProperty(d,t,{get:()=>i[t]})})),h&&d.preventDefault(),c&&t.dispatchEvent(d),d.defaultPrevented&&void 0!==a&&a.preventDefault(),d}},M=new Map,H={set(t,e,i){M.has(t)||M.set(t,new Map);const n=M.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>M.has(t)&&M.get(t).get(e)||null,remove(t,e){if(!M.has(t))return;const i=M.get(t);i.delete(e),0===i.size&&M.delete(t)}};class B{constructor(t){(t=r(t))&&(this._element=t,H.set(this._element,this.constructor.DATA_KEY,this))}dispose(){H.remove(this._element,this.constructor.DATA_KEY),j.off(this._element,this.constructor.EVENT_KEY),Object.getOwnPropertyNames(this).forEach((t=>{this[t]=null}))}_queueCallback(t,e,i=!0){b(t,e,i)}static getInstance(t){return H.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.1.3"}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}}const R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,s=t.NAME;j.on(document,i,`[data-bs-dismiss="${s}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),c(this))return;const o=n(this)||this.closest(`.${s}`);t.getOrCreateInstance(o)[e]()}))};class W extends B{static get NAME(){return"alert"}close(){if(j.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),j.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=W.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(W,"close"),g(W);const $='[data-bs-toggle="button"]';class z extends B{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=z.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}function q(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function F(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}j.on(document,"click.bs.button.data-api",$,(t=>{t.preventDefault();const e=t.target.closest($);z.getOrCreateInstance(e).toggle()})),g(z);const U={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${F(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${F(e)}`)},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter((t=>t.startsWith("bs"))).forEach((i=>{let n=i.replace(/^bs/,"");n=n.charAt(0).toLowerCase()+n.slice(1,n.length),e[n]=q(t.dataset[i])})),e},getDataAttribute:(t,e)=>q(t.getAttribute(`data-bs-${F(e)}`)),offset(t){const e=t.getBoundingClientRect();return{top:e.top+window.pageYOffset,left:e.left+window.pageXOffset}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},V={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode;for(;n&&n.nodeType===Node.ELEMENT_NODE&&3!==n.nodeType;)n.matches(e)&&i.push(n),n=n.parentNode;return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(", ");return this.find(e,t).filter((t=>!c(t)&&l(t)))}},K="carousel",X={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},Y={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},Q="next",G="prev",Z="left",J="right",tt={ArrowLeft:J,ArrowRight:Z},et="slid.bs.carousel",it="active",nt=".active.carousel-item";class st extends B{constructor(t,e){super(t),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._indicatorsElement=V.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return X}static get NAME(){return K}next(){this._slide(Q)}nextWhenVisible(){!document.hidden&&l(this._element)&&this.next()}prev(){this._slide(G)}pause(t){t||(this._isPaused=!0),V.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(s(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(t){this._activeElement=V.findOne(nt,this._element);const e=this._getItemIndex(this._activeElement);if(t>this._items.length-1||t<0)return;if(this._isSliding)return void j.one(this._element,et,(()=>this.to(t)));if(e===t)return this.pause(),void this.cycle();const i=t>e?Q:G;this._slide(i,this._items[t])}_getConfig(t){return t={...X,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(K,t,Y),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?J:Z)}_addEventListeners(){this._config.keyboard&&j.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(j.on(this._element,"mouseenter.bs.carousel",(t=>this.pause(t))),j.on(this._element,"mouseleave.bs.carousel",(t=>this.cycle(t)))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const t=t=>this._pointerEvent&&("pen"===t.pointerType||"touch"===t.pointerType),e=e=>{t(e)?this.touchStartX=e.clientX:this._pointerEvent||(this.touchStartX=e.touches[0].clientX)},i=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},n=e=>{t(e)&&(this.touchDeltaX=e.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((t=>this.cycle(t)),500+this._config.interval))};V.find(".carousel-item img",this._element).forEach((t=>{j.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()))})),this._pointerEvent?(j.on(this._element,"pointerdown.bs.carousel",(t=>e(t))),j.on(this._element,"pointerup.bs.carousel",(t=>n(t))),this._element.classList.add("pointer-event")):(j.on(this._element,"touchstart.bs.carousel",(t=>e(t))),j.on(this._element,"touchmove.bs.carousel",(t=>i(t))),j.on(this._element,"touchend.bs.carousel",(t=>n(t))))}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=tt[t.key];e&&(t.preventDefault(),this._slide(e))}_getItemIndex(t){return this._items=t&&t.parentNode?V.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)}_getItemByOrder(t,e){const i=t===Q;return v(this._items,e,i,this._config.wrap)}_triggerSlideEvent(t,e){const i=this._getItemIndex(t),n=this._getItemIndex(V.findOne(nt,this._element));return j.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:n,to:i})}_setActiveIndicatorElement(t){if(this._indicatorsElement){const e=V.findOne(".active",this._indicatorsElement);e.classList.remove(it),e.removeAttribute("aria-current");const i=V.find("[data-bs-target]",this._indicatorsElement);for(let e=0;e{j.trigger(this._element,et,{relatedTarget:o,direction:d,from:s,to:r})};if(this._element.classList.contains("slide")){o.classList.add(h),u(o),n.classList.add(c),o.classList.add(c);const t=()=>{o.classList.remove(c,h),o.classList.add(it),n.classList.remove(it,h,c),this._isSliding=!1,setTimeout(f,0)};this._queueCallback(t,n,!0)}else n.classList.remove(it),o.classList.add(it),this._isSliding=!1,f();a&&this.cycle()}_directionToOrder(t){return[J,Z].includes(t)?m()?t===Z?G:Q:t===Z?Q:G:t}_orderToDirection(t){return[Q,G].includes(t)?m()?t===G?Z:J:t===G?J:Z:t}static carouselInterface(t,e){const i=st.getOrCreateInstance(t,e);let{_config:n}=i;"object"==typeof e&&(n={...n,...e});const s="string"==typeof e?e:n.slide;if("number"==typeof e)i.to(e);else if("string"==typeof s){if(void 0===i[s])throw new TypeError(`No method named "${s}"`);i[s]()}else n.interval&&n.ride&&(i.pause(),i.cycle())}static jQueryInterface(t){return this.each((function(){st.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=n(this);if(!e||!e.classList.contains("carousel"))return;const i={...U.getDataAttributes(e),...U.getDataAttributes(this)},s=this.getAttribute("data-bs-slide-to");s&&(i.interval=!1),st.carouselInterface(e,i),s&&st.getInstance(e).to(s),t.preventDefault()}}j.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",st.dataApiClickHandler),j.on(window,"load.bs.carousel.data-api",(()=>{const t=V.find('[data-bs-ride="carousel"]');for(let e=0,i=t.length;et===this._element));null!==s&&o.length&&(this._selector=s,this._triggerArray.push(e))}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return rt}static get NAME(){return ot}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t,e=[];if(this._config.parent){const t=V.find(ut,this._config.parent);e=V.find(".collapse.show, .collapse.collapsing",this._config.parent).filter((e=>!t.includes(e)))}const i=V.findOne(this._selector);if(e.length){const n=e.find((t=>i!==t));if(t=n?pt.getInstance(n):null,t&&t._isTransitioning)return}if(j.trigger(this._element,"show.bs.collapse").defaultPrevented)return;e.forEach((e=>{i!==e&&pt.getOrCreateInstance(e,{toggle:!1}).hide(),t||H.set(e,"bs.collapse",null)}));const n=this._getDimension();this._element.classList.remove(ct),this._element.classList.add(ht),this._element.style[n]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const s=`scroll${n[0].toUpperCase()+n.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct,lt),this._element.style[n]="",j.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[n]=`${this._element[s]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(j.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,u(this._element),this._element.classList.add(ht),this._element.classList.remove(ct,lt);const e=this._triggerArray.length;for(let t=0;t{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct),j.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(lt)}_getConfig(t){return(t={...rt,...U.getDataAttributes(this._element),...t}).toggle=Boolean(t.toggle),t.parent=r(t.parent),a(ot,t,at),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=V.find(ut,this._config.parent);V.find(ft,this._config.parent).filter((e=>!t.includes(e))).forEach((t=>{const e=n(t);e&&this._addAriaAndCollapsedClass([t],this._isShown(e))}))}_addAriaAndCollapsedClass(t,e){t.length&&t.forEach((t=>{e?t.classList.remove(dt):t.classList.add(dt),t.setAttribute("aria-expanded",e)}))}static jQueryInterface(t){return this.each((function(){const e={};"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1);const i=pt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}j.on(document,"click.bs.collapse.data-api",ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=i(this);V.find(e).forEach((t=>{pt.getOrCreateInstance(t,{toggle:!1}).toggle()}))})),g(pt);var mt="top",gt="bottom",_t="right",bt="left",vt="auto",yt=[mt,gt,_t,bt],wt="start",Et="end",At="clippingParents",Tt="viewport",Ot="popper",Ct="reference",kt=yt.reduce((function(t,e){return t.concat([e+"-"+wt,e+"-"+Et])}),[]),Lt=[].concat(yt,[vt]).reduce((function(t,e){return t.concat([e,e+"-"+wt,e+"-"+Et])}),[]),xt="beforeRead",Dt="read",St="afterRead",Nt="beforeMain",It="main",Pt="afterMain",jt="beforeWrite",Mt="write",Ht="afterWrite",Bt=[xt,Dt,St,Nt,It,Pt,jt,Mt,Ht];function Rt(t){return t?(t.nodeName||"").toLowerCase():null}function Wt(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function $t(t){return t instanceof Wt(t).Element||t instanceof Element}function zt(t){return t instanceof Wt(t).HTMLElement||t instanceof HTMLElement}function qt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof Wt(t).ShadowRoot||t instanceof ShadowRoot)}const Ft={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];zt(s)&&Rt(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});zt(n)&&Rt(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function Ut(t){return t.split("-")[0]}function Vt(t,e){var i=t.getBoundingClientRect();return{width:i.width/1,height:i.height/1,top:i.top/1,right:i.right/1,bottom:i.bottom/1,left:i.left/1,x:i.left/1,y:i.top/1}}function Kt(t){var e=Vt(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Xt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&qt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Yt(t){return Wt(t).getComputedStyle(t)}function Qt(t){return["table","td","th"].indexOf(Rt(t))>=0}function Gt(t){return(($t(t)?t.ownerDocument:t.document)||window.document).documentElement}function Zt(t){return"html"===Rt(t)?t:t.assignedSlot||t.parentNode||(qt(t)?t.host:null)||Gt(t)}function Jt(t){return zt(t)&&"fixed"!==Yt(t).position?t.offsetParent:null}function te(t){for(var e=Wt(t),i=Jt(t);i&&Qt(i)&&"static"===Yt(i).position;)i=Jt(i);return i&&("html"===Rt(i)||"body"===Rt(i)&&"static"===Yt(i).position)?e:i||function(t){var e=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&zt(t)&&"fixed"===Yt(t).position)return null;for(var i=Zt(t);zt(i)&&["html","body"].indexOf(Rt(i))<0;){var n=Yt(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function ee(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}var ie=Math.max,ne=Math.min,se=Math.round;function oe(t,e,i){return ie(t,ne(e,i))}function re(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function ae(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const le={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=Ut(i.placement),l=ee(a),c=[bt,_t].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return re("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:ae(t,yt))}(s.padding,i),d=Kt(o),u="y"===l?mt:bt,f="y"===l?gt:_t,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=te(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,E=oe(v,w,y),A=l;i.modifiersData[n]=((e={})[A]=E,e.centerOffset=E-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Xt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ce(t){return t.split("-")[1]}var he={top:"auto",right:"auto",bottom:"auto",left:"auto"};function de(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=!0===h?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:se(se(e*n)/n)||0,y:se(se(i*n)/n)||0}}(r):"function"==typeof h?h(r):r,u=d.x,f=void 0===u?0:u,p=d.y,m=void 0===p?0:p,g=r.hasOwnProperty("x"),_=r.hasOwnProperty("y"),b=bt,v=mt,y=window;if(c){var w=te(i),E="clientHeight",A="clientWidth";w===Wt(i)&&"static"!==Yt(w=Gt(i)).position&&"absolute"===a&&(E="scrollHeight",A="scrollWidth"),w=w,s!==mt&&(s!==bt&&s!==_t||o!==Et)||(v=gt,m-=w[E]-n.height,m*=l?1:-1),s!==bt&&(s!==mt&&s!==gt||o!==Et)||(b=_t,f-=w[A]-n.width,f*=l?1:-1)}var T,O=Object.assign({position:a},c&&he);return l?Object.assign({},O,((T={})[v]=_?"0":"",T[b]=g?"0":"",T.transform=(y.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",T)):Object.assign({},O,((e={})[v]=_?m+"px":"",e[b]=g?f+"px":"",e.transform="",e))}const ue={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:Ut(e.placement),variation:ce(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,de(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,de(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var fe={passive:!0};const pe={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=Wt(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,fe)})),a&&l.addEventListener("resize",i.update,fe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,fe)})),a&&l.removeEventListener("resize",i.update,fe)}},data:{}};var me={left:"right",right:"left",bottom:"top",top:"bottom"};function ge(t){return t.replace(/left|right|bottom|top/g,(function(t){return me[t]}))}var _e={start:"end",end:"start"};function be(t){return t.replace(/start|end/g,(function(t){return _e[t]}))}function ve(t){var e=Wt(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function ye(t){return Vt(Gt(t)).left+ve(t).scrollLeft}function we(t){var e=Yt(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ee(t){return["html","body","#document"].indexOf(Rt(t))>=0?t.ownerDocument.body:zt(t)&&we(t)?t:Ee(Zt(t))}function Ae(t,e){var i;void 0===e&&(e=[]);var n=Ee(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=Wt(n),r=s?[o].concat(o.visualViewport||[],we(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Ae(Zt(r)))}function Te(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Oe(t,e){return e===Tt?Te(function(t){var e=Wt(t),i=Gt(t),n=e.visualViewport,s=i.clientWidth,o=i.clientHeight,r=0,a=0;return n&&(s=n.width,o=n.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(r=n.offsetLeft,a=n.offsetTop)),{width:s,height:o,x:r+ye(t),y:a}}(t)):zt(e)?function(t){var e=Vt(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Te(function(t){var e,i=Gt(t),n=ve(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ie(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ie(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+ye(t),l=-n.scrollTop;return"rtl"===Yt(s||i).direction&&(a+=ie(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Gt(t)))}function Ce(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?Ut(s):null,r=s?ce(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case mt:e={x:a,y:i.y-n.height};break;case gt:e={x:a,y:i.y+i.height};break;case _t:e={x:i.x+i.width,y:l};break;case bt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?ee(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case wt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Et:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ke(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.boundary,r=void 0===o?At:o,a=i.rootBoundary,l=void 0===a?Tt:a,c=i.elementContext,h=void 0===c?Ot:c,d=i.altBoundary,u=void 0!==d&&d,f=i.padding,p=void 0===f?0:f,m=re("number"!=typeof p?p:ae(p,yt)),g=h===Ot?Ct:Ot,_=t.rects.popper,b=t.elements[u?g:h],v=function(t,e,i){var n="clippingParents"===e?function(t){var e=Ae(Zt(t)),i=["absolute","fixed"].indexOf(Yt(t).position)>=0&&zt(t)?te(t):t;return $t(i)?e.filter((function(t){return $t(t)&&Xt(t,i)&&"body"!==Rt(t)})):[]}(t):[].concat(e),s=[].concat(n,[i]),o=s[0],r=s.reduce((function(e,i){var n=Oe(t,i);return e.top=ie(n.top,e.top),e.right=ne(n.right,e.right),e.bottom=ne(n.bottom,e.bottom),e.left=ie(n.left,e.left),e}),Oe(t,o));return r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}($t(b)?b:b.contextElement||Gt(t.elements.popper),r,l),y=Vt(t.elements.reference),w=Ce({reference:y,element:_,strategy:"absolute",placement:s}),E=Te(Object.assign({},_,w)),A=h===Ot?E:y,T={top:v.top-A.top+m.top,bottom:A.bottom-v.bottom+m.bottom,left:v.left-A.left+m.left,right:A.right-v.right+m.right},O=t.modifiersData.offset;if(h===Ot&&O){var C=O[s];Object.keys(T).forEach((function(t){var e=[_t,gt].indexOf(t)>=0?1:-1,i=[mt,gt].indexOf(t)>=0?"y":"x";T[t]+=C[i]*e}))}return T}function Le(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?Lt:l,h=ce(n),d=h?a?kt:kt.filter((function(t){return ce(t)===h})):yt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ke(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[Ut(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const xe={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=Ut(g),b=l||(_!==g&&p?function(t){if(Ut(t)===vt)return[];var e=ge(t);return[be(t),e,be(e)]}(g):[ge(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(Ut(i)===vt?Le(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,E=new Map,A=!0,T=v[0],O=0;O=0,D=x?"width":"height",S=ke(e,{placement:C,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),N=x?L?_t:bt:L?gt:mt;y[D]>w[D]&&(N=ge(N));var I=ge(N),P=[];if(o&&P.push(S[k]<=0),a&&P.push(S[N]<=0,S[I]<=0),P.every((function(t){return t}))){T=C,A=!1;break}E.set(C,P)}if(A)for(var j=function(t){var e=v.find((function(e){var i=E.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==j(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function De(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Se(t){return[mt,_t,gt,bt].some((function(e){return t[e]>=0}))}const Ne={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ke(e,{elementContext:"reference"}),a=ke(e,{altBoundary:!0}),l=De(r,n),c=De(a,s,o),h=Se(l),d=Se(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},Ie={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=Lt.reduce((function(t,i){return t[i]=function(t,e,i){var n=Ut(t),s=[bt,mt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[bt,_t].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},Pe={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=Ce({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},je={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ke(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=Ut(e.placement),b=ce(e.placement),v=!b,y=ee(_),w="x"===y?"y":"x",E=e.modifiersData.popperOffsets,A=e.rects.reference,T=e.rects.popper,O="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,C={x:0,y:0};if(E){if(o||a){var k="y"===y?mt:bt,L="y"===y?gt:_t,x="y"===y?"height":"width",D=E[y],S=E[y]+g[k],N=E[y]-g[L],I=f?-T[x]/2:0,P=b===wt?A[x]:T[x],j=b===wt?-T[x]:-A[x],M=e.elements.arrow,H=f&&M?Kt(M):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},R=B[k],W=B[L],$=oe(0,A[x],H[x]),z=v?A[x]/2-I-$-R-O:P-$-R-O,q=v?-A[x]/2+I+$+W+O:j+$+W+O,F=e.elements.arrow&&te(e.elements.arrow),U=F?"y"===y?F.clientTop||0:F.clientLeft||0:0,V=e.modifiersData.offset?e.modifiersData.offset[e.placement][y]:0,K=E[y]+z-V-U,X=E[y]+q-V;if(o){var Y=oe(f?ne(S,K):S,D,f?ie(N,X):N);E[y]=Y,C[y]=Y-D}if(a){var Q="x"===y?mt:bt,G="x"===y?gt:_t,Z=E[w],J=Z+g[Q],tt=Z-g[G],et=oe(f?ne(J,K):J,Z,f?ie(tt,X):tt);E[w]=et,C[w]=et-Z}}e.modifiersData[n]=C}},requiresIfExists:["offset"]};function Me(t,e,i){void 0===i&&(i=!1);var n=zt(e);zt(e)&&function(t){var e=t.getBoundingClientRect();e.width,t.offsetWidth,e.height,t.offsetHeight}(e);var s,o,r=Gt(e),a=Vt(t),l={scrollLeft:0,scrollTop:0},c={x:0,y:0};return(n||!n&&!i)&&(("body"!==Rt(e)||we(r))&&(l=(s=e)!==Wt(s)&&zt(s)?{scrollLeft:(o=s).scrollLeft,scrollTop:o.scrollTop}:ve(s)),zt(e)?((c=Vt(e)).x+=e.clientLeft,c.y+=e.clientTop):r&&(c.x=ye(r))),{x:a.left+l.scrollLeft-c.x,y:a.top+l.scrollTop-c.y,width:a.width,height:a.height}}function He(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var Be={placement:"bottom",modifiers:[],strategy:"absolute"};function Re(){for(var t=arguments.length,e=new Array(t),i=0;ij.on(t,"mouseover",d))),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(Je),this._element.classList.add(Je),j.trigger(this._element,"shown.bs.dropdown",t)}hide(){if(c(this._element)||!this._isShown(this._menu))return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){j.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._popper&&this._popper.destroy(),this._menu.classList.remove(Je),this._element.classList.remove(Je),this._element.setAttribute("aria-expanded","false"),U.removeDataAttribute(this._menu,"popper"),j.trigger(this._element,"hidden.bs.dropdown",t))}_getConfig(t){if(t={...this.constructor.Default,...U.getDataAttributes(this._element),...t},a(Ue,t,this.constructor.DefaultType),"object"==typeof t.reference&&!o(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${Ue.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(t){if(void 0===Fe)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let e=this._element;"parent"===this._config.reference?e=t:o(this._config.reference)?e=r(this._config.reference):"object"==typeof this._config.reference&&(e=this._config.reference);const i=this._getPopperConfig(),n=i.modifiers.find((t=>"applyStyles"===t.name&&!1===t.enabled));this._popper=qe(e,this._menu,i),n&&U.setDataAttribute(this._menu,"popper","static")}_isShown(t=this._element){return t.classList.contains(Je)}_getMenuElement(){return V.next(this._element,ei)[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains("dropend"))return ri;if(t.classList.contains("dropstart"))return ai;const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?ni:ii:e?oi:si}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem({key:t,target:e}){const i=V.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter(l);i.length&&v(i,e,t===Ye,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(t&&(2===t.button||"keyup"===t.type&&"Tab"!==t.key))return;const e=V.find(ti);for(let i=0,n=e.length;ie+t)),this._setElementAttributes(di,"paddingRight",(e=>e+t)),this._setElementAttributes(ui,"marginRight",(e=>e-t))}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t)[e];t.style[e]=`${i(Number.parseFloat(s))}px`}))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,"paddingRight"),this._resetElementAttributes(di,"paddingRight"),this._resetElementAttributes(ui,"marginRight")}_saveInitialAttribute(t,e){const i=t.style[e];i&&U.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=U.getDataAttribute(t,e);void 0===i?t.style.removeProperty(e):(U.removeDataAttribute(t,e),t.style[e]=i)}))}_applyManipulationCallback(t,e){o(t)?e(t):V.find(t,this._element).forEach(e)}isOverflowing(){return this.getWidth()>0}}const pi={className:"modal-backdrop",isVisible:!0,isAnimated:!1,rootElement:"body",clickCallback:null},mi={className:"string",isVisible:"boolean",isAnimated:"boolean",rootElement:"(element|string)",clickCallback:"(function|null)"},gi="show",_i="mousedown.bs.backdrop";class bi{constructor(t){this._config=this._getConfig(t),this._isAppended=!1,this._element=null}show(t){this._config.isVisible?(this._append(),this._config.isAnimated&&u(this._getElement()),this._getElement().classList.add(gi),this._emulateAnimation((()=>{_(t)}))):_(t)}hide(t){this._config.isVisible?(this._getElement().classList.remove(gi),this._emulateAnimation((()=>{this.dispose(),_(t)}))):_(t)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_getConfig(t){return(t={...pi,..."object"==typeof t?t:{}}).rootElement=r(t.rootElement),a("backdrop",t,mi),t}_append(){this._isAppended||(this._config.rootElement.append(this._getElement()),j.on(this._getElement(),_i,(()=>{_(this._config.clickCallback)})),this._isAppended=!0)}dispose(){this._isAppended&&(j.off(this._element,_i),this._element.remove(),this._isAppended=!1)}_emulateAnimation(t){b(t,this._getElement(),this._config.isAnimated)}}const vi={trapElement:null,autofocus:!0},yi={trapElement:"element",autofocus:"boolean"},wi=".bs.focustrap",Ei="backward";class Ai{constructor(t){this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}activate(){const{trapElement:t,autofocus:e}=this._config;this._isActive||(e&&t.focus(),j.off(document,wi),j.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),j.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,j.off(document,wi))}_handleFocusin(t){const{target:e}=t,{trapElement:i}=this._config;if(e===document||e===i||i.contains(e))return;const n=V.focusableChildren(i);0===n.length?i.focus():this._lastTabNavDirection===Ei?n[n.length-1].focus():n[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?Ei:"forward")}_getConfig(t){return t={...vi,..."object"==typeof t?t:{}},a("focustrap",t,yi),t}}const Ti="modal",Oi="Escape",Ci={backdrop:!0,keyboard:!0,focus:!0},ki={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean"},Li="hidden.bs.modal",xi="show.bs.modal",Di="resize.bs.modal",Si="click.dismiss.bs.modal",Ni="keydown.dismiss.bs.modal",Ii="mousedown.dismiss.bs.modal",Pi="modal-open",ji="show",Mi="modal-static";class Hi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._dialog=V.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollBar=new fi}static get Default(){return Ci}static get NAME(){return Ti}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||j.trigger(this._element,xi,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isAnimated()&&(this._isTransitioning=!0),this._scrollBar.hide(),document.body.classList.add(Pi),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),j.on(this._dialog,Ii,(()=>{j.one(this._element,"mouseup.dismiss.bs.modal",(t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)}))})),this._showBackdrop((()=>this._showElement(t))))}hide(){if(!this._isShown||this._isTransitioning)return;if(j.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const t=this._isAnimated();t&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),this._focustrap.deactivate(),this._element.classList.remove(ji),j.off(this._element,Si),j.off(this._dialog,Ii),this._queueCallback((()=>this._hideModal()),this._element,t)}dispose(){[window,this._dialog].forEach((t=>j.off(t,".bs.modal"))),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new bi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_getConfig(t){return t={...Ci,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Ti,t,ki),t}_showElement(t){const e=this._isAnimated(),i=V.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0,i&&(i.scrollTop=0),e&&u(this._element),this._element.classList.add(ji),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,j.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,e)}_setEscapeEvent(){this._isShown?j.on(this._element,Ni,(t=>{this._config.keyboard&&t.key===Oi?(t.preventDefault(),this.hide()):this._config.keyboard||t.key!==Oi||this._triggerBackdropTransition()})):j.off(this._element,Ni)}_setResizeEvent(){this._isShown?j.on(window,Di,(()=>this._adjustDialog())):j.off(window,Di)}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(Pi),this._resetAdjustments(),this._scrollBar.reset(),j.trigger(this._element,Li)}))}_showBackdrop(t){j.on(this._element,Si,(t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&(!0===this._config.backdrop?this.hide():"static"===this._config.backdrop&&this._triggerBackdropTransition())})),this._backdrop.show(t)}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(j.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const{classList:t,scrollHeight:e,style:i}=this._element,n=e>document.documentElement.clientHeight;!n&&"hidden"===i.overflowY||t.contains(Mi)||(n||(i.overflowY="hidden"),t.add(Mi),this._queueCallback((()=>{t.remove(Mi),n||this._queueCallback((()=>{i.overflowY=""}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;(!i&&t&&!m()||i&&!t&&m())&&(this._element.style.paddingLeft=`${e}px`),(i&&!t&&!m()||!i&&t&&m())&&(this._element.style.paddingRight=`${e}px`)}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}j.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=n(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),j.one(e,xi,(t=>{t.defaultPrevented||j.one(e,Li,(()=>{l(this)&&this.focus()}))}));const i=V.findOne(".modal.show");i&&Hi.getInstance(i).hide(),Hi.getOrCreateInstance(e).toggle(this)})),R(Hi),g(Hi);const Bi="offcanvas",Ri={backdrop:!0,keyboard:!0,scroll:!1},Wi={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"},$i="show",zi=".offcanvas.show",qi="hidden.bs.offcanvas";class Fi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get NAME(){return Bi}static get Default(){return Ri}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||j.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._element.style.visibility="visible",this._backdrop.show(),this._config.scroll||(new fi).hide(),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add($i),this._queueCallback((()=>{this._config.scroll||this._focustrap.activate(),j.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(j.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.remove($i),this._backdrop.hide(),this._queueCallback((()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.scroll||(new fi).reset(),j.trigger(this._element,qi)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_getConfig(t){return t={...Ri,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Bi,t,Wi),t}_initializeBackDrop(){return new bi({className:"offcanvas-backdrop",isVisible:this._config.backdrop,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:()=>this.hide()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_addEventListeners(){j.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{this._config.keyboard&&"Escape"===t.key&&this.hide()}))}static jQueryInterface(t){return this.each((function(){const e=Fi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}j.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=n(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this))return;j.one(e,qi,(()=>{l(this)&&this.focus()}));const i=V.findOne(zi);i&&i!==e&&Fi.getInstance(i).hide(),Fi.getOrCreateInstance(e).toggle(this)})),j.on(window,"load.bs.offcanvas.data-api",(()=>V.find(zi).forEach((t=>Fi.getOrCreateInstance(t).show())))),R(Fi),g(Fi);const Ui=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Vi=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,Ki=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Xi=(t,e)=>{const i=t.nodeName.toLowerCase();if(e.includes(i))return!Ui.has(i)||Boolean(Vi.test(t.nodeValue)||Ki.test(t.nodeValue));const n=e.filter((t=>t instanceof RegExp));for(let t=0,e=n.length;t{Xi(t,r)||i.removeAttribute(t.nodeName)}))}return n.body.innerHTML}const Qi="tooltip",Gi=new Set(["sanitize","allowList","sanitizeFn"]),Zi={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},Ji={AUTO:"auto",TOP:"top",RIGHT:m()?"left":"right",BOTTOM:"bottom",LEFT:m()?"right":"left"},tn={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},en={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},nn="fade",sn="show",on="show",rn="out",an=".tooltip-inner",ln=".modal",cn="hide.bs.modal",hn="hover",dn="focus";class un extends B{constructor(t,e){if(void 0===Fe)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this._config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return tn}static get NAME(){return Qi}static get Event(){return en}static get DefaultType(){return Zi}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains(sn))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),j.off(this._element.closest(ln),cn,this._hideModalHandler),this.tip&&this.tip.remove(),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this.isWithContent()||!this._isEnabled)return;const t=j.trigger(this._element,this.constructor.Event.SHOW),e=h(this._element),i=null===e?this._element.ownerDocument.documentElement.contains(this._element):e.contains(this._element);if(t.defaultPrevented||!i)return;"tooltip"===this.constructor.NAME&&this.tip&&this.getTitle()!==this.tip.querySelector(an).innerHTML&&(this._disposePopper(),this.tip.remove(),this.tip=null);const n=this.getTipElement(),s=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME);n.setAttribute("id",s),this._element.setAttribute("aria-describedby",s),this._config.animation&&n.classList.add(nn);const o="function"==typeof this._config.placement?this._config.placement.call(this,n,this._element):this._config.placement,r=this._getAttachment(o);this._addAttachmentClass(r);const{container:a}=this._config;H.set(n,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(a.append(n),j.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=qe(this._element,n,this._getPopperConfig(r)),n.classList.add(sn);const l=this._resolvePossibleFunction(this._config.customClass);l&&n.classList.add(...l.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>{j.on(t,"mouseover",d)}));const c=this.tip.classList.contains(nn);this._queueCallback((()=>{const t=this._hoverState;this._hoverState=null,j.trigger(this._element,this.constructor.Event.SHOWN),t===rn&&this._leave(null,this)}),this.tip,c)}hide(){if(!this._popper)return;const t=this.getTipElement();if(j.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented)return;t.classList.remove(sn),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1;const e=this.tip.classList.contains(nn);this._queueCallback((()=>{this._isWithActiveTrigger()||(this._hoverState!==on&&t.remove(),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),j.trigger(this._element,this.constructor.Event.HIDDEN),this._disposePopper())}),this.tip,e),this._hoverState=""}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement("div");t.innerHTML=this._config.template;const e=t.children[0];return this.setContent(e),e.classList.remove(nn,sn),this.tip=e,this.tip}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),an)}_sanitizeAndSetContent(t,e,i){const n=V.findOne(i,t);e||!n?this.setElementContent(n,e):n.remove()}setElementContent(t,e){if(null!==t)return o(e)?(e=r(e),void(this._config.html?e.parentNode!==t&&(t.innerHTML="",t.append(e)):t.textContent=e.textContent)):void(this._config.html?(this._config.sanitize&&(e=Yi(e,this._config.allowList,this._config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){const t=this._element.getAttribute("data-bs-original-title")||this._config.title;return this._resolvePossibleFunction(t)}updateAttachment(t){return"right"===t?"end":"left"===t?"start":t}_initializeOnDelegatedTarget(t,e){return e||this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return"function"==typeof t?t.call(this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(t)}`)}_getAttachment(t){return Ji[t.toUpperCase()]}_setListeners(){this._config.trigger.split(" ").forEach((t=>{if("click"===t)j.on(this._element,this.constructor.Event.CLICK,this._config.selector,(t=>this.toggle(t)));else if("manual"!==t){const e=t===hn?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,i=t===hn?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;j.on(this._element,e,this._config.selector,(t=>this._enter(t))),j.on(this._element,i,this._config.selector,(t=>this._leave(t)))}})),this._hideModalHandler=()=>{this._element&&this.hide()},j.on(this._element.closest(ln),cn,this._hideModalHandler),this._config.selector?this._config={...this._config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?dn:hn]=!0),e.getTipElement().classList.contains(sn)||e._hoverState===on?e._hoverState=on:(clearTimeout(e._timeout),e._hoverState=on,e._config.delay&&e._config.delay.show?e._timeout=setTimeout((()=>{e._hoverState===on&&e.show()}),e._config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?dn:hn]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=rn,e._config.delay&&e._config.delay.hide?e._timeout=setTimeout((()=>{e._hoverState===rn&&e.hide()}),e._config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=U.getDataAttributes(this._element);return Object.keys(e).forEach((t=>{Gi.has(t)&&delete e[t]})),(t={...this.constructor.Default,...e,..."object"==typeof t&&t?t:{}}).container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),a(Qi,t,this.constructor.DefaultType),t.sanitize&&(t.template=Yi(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`,"g"),i=t.getAttribute("class").match(e);null!==i&&i.length>0&&i.map((t=>t.trim())).forEach((e=>t.classList.remove(e)))}_getBasicClassPrefix(){return"bs-tooltip"}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null)}static jQueryInterface(t){return this.each((function(){const e=un.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(un);const fn={...un.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},pn={...un.DefaultType,content:"(string|element|function)"},mn={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class gn extends un{static get Default(){return fn}static get NAME(){return"popover"}static get Event(){return mn}static get DefaultType(){return pn}isWithContent(){return this.getTitle()||this._getContent()}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),".popover-header"),this._sanitizeAndSetContent(t,this._getContent(),".popover-body")}_getContent(){return this._resolvePossibleFunction(this._config.content)}_getBasicClassPrefix(){return"bs-popover"}static jQueryInterface(t){return this.each((function(){const e=gn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(gn);const _n="scrollspy",bn={offset:10,method:"auto",target:""},vn={offset:"number",method:"string",target:"(string|element)"},yn="active",wn=".nav-link, .list-group-item, .dropdown-item",En="position";class An extends B{constructor(t,e){super(t),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,j.on(this._scrollElement,"scroll.bs.scrollspy",(()=>this._process())),this.refresh(),this._process()}static get Default(){return bn}static get NAME(){return _n}refresh(){const t=this._scrollElement===this._scrollElement.window?"offset":En,e="auto"===this._config.method?t:this._config.method,n=e===En?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),V.find(wn,this._config.target).map((t=>{const s=i(t),o=s?V.findOne(s):null;if(o){const t=o.getBoundingClientRect();if(t.width||t.height)return[U[e](o).top+n,s]}return null})).filter((t=>t)).sort(((t,e)=>t[0]-e[0])).forEach((t=>{this._offsets.push(t[0]),this._targets.push(t[1])}))}dispose(){j.off(this._scrollElement,".bs.scrollspy"),super.dispose()}_getConfig(t){return(t={...bn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}}).target=r(t.target)||document.documentElement,a(_n,t,vn),t}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),i=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=i){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t`${e}[data-bs-target="${t}"],${e}[href="${t}"]`)),i=V.findOne(e.join(","),this._config.target);i.classList.add(yn),i.classList.contains("dropdown-item")?V.findOne(".dropdown-toggle",i.closest(".dropdown")).classList.add(yn):V.parents(i,".nav, .list-group").forEach((t=>{V.prev(t,".nav-link, .list-group-item").forEach((t=>t.classList.add(yn))),V.prev(t,".nav-item").forEach((t=>{V.children(t,".nav-link").forEach((t=>t.classList.add(yn)))}))})),j.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})}_clear(){V.find(wn,this._config.target).filter((t=>t.classList.contains(yn))).forEach((t=>t.classList.remove(yn)))}static jQueryInterface(t){return this.each((function(){const e=An.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(window,"load.bs.scrollspy.data-api",(()=>{V.find('[data-bs-spy="scroll"]').forEach((t=>new An(t)))})),g(An);const Tn="active",On="fade",Cn="show",kn=".active",Ln=":scope > li > .active";class xn extends B{static get NAME(){return"tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains(Tn))return;let t;const e=n(this._element),i=this._element.closest(".nav, .list-group");if(i){const e="UL"===i.nodeName||"OL"===i.nodeName?Ln:kn;t=V.find(e,i),t=t[t.length-1]}const s=t?j.trigger(t,"hide.bs.tab",{relatedTarget:this._element}):null;if(j.trigger(this._element,"show.bs.tab",{relatedTarget:t}).defaultPrevented||null!==s&&s.defaultPrevented)return;this._activate(this._element,i);const o=()=>{j.trigger(t,"hidden.bs.tab",{relatedTarget:this._element}),j.trigger(this._element,"shown.bs.tab",{relatedTarget:t})};e?this._activate(e,e.parentNode,o):o()}_activate(t,e,i){const n=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?V.children(e,kn):V.find(Ln,e))[0],s=i&&n&&n.classList.contains(On),o=()=>this._transitionComplete(t,n,i);n&&s?(n.classList.remove(Cn),this._queueCallback(o,t,!0)):o()}_transitionComplete(t,e,i){if(e){e.classList.remove(Tn);const t=V.findOne(":scope > .dropdown-menu .active",e.parentNode);t&&t.classList.remove(Tn),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add(Tn),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),u(t),t.classList.contains(On)&&t.classList.add(Cn);let n=t.parentNode;if(n&&"LI"===n.nodeName&&(n=n.parentNode),n&&n.classList.contains("dropdown-menu")){const e=t.closest(".dropdown");e&&V.find(".dropdown-toggle",e).forEach((t=>t.classList.add(Tn))),t.setAttribute("aria-expanded",!0)}i&&i()}static jQueryInterface(t){return this.each((function(){const e=xn.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this)||xn.getOrCreateInstance(this).show()})),g(xn);const Dn="toast",Sn="hide",Nn="show",In="showing",Pn={animation:"boolean",autohide:"boolean",delay:"number"},jn={animation:!0,autohide:!0,delay:5e3};class Mn extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get DefaultType(){return Pn}static get Default(){return jn}static get NAME(){return Dn}show(){j.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(Sn),u(this._element),this._element.classList.add(Nn),this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.remove(In),j.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this._element.classList.contains(Nn)&&(j.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.add(Sn),this._element.classList.remove(In),this._element.classList.remove(Nn),j.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this._element.classList.contains(Nn)&&this._element.classList.remove(Nn),super.dispose()}_getConfig(t){return t={...jn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}},a(Dn,t,this.constructor.DefaultType),t}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){j.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),j.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=Mn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(Mn),g(Mn),{Alert:W,Button:z,Carousel:st,Collapse:pt,Dropdown:hi,Modal:Hi,Offcanvas:Fi,Popover:gn,ScrollSpy:An,Tab:xn,Toast:Mn,Tooltip:un}})); +//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/docs/site_libs/clipboard/clipboard.min.js b/docs/site_libs/clipboard/clipboard.min.js new file mode 100644 index 0000000..41c6a0f --- /dev/null +++ b/docs/site_libs/clipboard/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.10 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1.container-fluid.crosstalk-bscols{margin-left:auto;margin-right:auto}.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:inline-block;padding-right:12px;vertical-align:top}@media only screen and (max-width: 480px){.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:block;padding-right:inherit}}.crosstalk-input{margin-bottom:15px}.crosstalk-input .control-label{margin-bottom:0;vertical-align:middle}.crosstalk-input input[type="checkbox"]{margin:4px 0 0;margin-top:1px;line-height:normal}.crosstalk-input .checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.crosstalk-input .checkbox>label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.crosstalk-input .checkbox input[type="checkbox"],.crosstalk-input .checkbox-inline input[type="checkbox"]{position:absolute;margin-top:2px;margin-left:-20px}.crosstalk-input .checkbox+.checkbox{margin-top:-5px}.crosstalk-input .checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.crosstalk-input .checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px} diff --git a/docs/site_libs/crosstalk-1.2.0/js/crosstalk.js b/docs/site_libs/crosstalk-1.2.0/js/crosstalk.js new file mode 100644 index 0000000..fd9eb53 --- /dev/null +++ b/docs/site_libs/crosstalk-1.2.0/js/crosstalk.js @@ -0,0 +1,1474 @@ +(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o b) { + return 1; + } +} + +/** + * @private + */ + +var FilterSet = function () { + function FilterSet() { + _classCallCheck(this, FilterSet); + + this.reset(); + } + + _createClass(FilterSet, [{ + key: "reset", + value: function reset() { + // Key: handle ID, Value: array of selected keys, or null + this._handles = {}; + // Key: key string, Value: count of handles that include it + this._keys = {}; + this._value = null; + this._activeHandles = 0; + } + }, { + key: "update", + value: function update(handleId, keys) { + if (keys !== null) { + keys = keys.slice(0); // clone before sorting + keys.sort(naturalComparator); + } + + var _diffSortedLists = (0, _util.diffSortedLists)(this._handles[handleId], keys), + added = _diffSortedLists.added, + removed = _diffSortedLists.removed; + + this._handles[handleId] = keys; + + for (var i = 0; i < added.length; i++) { + this._keys[added[i]] = (this._keys[added[i]] || 0) + 1; + } + for (var _i = 0; _i < removed.length; _i++) { + this._keys[removed[_i]]--; + } + + this._updateValue(keys); + } + + /** + * @param {string[]} keys Sorted array of strings that indicate + * a superset of possible keys. + * @private + */ + + }, { + key: "_updateValue", + value: function _updateValue() { + var keys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._allKeys; + + var handleCount = Object.keys(this._handles).length; + if (handleCount === 0) { + this._value = null; + } else { + this._value = []; + for (var i = 0; i < keys.length; i++) { + var count = this._keys[keys[i]]; + if (count === handleCount) { + this._value.push(keys[i]); + } + } + } + } + }, { + key: "clear", + value: function clear(handleId) { + if (typeof this._handles[handleId] === "undefined") { + return; + } + + var keys = this._handles[handleId]; + if (!keys) { + keys = []; + } + + for (var i = 0; i < keys.length; i++) { + this._keys[keys[i]]--; + } + delete this._handles[handleId]; + + this._updateValue(); + } + }, { + key: "value", + get: function get() { + return this._value; + } + }, { + key: "_allKeys", + get: function get() { + var allKeys = Object.keys(this._keys); + allKeys.sort(naturalComparator); + return allKeys; + } + }]); + + return FilterSet; +}(); + +exports.default = FilterSet; + +},{"./util":11}],4:[function(require,module,exports){ +(function (global){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.default = group; + +var _var2 = require("./var"); + +var _var3 = _interopRequireDefault(_var2); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +// Use a global so that multiple copies of crosstalk.js can be loaded and still +// have groups behave as singletons across all copies. +global.__crosstalk_groups = global.__crosstalk_groups || {}; +var groups = global.__crosstalk_groups; + +function group(groupName) { + if (groupName && typeof groupName === "string") { + if (!groups.hasOwnProperty(groupName)) { + groups[groupName] = new Group(groupName); + } + return groups[groupName]; + } else if ((typeof groupName === "undefined" ? "undefined" : _typeof(groupName)) === "object" && groupName._vars && groupName.var) { + // Appears to already be a group object + return groupName; + } else if (Array.isArray(groupName) && groupName.length == 1 && typeof groupName[0] === "string") { + return group(groupName[0]); + } else { + throw new Error("Invalid groupName argument"); + } +} + +var Group = function () { + function Group(name) { + _classCallCheck(this, Group); + + this.name = name; + this._vars = {}; + } + + _createClass(Group, [{ + key: "var", + value: function _var(name) { + if (!name || typeof name !== "string") { + throw new Error("Invalid var name"); + } + + if (!this._vars.hasOwnProperty(name)) this._vars[name] = new _var3.default(this, name); + return this._vars[name]; + } + }, { + key: "has", + value: function has(name) { + if (!name || typeof name !== "string") { + throw new Error("Invalid var name"); + } + + return this._vars.hasOwnProperty(name); + } + }]); + + return Group; +}(); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./var":12}],5:[function(require,module,exports){ +(function (global){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _group = require("./group"); + +var _group2 = _interopRequireDefault(_group); + +var _selection = require("./selection"); + +var _filter = require("./filter"); + +var _input = require("./input"); + +require("./input_selectize"); + +require("./input_checkboxgroup"); + +require("./input_slider"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var defaultGroup = (0, _group2.default)("default"); + +function var_(name) { + return defaultGroup.var(name); +} + +function has(name) { + return defaultGroup.has(name); +} + +if (global.Shiny) { + global.Shiny.addCustomMessageHandler("update-client-value", function (message) { + if (typeof message.group === "string") { + (0, _group2.default)(message.group).var(message.name).set(message.value); + } else { + var_(message.name).set(message.value); + } + }); +} + +var crosstalk = { + group: _group2.default, + var: var_, + has: has, + SelectionHandle: _selection.SelectionHandle, + FilterHandle: _filter.FilterHandle, + bind: _input.bind +}; + +/** + * @namespace crosstalk + */ +exports.default = crosstalk; + +global.crosstalk = crosstalk; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./filter":2,"./group":4,"./input":6,"./input_checkboxgroup":7,"./input_selectize":8,"./input_slider":9,"./selection":10}],6:[function(require,module,exports){ +(function (global){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.register = register; +exports.bind = bind; +var $ = global.jQuery; + +var bindings = {}; + +function register(reg) { + bindings[reg.className] = reg; + if (global.document && global.document.readyState !== "complete") { + $(function () { + bind(); + }); + } else if (global.document) { + setTimeout(bind, 100); + } +} + +function bind() { + Object.keys(bindings).forEach(function (className) { + var binding = bindings[className]; + $("." + binding.className).not(".crosstalk-input-bound").each(function (i, el) { + bindInstance(binding, el); + }); + }); +} + +// Escape jQuery identifier +function $escape(val) { + return val.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1"); +} + +function bindEl(el) { + var $el = $(el); + Object.keys(bindings).forEach(function (className) { + if ($el.hasClass(className) && !$el.hasClass("crosstalk-input-bound")) { + var binding = bindings[className]; + bindInstance(binding, el); + } + }); +} + +function bindInstance(binding, el) { + var jsonEl = $(el).find("script[type='application/json'][data-for='" + $escape(el.id) + "']"); + var data = JSON.parse(jsonEl[0].innerText); + + var instance = binding.factory(el, data); + $(el).data("crosstalk-instance", instance); + $(el).addClass("crosstalk-input-bound"); +} + +if (global.Shiny) { + var inputBinding = new global.Shiny.InputBinding(); + var _$ = global.jQuery; + _$.extend(inputBinding, { + find: function find(scope) { + return _$(scope).find(".crosstalk-input"); + }, + initialize: function initialize(el) { + if (!_$(el).hasClass("crosstalk-input-bound")) { + bindEl(el); + } + }, + getId: function getId(el) { + return el.id; + }, + getValue: function getValue(el) {}, + setValue: function setValue(el, value) {}, + receiveMessage: function receiveMessage(el, data) {}, + subscribe: function subscribe(el, callback) { + _$(el).data("crosstalk-instance").resume(); + }, + unsubscribe: function unsubscribe(el) { + _$(el).data("crosstalk-instance").suspend(); + } + }); + global.Shiny.inputBindings.register(inputBinding, "crosstalk.inputBinding"); +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],7:[function(require,module,exports){ +(function (global){ +"use strict"; + +var _input = require("./input"); + +var input = _interopRequireWildcard(_input); + +var _filter = require("./filter"); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var $ = global.jQuery; + +input.register({ + className: "crosstalk-input-checkboxgroup", + + factory: function factory(el, data) { + /* + * map: {"groupA": ["keyA", "keyB", ...], ...} + * group: "ct-groupname" + */ + var ctHandle = new _filter.FilterHandle(data.group); + + var lastKnownKeys = void 0; + var $el = $(el); + $el.on("change", "input[type='checkbox']", function () { + var checked = $el.find("input[type='checkbox']:checked"); + if (checked.length === 0) { + lastKnownKeys = null; + ctHandle.clear(); + } else { + var keys = {}; + checked.each(function () { + data.map[this.value].forEach(function (key) { + keys[key] = true; + }); + }); + var keyArray = Object.keys(keys); + keyArray.sort(); + lastKnownKeys = keyArray; + ctHandle.set(keyArray); + } + }); + + return { + suspend: function suspend() { + ctHandle.clear(); + }, + resume: function resume() { + if (lastKnownKeys) ctHandle.set(lastKnownKeys); + } + }; + } +}); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./filter":2,"./input":6}],8:[function(require,module,exports){ +(function (global){ +"use strict"; + +var _input = require("./input"); + +var input = _interopRequireWildcard(_input); + +var _util = require("./util"); + +var util = _interopRequireWildcard(_util); + +var _filter = require("./filter"); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var $ = global.jQuery; + +input.register({ + className: "crosstalk-input-select", + + factory: function factory(el, data) { + /* + * items: {value: [...], label: [...]} + * map: {"groupA": ["keyA", "keyB", ...], ...} + * group: "ct-groupname" + */ + + var first = [{ value: "", label: "(All)" }]; + var items = util.dataframeToD3(data.items); + var opts = { + options: first.concat(items), + valueField: "value", + labelField: "label", + searchField: "label" + }; + + var select = $(el).find("select")[0]; + + var selectize = $(select).selectize(opts)[0].selectize; + + var ctHandle = new _filter.FilterHandle(data.group); + + var lastKnownKeys = void 0; + selectize.on("change", function () { + if (selectize.items.length === 0) { + lastKnownKeys = null; + ctHandle.clear(); + } else { + var keys = {}; + selectize.items.forEach(function (group) { + data.map[group].forEach(function (key) { + keys[key] = true; + }); + }); + var keyArray = Object.keys(keys); + keyArray.sort(); + lastKnownKeys = keyArray; + ctHandle.set(keyArray); + } + }); + + return { + suspend: function suspend() { + ctHandle.clear(); + }, + resume: function resume() { + if (lastKnownKeys) ctHandle.set(lastKnownKeys); + } + }; + } +}); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./filter":2,"./input":6,"./util":11}],9:[function(require,module,exports){ +(function (global){ +"use strict"; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var _input = require("./input"); + +var input = _interopRequireWildcard(_input); + +var _filter = require("./filter"); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var $ = global.jQuery; +var strftime = global.strftime; + +input.register({ + className: "crosstalk-input-slider", + + factory: function factory(el, data) { + /* + * map: {"groupA": ["keyA", "keyB", ...], ...} + * group: "ct-groupname" + */ + var ctHandle = new _filter.FilterHandle(data.group); + + var opts = {}; + var $el = $(el).find("input"); + var dataType = $el.data("data-type"); + var timeFormat = $el.data("time-format"); + var round = $el.data("round"); + var timeFormatter = void 0; + + // Set up formatting functions + if (dataType === "date") { + timeFormatter = strftime.utc(); + opts.prettify = function (num) { + return timeFormatter(timeFormat, new Date(num)); + }; + } else if (dataType === "datetime") { + var timezone = $el.data("timezone"); + if (timezone) timeFormatter = strftime.timezone(timezone);else timeFormatter = strftime; + + opts.prettify = function (num) { + return timeFormatter(timeFormat, new Date(num)); + }; + } else if (dataType === "number") { + if (typeof round !== "undefined") opts.prettify = function (num) { + var factor = Math.pow(10, round); + return Math.round(num * factor) / factor; + }; + } + + $el.ionRangeSlider(opts); + + function getValue() { + var result = $el.data("ionRangeSlider").result; + + // Function for converting numeric value from slider to appropriate type. + var convert = void 0; + var dataType = $el.data("data-type"); + if (dataType === "date") { + convert = function convert(val) { + return formatDateUTC(new Date(+val)); + }; + } else if (dataType === "datetime") { + convert = function convert(val) { + // Convert ms to s + return +val / 1000; + }; + } else { + convert = function convert(val) { + return +val; + }; + } + + if ($el.data("ionRangeSlider").options.type === "double") { + return [convert(result.from), convert(result.to)]; + } else { + return convert(result.from); + } + } + + var lastKnownKeys = null; + + $el.on("change.crosstalkSliderInput", function (event) { + if (!$el.data("updating") && !$el.data("animating")) { + var _getValue = getValue(), + _getValue2 = _slicedToArray(_getValue, 2), + from = _getValue2[0], + to = _getValue2[1]; + + var keys = []; + for (var i = 0; i < data.values.length; i++) { + var val = data.values[i]; + if (val >= from && val <= to) { + keys.push(data.keys[i]); + } + } + keys.sort(); + ctHandle.set(keys); + lastKnownKeys = keys; + } + }); + + // let $el = $(el); + // $el.on("change", "input[type="checkbox"]", function() { + // let checked = $el.find("input[type="checkbox"]:checked"); + // if (checked.length === 0) { + // ctHandle.clear(); + // } else { + // let keys = {}; + // checked.each(function() { + // data.map[this.value].forEach(function(key) { + // keys[key] = true; + // }); + // }); + // let keyArray = Object.keys(keys); + // keyArray.sort(); + // ctHandle.set(keyArray); + // } + // }); + + return { + suspend: function suspend() { + ctHandle.clear(); + }, + resume: function resume() { + if (lastKnownKeys) ctHandle.set(lastKnownKeys); + } + }; + } +}); + +// Convert a number to a string with leading zeros +function padZeros(n, digits) { + var str = n.toString(); + while (str.length < digits) { + str = "0" + str; + }return str; +} + +// Given a Date object, return a string in yyyy-mm-dd format, using the +// UTC date. This may be a day off from the date in the local time zone. +function formatDateUTC(date) { + if (date instanceof Date) { + return date.getUTCFullYear() + "-" + padZeros(date.getUTCMonth() + 1, 2) + "-" + padZeros(date.getUTCDate(), 2); + } else { + return null; + } +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./filter":2,"./input":6}],10:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SelectionHandle = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _events = require("./events"); + +var _events2 = _interopRequireDefault(_events); + +var _group = require("./group"); + +var _group2 = _interopRequireDefault(_group); + +var _util = require("./util"); + +var util = _interopRequireWildcard(_util); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Use this class to read and write (and listen for changes to) the selection + * for a Crosstalk group. This is intended to be used for linked brushing. + * + * If two (or more) `SelectionHandle` instances in the same webpage share the + * same group name, they will share the same state. Setting the selection using + * one `SelectionHandle` instance will result in the `value` property instantly + * changing across the others, and `"change"` event listeners on all instances + * (including the one that initiated the sending) will fire. + * + * @param {string} [group] - The name of the Crosstalk group, or if none, + * null or undefined (or any other falsy value). This can be changed later + * via the [SelectionHandle#setGroup](#setGroup) method. + * @param {Object} [extraInfo] - An object whose properties will be copied to + * the event object whenever an event is emitted. + */ +var SelectionHandle = exports.SelectionHandle = function () { + function SelectionHandle() { + var group = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var extraInfo = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + _classCallCheck(this, SelectionHandle); + + this._eventRelay = new _events2.default(); + this._emitter = new util.SubscriptionTracker(this._eventRelay); + + // Name of the group we're currently tracking, if any. Can change over time. + this._group = null; + // The Var we're currently tracking, if any. Can change over time. + this._var = null; + // The event handler subscription we currently have on var.on("change"). + this._varOnChangeSub = null; + + this._extraInfo = util.extend({ sender: this }, extraInfo); + + this.setGroup(group); + } + + /** + * Changes the Crosstalk group membership of this SelectionHandle. The group + * being switched away from (if any) will not have its selection value + * modified as a result of calling `setGroup`, even if this handle was the + * most recent handle to set the selection of the group. + * + * The group being switched to (if any) will also not have its selection value + * modified as a result of calling `setGroup`. If you want to set the + * selection value of the new group, call `set` explicitly. + * + * @param {string} group - The name of the Crosstalk group, or null (or + * undefined) to clear the group. + */ + + + _createClass(SelectionHandle, [{ + key: "setGroup", + value: function setGroup(group) { + var _this = this; + + // If group is unchanged, do nothing + if (this._group === group) return; + // Treat null, undefined, and other falsy values the same + if (!this._group && !group) return; + + if (this._var) { + this._var.off("change", this._varOnChangeSub); + this._var = null; + this._varOnChangeSub = null; + } + + this._group = group; + + if (group) { + this._var = (0, _group2.default)(group).var("selection"); + var sub = this._var.on("change", function (e) { + _this._eventRelay.trigger("change", e, _this); + }); + this._varOnChangeSub = sub; + } + } + + /** + * Retrieves the current selection for the group represented by this + * `SelectionHandle`. + * + * - If no selection is active, then this value will be falsy. + * - If a selection is active, but no data points are selected, then this + * value will be an empty array. + * - If a selection is active, and data points are selected, then the keys + * of the selected data points will be present in the array. + */ + + }, { + key: "_mergeExtraInfo", + + + /** + * Combines the given `extraInfo` (if any) with the handle's default + * `_extraInfo` (if any). + * @private + */ + value: function _mergeExtraInfo(extraInfo) { + // Important incidental effect: shallow clone is returned + return util.extend({}, this._extraInfo ? this._extraInfo : null, extraInfo ? extraInfo : null); + } + + /** + * Overwrites the current selection for the group, and raises the `"change"` + * event among all of the group's '`SelectionHandle` instances (including + * this one). + * + * @fires SelectionHandle#change + * @param {string[]} selectedKeys - Falsy, empty array, or array of keys (see + * {@link SelectionHandle#value}). + * @param {Object} [extraInfo] - Extra properties to be included on the event + * object that's passed to listeners (in addition to any options that were + * passed into the `SelectionHandle` constructor). + */ + + }, { + key: "set", + value: function set(selectedKeys, extraInfo) { + if (this._var) this._var.set(selectedKeys, this._mergeExtraInfo(extraInfo)); + } + + /** + * Overwrites the current selection for the group, and raises the `"change"` + * event among all of the group's '`SelectionHandle` instances (including + * this one). + * + * @fires SelectionHandle#change + * @param {Object} [extraInfo] - Extra properties to be included on the event + * object that's passed to listeners (in addition to any that were passed + * into the `SelectionHandle` constructor). + */ + + }, { + key: "clear", + value: function clear(extraInfo) { + if (this._var) this.set(void 0, this._mergeExtraInfo(extraInfo)); + } + + /** + * Subscribes to events on this `SelectionHandle`. + * + * @param {string} eventType - Indicates the type of events to listen to. + * Currently, only `"change"` is supported. + * @param {SelectionHandle~listener} listener - The callback function that + * will be invoked when the event occurs. + * @return {string} - A token to pass to {@link SelectionHandle#off} to cancel + * this subscription. + */ + + }, { + key: "on", + value: function on(eventType, listener) { + return this._emitter.on(eventType, listener); + } + + /** + * Cancels event subscriptions created by {@link SelectionHandle#on}. + * + * @param {string} eventType - The type of event to unsubscribe. + * @param {string|SelectionHandle~listener} listener - Either the callback + * function previously passed into {@link SelectionHandle#on}, or the + * string that was returned from {@link SelectionHandle#on}. + */ + + }, { + key: "off", + value: function off(eventType, listener) { + return this._emitter.off(eventType, listener); + } + + /** + * Shuts down the `SelectionHandle` object. + * + * Removes all event listeners that were added through this handle. + */ + + }, { + key: "close", + value: function close() { + this._emitter.removeAllListeners(); + this.setGroup(null); + } + }, { + key: "value", + get: function get() { + return this._var ? this._var.get() : null; + } + }]); + + return SelectionHandle; +}(); + +/** + * @callback SelectionHandle~listener + * @param {Object} event - An object containing details of the event. For + * `"change"` events, this includes the properties `value` (the new + * value of the selection, or `undefined` if no selection is active), + * `oldValue` (the previous value of the selection), and `sender` (the + * `SelectionHandle` instance that made the change). + */ + +/** + * @event SelectionHandle#change + * @type {object} + * @property {object} value - The new value of the selection, or `undefined` + * if no selection is active. + * @property {object} oldValue - The previous value of the selection. + * @property {SelectionHandle} sender - The `SelectionHandle` instance that + * changed the value. + */ + +},{"./events":1,"./group":4,"./util":11}],11:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.extend = extend; +exports.checkSorted = checkSorted; +exports.diffSortedLists = diffSortedLists; +exports.dataframeToD3 = dataframeToD3; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function extend(target) { + for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + sources[_key - 1] = arguments[_key]; + } + + for (var i = 0; i < sources.length; i++) { + var src = sources[i]; + if (typeof src === "undefined" || src === null) continue; + + for (var key in src) { + if (src.hasOwnProperty(key)) { + target[key] = src[key]; + } + } + } + return target; +} + +function checkSorted(list) { + for (var i = 1; i < list.length; i++) { + if (list[i] <= list[i - 1]) { + throw new Error("List is not sorted or contains duplicate"); + } + } +} + +function diffSortedLists(a, b) { + var i_a = 0; + var i_b = 0; + + if (!a) a = []; + if (!b) b = []; + + var a_only = []; + var b_only = []; + + checkSorted(a); + checkSorted(b); + + while (i_a < a.length && i_b < b.length) { + if (a[i_a] === b[i_b]) { + i_a++; + i_b++; + } else if (a[i_a] < b[i_b]) { + a_only.push(a[i_a++]); + } else { + b_only.push(b[i_b++]); + } + } + + if (i_a < a.length) a_only = a_only.concat(a.slice(i_a)); + if (i_b < b.length) b_only = b_only.concat(b.slice(i_b)); + return { + removed: a_only, + added: b_only + }; +} + +// Convert from wide: { colA: [1,2,3], colB: [4,5,6], ... } +// to long: [ {colA: 1, colB: 4}, {colA: 2, colB: 5}, ... ] +function dataframeToD3(df) { + var names = []; + var length = void 0; + for (var name in df) { + if (df.hasOwnProperty(name)) names.push(name); + if (_typeof(df[name]) !== "object" || typeof df[name].length === "undefined") { + throw new Error("All fields must be arrays"); + } else if (typeof length !== "undefined" && length !== df[name].length) { + throw new Error("All fields must be arrays of the same length"); + } + length = df[name].length; + } + var results = []; + var item = void 0; + for (var row = 0; row < length; row++) { + item = {}; + for (var col = 0; col < names.length; col++) { + item[names[col]] = df[names[col]][row]; + } + results.push(item); + } + return results; +} + +/** + * Keeps track of all event listener additions/removals and lets all active + * listeners be removed with a single operation. + * + * @private + */ + +var SubscriptionTracker = exports.SubscriptionTracker = function () { + function SubscriptionTracker(emitter) { + _classCallCheck(this, SubscriptionTracker); + + this._emitter = emitter; + this._subs = {}; + } + + _createClass(SubscriptionTracker, [{ + key: "on", + value: function on(eventType, listener) { + var sub = this._emitter.on(eventType, listener); + this._subs[sub] = eventType; + return sub; + } + }, { + key: "off", + value: function off(eventType, listener) { + var sub = this._emitter.off(eventType, listener); + if (sub) { + delete this._subs[sub]; + } + return sub; + } + }, { + key: "removeAllListeners", + value: function removeAllListeners() { + var _this = this; + + var current_subs = this._subs; + this._subs = {}; + Object.keys(current_subs).forEach(function (sub) { + _this._emitter.off(current_subs[sub], sub); + }); + } + }]); + + return SubscriptionTracker; +}(); + +},{}],12:[function(require,module,exports){ +(function (global){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _events = require("./events"); + +var _events2 = _interopRequireDefault(_events); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Var = function () { + function Var(group, name, /*optional*/value) { + _classCallCheck(this, Var); + + this._group = group; + this._name = name; + this._value = value; + this._events = new _events2.default(); + } + + _createClass(Var, [{ + key: "get", + value: function get() { + return this._value; + } + }, { + key: "set", + value: function set(value, /*optional*/event) { + if (this._value === value) { + // Do nothing; the value hasn't changed + return; + } + var oldValue = this._value; + this._value = value; + // Alert JavaScript listeners that the value has changed + var evt = {}; + if (event && (typeof event === "undefined" ? "undefined" : _typeof(event)) === "object") { + for (var k in event) { + if (event.hasOwnProperty(k)) evt[k] = event[k]; + } + } + evt.oldValue = oldValue; + evt.value = value; + this._events.trigger("change", evt, this); + + // TODO: Make this extensible, to let arbitrary back-ends know that + // something has changed + if (global.Shiny && global.Shiny.onInputChange) { + global.Shiny.onInputChange(".clientValue-" + (this._group.name !== null ? this._group.name + "-" : "") + this._name, typeof value === "undefined" ? null : value); + } + } + }, { + key: "on", + value: function on(eventType, listener) { + return this._events.on(eventType, listener); + } + }, { + key: "off", + value: function off(eventType, listener) { + return this._events.off(eventType, listener); + } + }]); + + return Var; +}(); + +exports.default = Var; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./events":1}]},{},[5]) +//# sourceMappingURL=crosstalk.js.map diff --git a/docs/site_libs/crosstalk-1.2.0/js/crosstalk.js.map b/docs/site_libs/crosstalk-1.2.0/js/crosstalk.js.map new file mode 100644 index 0000000..cff94f0 --- /dev/null +++ b/docs/site_libs/crosstalk-1.2.0/js/crosstalk.js.map @@ -0,0 +1,37 @@ +{ + "version": 3, + "sources": [ + "node_modules/browser-pack/_prelude.js", + "javascript/src/events.js", + "javascript/src/filter.js", + "javascript/src/filterset.js", + "javascript/src/group.js", + "javascript/src/index.js", + "javascript/src/input.js", + "javascript/src/input_checkboxgroup.js", + "javascript/src/input_selectize.js", + "javascript/src/input_slider.js", + "javascript/src/selection.js", + "javascript/src/util.js", + "javascript/src/var.js" + ], + "names": [], + "mappings": "AAAA;;;;;;;;;;;ICAqB,M;AACnB,oBAAc;AAAA;;AACZ,SAAK,MAAL,GAAc,EAAd;AACA,SAAK,IAAL,GAAY,CAAZ;AACD;;;;uBAEE,S,EAAW,Q,EAAU;AACtB,UAAI,OAAO,KAAK,MAAL,CAAY,SAAZ,CAAX;AACA,UAAI,CAAC,IAAL,EAAW;AACT,eAAO,KAAK,MAAL,CAAY,SAAZ,IAAyB,EAAhC;AACD;AACD,UAAI,MAAM,QAAS,KAAK,IAAL,EAAnB;AACA,WAAK,GAAL,IAAY,QAAZ;AACA,aAAO,GAAP;AACD;;AAED;;;;wBACI,S,EAAW,Q,EAAU;AACvB,UAAI,OAAO,KAAK,MAAL,CAAY,SAAZ,CAAX;AACA,UAAI,OAAO,QAAP,KAAqB,UAAzB,EAAqC;AACnC,aAAK,IAAI,GAAT,IAAgB,IAAhB,EAAsB;AACpB,cAAI,KAAK,cAAL,CAAoB,GAApB,CAAJ,EAA8B;AAC5B,gBAAI,KAAK,GAAL,MAAc,QAAlB,EAA4B;AAC1B,qBAAO,KAAK,GAAL,CAAP;AACA,qBAAO,GAAP;AACD;AACF;AACF;AACD,eAAO,KAAP;AACD,OAVD,MAUO,IAAI,OAAO,QAAP,KAAqB,QAAzB,EAAmC;AACxC,YAAI,QAAQ,KAAK,QAAL,CAAZ,EAA4B;AAC1B,iBAAO,KAAK,QAAL,CAAP;AACA,iBAAO,QAAP;AACD;AACD,eAAO,KAAP;AACD,OANM,MAMA;AACL,cAAM,IAAI,KAAJ,CAAU,8BAAV,CAAN;AACD;AACF;;;4BAEO,S,EAAW,G,EAAK,O,EAAS;AAC/B,UAAI,OAAO,KAAK,MAAL,CAAY,SAAZ,CAAX;AACA,WAAK,IAAI,GAAT,IAAgB,IAAhB,EAAsB;AACpB,YAAI,KAAK,cAAL,CAAoB,GAApB,CAAJ,EAA8B;AAC5B,eAAK,GAAL,EAAU,IAAV,CAAe,OAAf,EAAwB,GAAxB;AACD;AACF;AACF;;;;;;kBA/CkB,M;;;;;;;;;;;;ACArB;;;;AACA;;;;AACA;;;;AACA;;IAAY,I;;;;;;;;AAEZ,SAAS,YAAT,CAAsB,KAAtB,EAA6B;AAC3B,MAAI,QAAQ,MAAM,GAAN,CAAU,WAAV,CAAZ;AACA,MAAI,SAAS,MAAM,GAAN,EAAb;AACA,MAAI,CAAC,MAAL,EAAa;AACX,aAAS,yBAAT;AACA,UAAM,GAAN,CAAU,MAAV;AACD;AACD,SAAO,MAAP;AACD;;AAED,IAAI,KAAK,CAAT;AACA,SAAS,MAAT,GAAkB;AAChB,SAAO,IAAP;AACD;;AAED;;;;;;;;;;;;;;;;;;;;;;;;;IAwBa,Y,WAAA,Y;AACX,wBAAY,KAAZ,EAAmB,SAAnB,EAA8B;AAAA;;AAC5B,SAAK,WAAL,GAAmB,sBAAnB;AACA,SAAK,QAAL,GAAgB,IAAI,KAAK,mBAAT,CAA6B,KAAK,WAAlC,CAAhB;;AAEA;AACA,SAAK,MAAL,GAAc,IAAd;AACA;AACA,SAAK,UAAL,GAAkB,IAAlB;AACA;AACA,SAAK,UAAL,GAAkB,IAAlB;AACA;AACA,SAAK,eAAL,GAAuB,IAAvB;;AAEA,SAAK,UAAL,GAAkB,KAAK,MAAL,CAAY,EAAE,QAAQ,IAAV,EAAZ,EAA8B,SAA9B,CAAlB;;AAEA,SAAK,GAAL,GAAW,WAAW,QAAtB;;AAEA,SAAK,QAAL,CAAc,KAAd;AACD;;AAED;;;;;;;;;;;;;;6BAUS,K,EAAO;AAAA;;AACd;AACA,UAAI,KAAK,MAAL,KAAgB,KAApB,EACE;AACF;AACA,UAAI,CAAC,KAAK,MAAN,IAAgB,CAAC,KAArB,EACE;;AAEF,UAAI,KAAK,UAAT,EAAqB;AACnB,aAAK,UAAL,CAAgB,GAAhB,CAAoB,QAApB,EAA8B,KAAK,eAAnC;AACA,aAAK,KAAL;AACA,aAAK,eAAL,GAAuB,IAAvB;AACA,aAAK,UAAL,GAAkB,IAAlB;AACA,aAAK,UAAL,GAAkB,IAAlB;AACD;;AAED,WAAK,MAAL,GAAc,KAAd;;AAEA,UAAI,KAAJ,EAAW;AACT,gBAAQ,qBAAI,KAAJ,CAAR;AACA,aAAK,UAAL,GAAkB,aAAa,KAAb,CAAlB;AACA,aAAK,UAAL,GAAkB,qBAAI,KAAJ,EAAW,GAAX,CAAe,QAAf,CAAlB;AACA,YAAI,MAAM,KAAK,UAAL,CAAgB,EAAhB,CAAmB,QAAnB,EAA6B,UAAC,CAAD,EAAO;AAC5C,gBAAK,WAAL,CAAiB,OAAjB,CAAyB,QAAzB,EAAmC,CAAnC;AACD,SAFS,CAAV;AAGA,aAAK,eAAL,GAAuB,GAAvB;AACD;AACF;;AAED;;;;;;;;oCAKgB,S,EAAW;AACzB,aAAO,KAAK,MAAL,CAAY,EAAZ,EACL,KAAK,UAAL,GAAkB,KAAK,UAAvB,GAAoC,IAD/B,EAEL,YAAY,SAAZ,GAAwB,IAFnB,CAAP;AAGD;;AAED;;;;;;;4BAIQ;AACN,WAAK,QAAL,CAAc,kBAAd;AACA,WAAK,KAAL;AACA,WAAK,QAAL,CAAc,IAAd;AACD;;AAED;;;;;;;;;;;;0BASM,S,EAAW;AACf,UAAI,CAAC,KAAK,UAAV,EACE;AACF,WAAK,UAAL,CAAgB,KAAhB,CAAsB,KAAK,GAA3B;AACA,WAAK,SAAL,CAAe,SAAf;AACD;;AAED;;;;;;;;;;;;;;;;;;;;wBAiBI,I,EAAM,S,EAAW;AACnB,UAAI,CAAC,KAAK,UAAV,EACE;AACF,WAAK,UAAL,CAAgB,MAAhB,CAAuB,KAAK,GAA5B,EAAiC,IAAjC;AACA,WAAK,SAAL,CAAe,SAAf;AACD;;AAED;;;;;;;;;;AASA;;;;;;;;;;uBAUG,S,EAAW,Q,EAAU;AACtB,aAAO,KAAK,QAAL,CAAc,EAAd,CAAiB,SAAjB,EAA4B,QAA5B,CAAP;AACD;;AAED;;;;;;;;;;;wBAQI,S,EAAW,Q,EAAU;AACvB,aAAO,KAAK,QAAL,CAAc,GAAd,CAAkB,SAAlB,EAA6B,QAA7B,CAAP;AACD;;;8BAES,S,EAAW;AACnB,UAAI,CAAC,KAAK,UAAV,EACE;AACF,WAAK,UAAL,CAAgB,GAAhB,CAAoB,KAAK,UAAL,CAAgB,KAApC,EAA2C,KAAK,eAAL,CAAqB,SAArB,CAA3C;AACD;;AAED;;;;;;;;;;;wBApCmB;AACjB,aAAO,KAAK,UAAL,GAAkB,KAAK,UAAL,CAAgB,KAAlC,GAA0C,IAAjD;AACD;;;;;;AA6CH;;;;;;;;;;;;;;;;;;;ACzNA;;;;AAEA,SAAS,iBAAT,CAA2B,CAA3B,EAA8B,CAA9B,EAAiC;AAC/B,MAAI,MAAM,CAAV,EAAa;AACX,WAAO,CAAP;AACD,GAFD,MAEO,IAAI,IAAI,CAAR,EAAW;AAChB,WAAO,CAAC,CAAR;AACD,GAFM,MAEA,IAAI,IAAI,CAAR,EAAW;AAChB,WAAO,CAAP;AACD;AACF;;AAED;;;;IAGqB,S;AACnB,uBAAc;AAAA;;AACZ,SAAK,KAAL;AACD;;;;4BAEO;AACN;AACA,WAAK,QAAL,GAAgB,EAAhB;AACA;AACA,WAAK,KAAL,GAAa,EAAb;AACA,WAAK,MAAL,GAAc,IAAd;AACA,WAAK,cAAL,GAAsB,CAAtB;AACD;;;2BAMM,Q,EAAU,I,EAAM;AACrB,UAAI,SAAS,IAAb,EAAmB;AACjB,eAAO,KAAK,KAAL,CAAW,CAAX,CAAP,CADiB,CACK;AACtB,aAAK,IAAL,CAAU,iBAAV;AACD;;AAJoB,6BAME,2BAAgB,KAAK,QAAL,CAAc,QAAd,CAAhB,EAAyC,IAAzC,CANF;AAAA,UAMhB,KANgB,oBAMhB,KANgB;AAAA,UAMT,OANS,oBAMT,OANS;;AAOrB,WAAK,QAAL,CAAc,QAAd,IAA0B,IAA1B;;AAEA,WAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,MAAM,MAA1B,EAAkC,GAAlC,EAAuC;AACrC,aAAK,KAAL,CAAW,MAAM,CAAN,CAAX,IAAuB,CAAC,KAAK,KAAL,CAAW,MAAM,CAAN,CAAX,KAAwB,CAAzB,IAA8B,CAArD;AACD;AACD,WAAK,IAAI,KAAI,CAAb,EAAgB,KAAI,QAAQ,MAA5B,EAAoC,IAApC,EAAyC;AACvC,aAAK,KAAL,CAAW,QAAQ,EAAR,CAAX;AACD;;AAED,WAAK,YAAL,CAAkB,IAAlB;AACD;;AAED;;;;;;;;mCAKmC;AAAA,UAAtB,IAAsB,uEAAf,KAAK,QAAU;;AACjC,UAAI,cAAc,OAAO,IAAP,CAAY,KAAK,QAAjB,EAA2B,MAA7C;AACA,UAAI,gBAAgB,CAApB,EAAuB;AACrB,aAAK,MAAL,GAAc,IAAd;AACD,OAFD,MAEO;AACL,aAAK,MAAL,GAAc,EAAd;AACA,aAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,KAAK,MAAzB,EAAiC,GAAjC,EAAsC;AACpC,cAAI,QAAQ,KAAK,KAAL,CAAW,KAAK,CAAL,CAAX,CAAZ;AACA,cAAI,UAAU,WAAd,EAA2B;AACzB,iBAAK,MAAL,CAAY,IAAZ,CAAiB,KAAK,CAAL,CAAjB;AACD;AACF;AACF;AACF;;;0BAEK,Q,EAAU;AACd,UAAI,OAAO,KAAK,QAAL,CAAc,QAAd,CAAP,KAAoC,WAAxC,EAAqD;AACnD;AACD;;AAED,UAAI,OAAO,KAAK,QAAL,CAAc,QAAd,CAAX;AACA,UAAI,CAAC,IAAL,EAAW;AACT,eAAO,EAAP;AACD;;AAED,WAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,KAAK,MAAzB,EAAiC,GAAjC,EAAsC;AACpC,aAAK,KAAL,CAAW,KAAK,CAAL,CAAX;AACD;AACD,aAAO,KAAK,QAAL,CAAc,QAAd,CAAP;;AAEA,WAAK,YAAL;AACD;;;wBA3DW;AACV,aAAO,KAAK,MAAZ;AACD;;;wBA2Dc;AACb,UAAI,UAAU,OAAO,IAAP,CAAY,KAAK,KAAjB,CAAd;AACA,cAAQ,IAAR,CAAa,iBAAb;AACA,aAAO,OAAP;AACD;;;;;;kBA/EkB,S;;;;;;;;;;;;;;kBCRG,K;;AAPxB;;;;;;;;AAEA;AACA;AACA,OAAO,kBAAP,GAA4B,OAAO,kBAAP,IAA6B,EAAzD;AACA,IAAI,SAAS,OAAO,kBAApB;;AAEe,SAAS,KAAT,CAAe,SAAf,EAA0B;AACvC,MAAI,aAAa,OAAO,SAAP,KAAsB,QAAvC,EAAiD;AAC/C,QAAI,CAAC,OAAO,cAAP,CAAsB,SAAtB,CAAL,EAAuC;AACrC,aAAO,SAAP,IAAoB,IAAI,KAAJ,CAAU,SAAV,CAApB;AACD;AACD,WAAO,OAAO,SAAP,CAAP;AACD,GALD,MAKO,IAAI,QAAO,SAAP,yCAAO,SAAP,OAAsB,QAAtB,IAAkC,UAAU,KAA5C,IAAqD,UAAU,GAAnE,EAAwE;AAC7E;AACA,WAAO,SAAP;AACD,GAHM,MAGA,IAAI,MAAM,OAAN,CAAc,SAAd,KACP,UAAU,MAAV,IAAoB,CADb,IAEP,OAAO,UAAU,CAAV,CAAP,KAAyB,QAFtB,EAEgC;AACrC,WAAO,MAAM,UAAU,CAAV,CAAN,CAAP;AACD,GAJM,MAIA;AACL,UAAM,IAAI,KAAJ,CAAU,4BAAV,CAAN;AACD;AACF;;IAEK,K;AACJ,iBAAY,IAAZ,EAAkB;AAAA;;AAChB,SAAK,IAAL,GAAY,IAAZ;AACA,SAAK,KAAL,GAAa,EAAb;AACD;;;;yBAEG,I,EAAM;AACR,UAAI,CAAC,IAAD,IAAS,OAAO,IAAP,KAAiB,QAA9B,EAAwC;AACtC,cAAM,IAAI,KAAJ,CAAU,kBAAV,CAAN;AACD;;AAED,UAAI,CAAC,KAAK,KAAL,CAAW,cAAX,CAA0B,IAA1B,CAAL,EACE,KAAK,KAAL,CAAW,IAAX,IAAmB,kBAAQ,IAAR,EAAc,IAAd,CAAnB;AACF,aAAO,KAAK,KAAL,CAAW,IAAX,CAAP;AACD;;;wBAEG,I,EAAM;AACR,UAAI,CAAC,IAAD,IAAS,OAAO,IAAP,KAAiB,QAA9B,EAAwC;AACtC,cAAM,IAAI,KAAJ,CAAU,kBAAV,CAAN;AACD;;AAED,aAAO,KAAK,KAAL,CAAW,cAAX,CAA0B,IAA1B,CAAP;AACD;;;;;;;;;;;;;;;;AC/CH;;;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;;;AAEA,IAAM,eAAe,qBAAM,SAAN,CAArB;;AAEA,SAAS,IAAT,CAAc,IAAd,EAAoB;AAClB,SAAO,aAAa,GAAb,CAAiB,IAAjB,CAAP;AACD;;AAED,SAAS,GAAT,CAAa,IAAb,EAAmB;AACjB,SAAO,aAAa,GAAb,CAAiB,IAAjB,CAAP;AACD;;AAED,IAAI,OAAO,KAAX,EAAkB;AAChB,SAAO,KAAP,CAAa,uBAAb,CAAqC,qBAArC,EAA4D,UAAS,OAAT,EAAkB;AAC5E,QAAI,OAAO,QAAQ,KAAf,KAA0B,QAA9B,EAAwC;AACtC,2BAAM,QAAQ,KAAd,EAAqB,GAArB,CAAyB,QAAQ,IAAjC,EAAuC,GAAvC,CAA2C,QAAQ,KAAnD;AACD,KAFD,MAEO;AACL,WAAK,QAAQ,IAAb,EAAmB,GAAnB,CAAuB,QAAQ,KAA/B;AACD;AACF,GAND;AAOD;;AAED,IAAM,YAAY;AAChB,wBADgB;AAEhB,OAAK,IAFW;AAGhB,OAAK,GAHW;AAIhB,6CAJgB;AAKhB,oCALgB;AAMhB;AANgB,CAAlB;;AASA;;;kBAGe,S;;AACf,OAAO,SAAP,GAAmB,SAAnB;;;;;;;;;;;QCrCgB,Q,GAAA,Q;QAWA,I,GAAA,I;AAfhB,IAAI,IAAI,OAAO,MAAf;;AAEA,IAAI,WAAW,EAAf;;AAEO,SAAS,QAAT,CAAkB,GAAlB,EAAuB;AAC5B,WAAS,IAAI,SAAb,IAA0B,GAA1B;AACA,MAAI,OAAO,QAAP,IAAmB,OAAO,QAAP,CAAgB,UAAhB,KAA+B,UAAtD,EAAkE;AAChE,MAAE,YAAM;AACN;AACD,KAFD;AAGD,GAJD,MAIO,IAAI,OAAO,QAAX,EAAqB;AAC1B,eAAW,IAAX,EAAiB,GAAjB;AACD;AACF;;AAEM,SAAS,IAAT,GAAgB;AACrB,SAAO,IAAP,CAAY,QAAZ,EAAsB,OAAtB,CAA8B,UAAS,SAAT,EAAoB;AAChD,QAAI,UAAU,SAAS,SAAT,CAAd;AACA,MAAE,MAAM,QAAQ,SAAhB,EAA2B,GAA3B,CAA+B,wBAA/B,EAAyD,IAAzD,CAA8D,UAAS,CAAT,EAAY,EAAZ,EAAgB;AAC5E,mBAAa,OAAb,EAAsB,EAAtB;AACD,KAFD;AAGD,GALD;AAMD;;AAED;AACA,SAAS,OAAT,CAAiB,GAAjB,EAAsB;AACpB,SAAO,IAAI,OAAJ,CAAY,uCAAZ,EAAqD,MAArD,CAAP;AACD;;AAED,SAAS,MAAT,CAAgB,EAAhB,EAAoB;AAClB,MAAI,MAAM,EAAE,EAAF,CAAV;AACA,SAAO,IAAP,CAAY,QAAZ,EAAsB,OAAtB,CAA8B,UAAS,SAAT,EAAoB;AAChD,QAAI,IAAI,QAAJ,CAAa,SAAb,KAA2B,CAAC,IAAI,QAAJ,CAAa,uBAAb,CAAhC,EAAuE;AACrE,UAAI,UAAU,SAAS,SAAT,CAAd;AACA,mBAAa,OAAb,EAAsB,EAAtB;AACD;AACF,GALD;AAMD;;AAED,SAAS,YAAT,CAAsB,OAAtB,EAA+B,EAA/B,EAAmC;AACjC,MAAI,SAAS,EAAE,EAAF,EAAM,IAAN,CAAW,+CAA+C,QAAQ,GAAG,EAAX,CAA/C,GAAgE,IAA3E,CAAb;AACA,MAAI,OAAO,KAAK,KAAL,CAAW,OAAO,CAAP,EAAU,SAArB,CAAX;;AAEA,MAAI,WAAW,QAAQ,OAAR,CAAgB,EAAhB,EAAoB,IAApB,CAAf;AACA,IAAE,EAAF,EAAM,IAAN,CAAW,oBAAX,EAAiC,QAAjC;AACA,IAAE,EAAF,EAAM,QAAN,CAAe,uBAAf;AACD;;AAED,IAAI,OAAO,KAAX,EAAkB;AAChB,MAAI,eAAe,IAAI,OAAO,KAAP,CAAa,YAAjB,EAAnB;AACA,MAAI,KAAI,OAAO,MAAf;AACA,KAAE,MAAF,CAAS,YAAT,EAAuB;AACrB,UAAM,cAAS,KAAT,EAAgB;AACpB,aAAO,GAAE,KAAF,EAAS,IAAT,CAAc,kBAAd,CAAP;AACD,KAHoB;AAIrB,gBAAY,oBAAS,EAAT,EAAa;AACvB,UAAI,CAAC,GAAE,EAAF,EAAM,QAAN,CAAe,uBAAf,CAAL,EAA8C;AAC5C,eAAO,EAAP;AACD;AACF,KARoB;AASrB,WAAO,eAAS,EAAT,EAAa;AAClB,aAAO,GAAG,EAAV;AACD,KAXoB;AAYrB,cAAU,kBAAS,EAAT,EAAa,CAEtB,CAdoB;AAerB,cAAU,kBAAS,EAAT,EAAa,KAAb,EAAoB,CAE7B,CAjBoB;AAkBrB,oBAAgB,wBAAS,EAAT,EAAa,IAAb,EAAmB,CAElC,CApBoB;AAqBrB,eAAW,mBAAS,EAAT,EAAa,QAAb,EAAuB;AAChC,SAAE,EAAF,EAAM,IAAN,CAAW,oBAAX,EAAiC,MAAjC;AACD,KAvBoB;AAwBrB,iBAAa,qBAAS,EAAT,EAAa;AACxB,SAAE,EAAF,EAAM,IAAN,CAAW,oBAAX,EAAiC,OAAjC;AACD;AA1BoB,GAAvB;AA4BA,SAAO,KAAP,CAAa,aAAb,CAA2B,QAA3B,CAAoC,YAApC,EAAkD,wBAAlD;AACD;;;;;;;;AChFD;;IAAY,K;;AACZ;;;;AAEA,IAAI,IAAI,OAAO,MAAf;;AAEA,MAAM,QAAN,CAAe;AACb,aAAW,+BADE;;AAGb,WAAS,iBAAS,EAAT,EAAa,IAAb,EAAmB;AAC1B;;;;AAIA,QAAI,WAAW,yBAAiB,KAAK,KAAtB,CAAf;;AAEA,QAAI,sBAAJ;AACA,QAAI,MAAM,EAAE,EAAF,CAAV;AACA,QAAI,EAAJ,CAAO,QAAP,EAAiB,wBAAjB,EAA2C,YAAW;AACpD,UAAI,UAAU,IAAI,IAAJ,CAAS,gCAAT,CAAd;AACA,UAAI,QAAQ,MAAR,KAAmB,CAAvB,EAA0B;AACxB,wBAAgB,IAAhB;AACA,iBAAS,KAAT;AACD,OAHD,MAGO;AACL,YAAI,OAAO,EAAX;AACA,gBAAQ,IAAR,CAAa,YAAW;AACtB,eAAK,GAAL,CAAS,KAAK,KAAd,EAAqB,OAArB,CAA6B,UAAS,GAAT,EAAc;AACzC,iBAAK,GAAL,IAAY,IAAZ;AACD,WAFD;AAGD,SAJD;AAKA,YAAI,WAAW,OAAO,IAAP,CAAY,IAAZ,CAAf;AACA,iBAAS,IAAT;AACA,wBAAgB,QAAhB;AACA,iBAAS,GAAT,CAAa,QAAb;AACD;AACF,KAjBD;;AAmBA,WAAO;AACL,eAAS,mBAAW;AAClB,iBAAS,KAAT;AACD,OAHI;AAIL,cAAQ,kBAAW;AACjB,YAAI,aAAJ,EACE,SAAS,GAAT,CAAa,aAAb;AACH;AAPI,KAAP;AASD;AAxCY,CAAf;;;;;;;;ACLA;;IAAY,K;;AACZ;;IAAY,I;;AACZ;;;;AAEA,IAAI,IAAI,OAAO,MAAf;;AAEA,MAAM,QAAN,CAAe;AACb,aAAW,wBADE;;AAGb,WAAS,iBAAS,EAAT,EAAa,IAAb,EAAmB;AAC1B;;;;;;AAMA,QAAI,QAAQ,CAAC,EAAC,OAAO,EAAR,EAAY,OAAO,OAAnB,EAAD,CAAZ;AACA,QAAI,QAAQ,KAAK,aAAL,CAAmB,KAAK,KAAxB,CAAZ;AACA,QAAI,OAAO;AACT,eAAS,MAAM,MAAN,CAAa,KAAb,CADA;AAET,kBAAY,OAFH;AAGT,kBAAY,OAHH;AAIT,mBAAa;AAJJ,KAAX;;AAOA,QAAI,SAAS,EAAE,EAAF,EAAM,IAAN,CAAW,QAAX,EAAqB,CAArB,CAAb;;AAEA,QAAI,YAAY,EAAE,MAAF,EAAU,SAAV,CAAoB,IAApB,EAA0B,CAA1B,EAA6B,SAA7C;;AAEA,QAAI,WAAW,yBAAiB,KAAK,KAAtB,CAAf;;AAEA,QAAI,sBAAJ;AACA,cAAU,EAAV,CAAa,QAAb,EAAuB,YAAW;AAChC,UAAI,UAAU,KAAV,CAAgB,MAAhB,KAA2B,CAA/B,EAAkC;AAChC,wBAAgB,IAAhB;AACA,iBAAS,KAAT;AACD,OAHD,MAGO;AACL,YAAI,OAAO,EAAX;AACA,kBAAU,KAAV,CAAgB,OAAhB,CAAwB,UAAS,KAAT,EAAgB;AACtC,eAAK,GAAL,CAAS,KAAT,EAAgB,OAAhB,CAAwB,UAAS,GAAT,EAAc;AACpC,iBAAK,GAAL,IAAY,IAAZ;AACD,WAFD;AAGD,SAJD;AAKA,YAAI,WAAW,OAAO,IAAP,CAAY,IAAZ,CAAf;AACA,iBAAS,IAAT;AACA,wBAAgB,QAAhB;AACA,iBAAS,GAAT,CAAa,QAAb;AACD;AACF,KAhBD;;AAkBA,WAAO;AACL,eAAS,mBAAW;AAClB,iBAAS,KAAT;AACD,OAHI;AAIL,cAAQ,kBAAW;AACjB,YAAI,aAAJ,EACE,SAAS,GAAT,CAAa,aAAb;AACH;AAPI,KAAP;AASD;AArDY,CAAf;;;;;;;;;;ACNA;;IAAY,K;;AACZ;;;;AAEA,IAAI,IAAI,OAAO,MAAf;AACA,IAAI,WAAW,OAAO,QAAtB;;AAEA,MAAM,QAAN,CAAe;AACb,aAAW,wBADE;;AAGb,WAAS,iBAAS,EAAT,EAAa,IAAb,EAAmB;AAC1B;;;;AAIA,QAAI,WAAW,yBAAiB,KAAK,KAAtB,CAAf;;AAEA,QAAI,OAAO,EAAX;AACA,QAAI,MAAM,EAAE,EAAF,EAAM,IAAN,CAAW,OAAX,CAAV;AACA,QAAI,WAAW,IAAI,IAAJ,CAAS,WAAT,CAAf;AACA,QAAI,aAAa,IAAI,IAAJ,CAAS,aAAT,CAAjB;AACA,QAAI,QAAQ,IAAI,IAAJ,CAAS,OAAT,CAAZ;AACA,QAAI,sBAAJ;;AAEA;AACA,QAAI,aAAa,MAAjB,EAAyB;AACvB,sBAAgB,SAAS,GAAT,EAAhB;AACA,WAAK,QAAL,GAAgB,UAAS,GAAT,EAAc;AAC5B,eAAO,cAAc,UAAd,EAA0B,IAAI,IAAJ,CAAS,GAAT,CAA1B,CAAP;AACD,OAFD;AAID,KAND,MAMO,IAAI,aAAa,UAAjB,EAA6B;AAClC,UAAI,WAAW,IAAI,IAAJ,CAAS,UAAT,CAAf;AACA,UAAI,QAAJ,EACE,gBAAgB,SAAS,QAAT,CAAkB,QAAlB,CAAhB,CADF,KAGE,gBAAgB,QAAhB;;AAEF,WAAK,QAAL,GAAgB,UAAS,GAAT,EAAc;AAC5B,eAAO,cAAc,UAAd,EAA0B,IAAI,IAAJ,CAAS,GAAT,CAA1B,CAAP;AACD,OAFD;AAGD,KAVM,MAUA,IAAI,aAAa,QAAjB,EAA2B;AAChC,UAAI,OAAO,KAAP,KAAiB,WAArB,EACE,KAAK,QAAL,GAAgB,UAAS,GAAT,EAAc;AAC5B,YAAI,SAAS,KAAK,GAAL,CAAS,EAAT,EAAa,KAAb,CAAb;AACA,eAAO,KAAK,KAAL,CAAW,MAAM,MAAjB,IAA2B,MAAlC;AACD,OAHD;AAIH;;AAED,QAAI,cAAJ,CAAmB,IAAnB;;AAEA,aAAS,QAAT,GAAoB;AAClB,UAAI,SAAS,IAAI,IAAJ,CAAS,gBAAT,EAA2B,MAAxC;;AAEA;AACA,UAAI,gBAAJ;AACA,UAAI,WAAW,IAAI,IAAJ,CAAS,WAAT,CAAf;AACA,UAAI,aAAa,MAAjB,EAAyB;AACvB,kBAAU,iBAAS,GAAT,EAAc;AACtB,iBAAO,cAAc,IAAI,IAAJ,CAAS,CAAC,GAAV,CAAd,CAAP;AACD,SAFD;AAGD,OAJD,MAIO,IAAI,aAAa,UAAjB,EAA6B;AAClC,kBAAU,iBAAS,GAAT,EAAc;AACtB;AACA,iBAAO,CAAC,GAAD,GAAO,IAAd;AACD,SAHD;AAID,OALM,MAKA;AACL,kBAAU,iBAAS,GAAT,EAAc;AAAE,iBAAO,CAAC,GAAR;AAAc,SAAxC;AACD;;AAED,UAAI,IAAI,IAAJ,CAAS,gBAAT,EAA2B,OAA3B,CAAmC,IAAnC,KAA4C,QAAhD,EAA0D;AACxD,eAAO,CAAC,QAAQ,OAAO,IAAf,CAAD,EAAuB,QAAQ,OAAO,EAAf,CAAvB,CAAP;AACD,OAFD,MAEO;AACL,eAAO,QAAQ,OAAO,IAAf,CAAP;AACD;AACF;;AAED,QAAI,gBAAgB,IAApB;;AAEA,QAAI,EAAJ,CAAO,6BAAP,EAAsC,UAAS,KAAT,EAAgB;AACpD,UAAI,CAAC,IAAI,IAAJ,CAAS,UAAT,CAAD,IAAyB,CAAC,IAAI,IAAJ,CAAS,WAAT,CAA9B,EAAqD;AAAA,wBAClC,UADkC;AAAA;AAAA,YAC9C,IAD8C;AAAA,YACxC,EADwC;;AAEnD,YAAI,OAAO,EAAX;AACA,aAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,KAAK,MAAL,CAAY,MAAhC,EAAwC,GAAxC,EAA6C;AAC3C,cAAI,MAAM,KAAK,MAAL,CAAY,CAAZ,CAAV;AACA,cAAI,OAAO,IAAP,IAAe,OAAO,EAA1B,EAA8B;AAC5B,iBAAK,IAAL,CAAU,KAAK,IAAL,CAAU,CAAV,CAAV;AACD;AACF;AACD,aAAK,IAAL;AACA,iBAAS,GAAT,CAAa,IAAb;AACA,wBAAgB,IAAhB;AACD;AACF,KAdD;;AAiBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,WAAO;AACL,eAAS,mBAAW;AAClB,iBAAS,KAAT;AACD,OAHI;AAIL,cAAQ,kBAAW;AACjB,YAAI,aAAJ,EACE,SAAS,GAAT,CAAa,aAAb;AACH;AAPI,KAAP;AASD;AApHY,CAAf;;AAwHA;AACA,SAAS,QAAT,CAAkB,CAAlB,EAAqB,MAArB,EAA6B;AAC3B,MAAI,MAAM,EAAE,QAAF,EAAV;AACA,SAAO,IAAI,MAAJ,GAAa,MAApB;AACE,UAAM,MAAM,GAAZ;AADF,GAEA,OAAO,GAAP;AACD;;AAED;AACA;AACA,SAAS,aAAT,CAAuB,IAAvB,EAA6B;AAC3B,MAAI,gBAAgB,IAApB,EAA0B;AACxB,WAAO,KAAK,cAAL,KAAwB,GAAxB,GACA,SAAS,KAAK,WAAL,KAAmB,CAA5B,EAA+B,CAA/B,CADA,GACoC,GADpC,GAEA,SAAS,KAAK,UAAL,EAAT,EAA4B,CAA5B,CAFP;AAID,GALD,MAKO;AACL,WAAO,IAAP;AACD;AACF;;;;;;;;;;;;;;ACjJD;;;;AACA;;;;AACA;;IAAY,I;;;;;;;;AAEZ;;;;;;;;;;;;;;;;IAgBa,e,WAAA,e;AAEX,6BAA4C;AAAA,QAAhC,KAAgC,uEAAxB,IAAwB;AAAA,QAAlB,SAAkB,uEAAN,IAAM;;AAAA;;AAC1C,SAAK,WAAL,GAAmB,sBAAnB;AACA,SAAK,QAAL,GAAgB,IAAI,KAAK,mBAAT,CAA6B,KAAK,WAAlC,CAAhB;;AAEA;AACA,SAAK,MAAL,GAAc,IAAd;AACA;AACA,SAAK,IAAL,GAAY,IAAZ;AACA;AACA,SAAK,eAAL,GAAuB,IAAvB;;AAEA,SAAK,UAAL,GAAkB,KAAK,MAAL,CAAY,EAAE,QAAQ,IAAV,EAAZ,EAA8B,SAA9B,CAAlB;;AAEA,SAAK,QAAL,CAAc,KAAd;AACD;;AAED;;;;;;;;;;;;;;;;;6BAaS,K,EAAO;AAAA;;AACd;AACA,UAAI,KAAK,MAAL,KAAgB,KAApB,EACE;AACF;AACA,UAAI,CAAC,KAAK,MAAN,IAAgB,CAAC,KAArB,EACE;;AAEF,UAAI,KAAK,IAAT,EAAe;AACb,aAAK,IAAL,CAAU,GAAV,CAAc,QAAd,EAAwB,KAAK,eAA7B;AACA,aAAK,IAAL,GAAY,IAAZ;AACA,aAAK,eAAL,GAAuB,IAAvB;AACD;;AAED,WAAK,MAAL,GAAc,KAAd;;AAEA,UAAI,KAAJ,EAAW;AACT,aAAK,IAAL,GAAY,qBAAI,KAAJ,EAAW,GAAX,CAAe,WAAf,CAAZ;AACA,YAAI,MAAM,KAAK,IAAL,CAAU,EAAV,CAAa,QAAb,EAAuB,UAAC,CAAD,EAAO;AACtC,gBAAK,WAAL,CAAiB,OAAjB,CAAyB,QAAzB,EAAmC,CAAnC;AACD,SAFS,CAAV;AAGA,aAAK,eAAL,GAAuB,GAAvB;AACD;AACF;;AAED;;;;;;;;;;;;;;;AAcA;;;;;oCAKgB,S,EAAW;AACzB;AACA,aAAO,KAAK,MAAL,CAAY,EAAZ,EACL,KAAK,UAAL,GAAkB,KAAK,UAAvB,GAAoC,IAD/B,EAEL,YAAY,SAAZ,GAAwB,IAFnB,CAAP;AAGD;;AAED;;;;;;;;;;;;;;;wBAYI,Y,EAAc,S,EAAW;AAC3B,UAAI,KAAK,IAAT,EACE,KAAK,IAAL,CAAU,GAAV,CAAc,YAAd,EAA4B,KAAK,eAAL,CAAqB,SAArB,CAA5B;AACH;;AAED;;;;;;;;;;;;;0BAUM,S,EAAW;AACf,UAAI,KAAK,IAAT,EACE,KAAK,GAAL,CAAS,KAAK,CAAd,EAAiB,KAAK,eAAL,CAAqB,SAArB,CAAjB;AACH;;AAED;;;;;;;;;;;;;uBAUG,S,EAAW,Q,EAAU;AACtB,aAAO,KAAK,QAAL,CAAc,EAAd,CAAiB,SAAjB,EAA4B,QAA5B,CAAP;AACD;;AAED;;;;;;;;;;;wBAQI,S,EAAW,Q,EAAU;AACvB,aAAO,KAAK,QAAL,CAAc,GAAd,CAAkB,SAAlB,EAA6B,QAA7B,CAAP;AACD;;AAED;;;;;;;;4BAKQ;AACN,WAAK,QAAL,CAAc,kBAAd;AACA,WAAK,QAAL,CAAc,IAAd;AACD;;;wBAlFW;AACV,aAAO,KAAK,IAAL,GAAY,KAAK,IAAL,CAAU,GAAV,EAAZ,GAA8B,IAArC;AACD;;;;;;AAmFH;;;;;;;;;AASA;;;;;;;;;;;;;;;;;;;;;QCpLgB,M,GAAA,M;QAeA,W,GAAA,W;QAQA,e,GAAA,e;QAoCA,a,GAAA,a;;;;AA3DT,SAAS,MAAT,CAAgB,MAAhB,EAAoC;AAAA,oCAAT,OAAS;AAAT,WAAS;AAAA;;AACzC,OAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,QAAQ,MAA5B,EAAoC,GAApC,EAAyC;AACvC,QAAI,MAAM,QAAQ,CAAR,CAAV;AACA,QAAI,OAAO,GAAP,KAAgB,WAAhB,IAA+B,QAAQ,IAA3C,EACE;;AAEF,SAAK,IAAI,GAAT,IAAgB,GAAhB,EAAqB;AACnB,UAAI,IAAI,cAAJ,CAAmB,GAAnB,CAAJ,EAA6B;AAC3B,eAAO,GAAP,IAAc,IAAI,GAAJ,CAAd;AACD;AACF;AACF;AACD,SAAO,MAAP;AACD;;AAEM,SAAS,WAAT,CAAqB,IAArB,EAA2B;AAChC,OAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,KAAK,MAAzB,EAAiC,GAAjC,EAAsC;AACpC,QAAI,KAAK,CAAL,KAAW,KAAK,IAAE,CAAP,CAAf,EAA0B;AACxB,YAAM,IAAI,KAAJ,CAAU,0CAAV,CAAN;AACD;AACF;AACF;;AAEM,SAAS,eAAT,CAAyB,CAAzB,EAA4B,CAA5B,EAA+B;AACpC,MAAI,MAAM,CAAV;AACA,MAAI,MAAM,CAAV;;AAEA,MAAI,CAAC,CAAL,EAAQ,IAAI,EAAJ;AACR,MAAI,CAAC,CAAL,EAAQ,IAAI,EAAJ;;AAER,MAAI,SAAS,EAAb;AACA,MAAI,SAAS,EAAb;;AAEA,cAAY,CAAZ;AACA,cAAY,CAAZ;;AAEA,SAAO,MAAM,EAAE,MAAR,IAAkB,MAAM,EAAE,MAAjC,EAAyC;AACvC,QAAI,EAAE,GAAF,MAAW,EAAE,GAAF,CAAf,EAAuB;AACrB;AACA;AACD,KAHD,MAGO,IAAI,EAAE,GAAF,IAAS,EAAE,GAAF,CAAb,EAAqB;AAC1B,aAAO,IAAP,CAAY,EAAE,KAAF,CAAZ;AACD,KAFM,MAEA;AACL,aAAO,IAAP,CAAY,EAAE,KAAF,CAAZ;AACD;AACF;;AAED,MAAI,MAAM,EAAE,MAAZ,EACE,SAAS,OAAO,MAAP,CAAc,EAAE,KAAF,CAAQ,GAAR,CAAd,CAAT;AACF,MAAI,MAAM,EAAE,MAAZ,EACE,SAAS,OAAO,MAAP,CAAc,EAAE,KAAF,CAAQ,GAAR,CAAd,CAAT;AACF,SAAO;AACL,aAAS,MADJ;AAEL,WAAO;AAFF,GAAP;AAID;;AAED;AACA;AACO,SAAS,aAAT,CAAuB,EAAvB,EAA2B;AAChC,MAAI,QAAQ,EAAZ;AACA,MAAI,eAAJ;AACA,OAAK,IAAI,IAAT,IAAiB,EAAjB,EAAqB;AACnB,QAAI,GAAG,cAAH,CAAkB,IAAlB,CAAJ,EACE,MAAM,IAAN,CAAW,IAAX;AACF,QAAI,QAAO,GAAG,IAAH,CAAP,MAAqB,QAArB,IAAiC,OAAO,GAAG,IAAH,EAAS,MAAhB,KAA4B,WAAjE,EAA8E;AAC5E,YAAM,IAAI,KAAJ,CAAU,2BAAV,CAAN;AACD,KAFD,MAEO,IAAI,OAAO,MAAP,KAAmB,WAAnB,IAAkC,WAAW,GAAG,IAAH,EAAS,MAA1D,EAAkE;AACvE,YAAM,IAAI,KAAJ,CAAU,8CAAV,CAAN;AACD;AACD,aAAS,GAAG,IAAH,EAAS,MAAlB;AACD;AACD,MAAI,UAAU,EAAd;AACA,MAAI,aAAJ;AACA,OAAK,IAAI,MAAM,CAAf,EAAkB,MAAM,MAAxB,EAAgC,KAAhC,EAAuC;AACrC,WAAO,EAAP;AACA,SAAK,IAAI,MAAM,CAAf,EAAkB,MAAM,MAAM,MAA9B,EAAsC,KAAtC,EAA6C;AAC3C,WAAK,MAAM,GAAN,CAAL,IAAmB,GAAG,MAAM,GAAN,CAAH,EAAe,GAAf,CAAnB;AACD;AACD,YAAQ,IAAR,CAAa,IAAb;AACD;AACD,SAAO,OAAP;AACD;;AAED;;;;;;;IAMa,mB,WAAA,mB;AACX,+BAAY,OAAZ,EAAqB;AAAA;;AACnB,SAAK,QAAL,GAAgB,OAAhB;AACA,SAAK,KAAL,GAAa,EAAb;AACD;;;;uBAEE,S,EAAW,Q,EAAU;AACtB,UAAI,MAAM,KAAK,QAAL,CAAc,EAAd,CAAiB,SAAjB,EAA4B,QAA5B,CAAV;AACA,WAAK,KAAL,CAAW,GAAX,IAAkB,SAAlB;AACA,aAAO,GAAP;AACD;;;wBAEG,S,EAAW,Q,EAAU;AACvB,UAAI,MAAM,KAAK,QAAL,CAAc,GAAd,CAAkB,SAAlB,EAA6B,QAA7B,CAAV;AACA,UAAI,GAAJ,EAAS;AACP,eAAO,KAAK,KAAL,CAAW,GAAX,CAAP;AACD;AACD,aAAO,GAAP;AACD;;;yCAEoB;AAAA;;AACnB,UAAI,eAAe,KAAK,KAAxB;AACA,WAAK,KAAL,GAAa,EAAb;AACA,aAAO,IAAP,CAAY,YAAZ,EAA0B,OAA1B,CAAkC,UAAC,GAAD,EAAS;AACzC,cAAK,QAAL,CAAc,GAAd,CAAkB,aAAa,GAAb,CAAlB,EAAqC,GAArC;AACD,OAFD;AAGD;;;;;;;;;;;;;;;;;;ACpHH;;;;;;;;IAEqB,G;AACnB,eAAY,KAAZ,EAAmB,IAAnB,EAAyB,YAAa,KAAtC,EAA6C;AAAA;;AAC3C,SAAK,MAAL,GAAc,KAAd;AACA,SAAK,KAAL,GAAa,IAAb;AACA,SAAK,MAAL,GAAc,KAAd;AACA,SAAK,OAAL,GAAe,sBAAf;AACD;;;;0BAEK;AACJ,aAAO,KAAK,MAAZ;AACD;;;wBAEG,K,EAAO,YAAa,K,EAAO;AAC7B,UAAI,KAAK,MAAL,KAAgB,KAApB,EAA2B;AACzB;AACA;AACD;AACD,UAAI,WAAW,KAAK,MAApB;AACA,WAAK,MAAL,GAAc,KAAd;AACA;AACA,UAAI,MAAM,EAAV;AACA,UAAI,SAAS,QAAO,KAAP,yCAAO,KAAP,OAAkB,QAA/B,EAAyC;AACvC,aAAK,IAAI,CAAT,IAAc,KAAd,EAAqB;AACnB,cAAI,MAAM,cAAN,CAAqB,CAArB,CAAJ,EACE,IAAI,CAAJ,IAAS,MAAM,CAAN,CAAT;AACH;AACF;AACD,UAAI,QAAJ,GAAe,QAAf;AACA,UAAI,KAAJ,GAAY,KAAZ;AACA,WAAK,OAAL,CAAa,OAAb,CAAqB,QAArB,EAA+B,GAA/B,EAAoC,IAApC;;AAEA;AACA;AACA,UAAI,OAAO,KAAP,IAAgB,OAAO,KAAP,CAAa,aAAjC,EAAgD;AAC9C,eAAO,KAAP,CAAa,aAAb,CACE,mBACG,KAAK,MAAL,CAAY,IAAZ,KAAqB,IAArB,GAA4B,KAAK,MAAL,CAAY,IAAZ,GAAmB,GAA/C,GAAqD,EADxD,IAEE,KAAK,KAHT,EAIE,OAAO,KAAP,KAAkB,WAAlB,GAAgC,IAAhC,GAAuC,KAJzC;AAMD;AACF;;;uBAEE,S,EAAW,Q,EAAU;AACtB,aAAO,KAAK,OAAL,CAAa,EAAb,CAAgB,SAAhB,EAA2B,QAA3B,CAAP;AACD;;;wBAEG,S,EAAW,Q,EAAU;AACvB,aAAO,KAAK,OAAL,CAAa,GAAb,CAAiB,SAAjB,EAA4B,QAA5B,CAAP;AACD;;;;;;kBAjDkB,G", + "file": "generated.js", + "sourceRoot": "", + "sourcesContent": [ + "(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o {\n this._eventRelay.trigger(\"change\", e, this);\n });\n this._varOnChangeSub = sub;\n }\n }\n\n /**\n * Combine the given `extraInfo` (if any) with the handle's default\n * `_extraInfo` (if any).\n * @private\n */\n _mergeExtraInfo(extraInfo) {\n return util.extend({},\n this._extraInfo ? this._extraInfo : null,\n extraInfo ? extraInfo : null);\n }\n\n /**\n * Close the handle. This clears this handle's contribution to the filter set,\n * and unsubscribes all event listeners.\n */\n close() {\n this._emitter.removeAllListeners();\n this.clear();\n this.setGroup(null);\n }\n\n /**\n * Clear this handle's contribution to the filter set.\n *\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `FilterHandle` constructor).\n * \n * @fires FilterHandle#change\n */\n clear(extraInfo) {\n if (!this._filterSet)\n return;\n this._filterSet.clear(this._id);\n this._onChange(extraInfo);\n }\n\n /**\n * Set this handle's contribution to the filter set. This array should consist\n * of the keys of the rows that _should_ be displayed; any keys that are not\n * present in the array will be considered _filtered out_. Note that multiple\n * `FilterHandle` instances in the group may each contribute an array of keys,\n * and only those keys that appear in _all_ of the arrays make it through the\n * filter.\n *\n * @param {string[]} keys - Empty array, or array of keys. To clear the\n * filter, don't pass an empty array; instead, use the\n * {@link FilterHandle#clear} method.\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `FilterHandle` constructor).\n * \n * @fires FilterHandle#change\n */\n set(keys, extraInfo) {\n if (!this._filterSet)\n return;\n this._filterSet.update(this._id, keys);\n this._onChange(extraInfo);\n }\n\n /**\n * @return {string[]|null} - Either: 1) an array of keys that made it through\n * all of the `FilterHandle` instances, or, 2) `null`, which means no filter\n * is being applied (all data should be displayed).\n */\n get filteredKeys() {\n return this._filterSet ? this._filterSet.value : null;\n }\n\n /**\n * Subscribe to events on this `FilterHandle`.\n *\n * @param {string} eventType - Indicates the type of events to listen to.\n * Currently, only `\"change\"` is supported.\n * @param {FilterHandle~listener} listener - The callback function that\n * will be invoked when the event occurs.\n * @return {string} - A token to pass to {@link FilterHandle#off} to cancel\n * this subscription.\n */\n on(eventType, listener) {\n return this._emitter.on(eventType, listener);\n }\n\n /**\n * Cancel event subscriptions created by {@link FilterHandle#on}.\n *\n * @param {string} eventType - The type of event to unsubscribe.\n * @param {string|FilterHandle~listener} listener - Either the callback\n * function previously passed into {@link FilterHandle#on}, or the\n * string that was returned from {@link FilterHandle#on}.\n */\n off(eventType, listener) {\n return this._emitter.off(eventType, listener);\n }\n\n _onChange(extraInfo) {\n if (!this._filterSet)\n return;\n this._filterVar.set(this._filterSet.value, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * @callback FilterHandle~listener\n * @param {Object} event - An object containing details of the event. For\n * `\"change\"` events, this includes the properties `value` (the new\n * value of the filter set, or `null` if no filter set is active),\n * `oldValue` (the previous value of the filter set), and `sender` (the\n * `FilterHandle` instance that made the change).\n */\n\n}\n\n/**\n * @event FilterHandle#change\n * @type {object}\n * @property {object} value - The new value of the filter set, or `null`\n * if no filter set is active.\n * @property {object} oldValue - The previous value of the filter set.\n * @property {FilterHandle} sender - The `FilterHandle` instance that\n * changed the value.\n */\n", + "import { diffSortedLists } from \"./util\";\n\nfunction naturalComparator(a, b) {\n if (a === b) {\n return 0;\n } else if (a < b) {\n return -1;\n } else if (a > b) {\n return 1;\n }\n}\n\n/**\n * @private\n */\nexport default class FilterSet {\n constructor() {\n this.reset();\n }\n\n reset() {\n // Key: handle ID, Value: array of selected keys, or null\n this._handles = {};\n // Key: key string, Value: count of handles that include it\n this._keys = {};\n this._value = null;\n this._activeHandles = 0;\n }\n\n get value() {\n return this._value;\n }\n\n update(handleId, keys) {\n if (keys !== null) {\n keys = keys.slice(0); // clone before sorting\n keys.sort(naturalComparator);\n }\n\n let {added, removed} = diffSortedLists(this._handles[handleId], keys);\n this._handles[handleId] = keys;\n\n for (let i = 0; i < added.length; i++) {\n this._keys[added[i]] = (this._keys[added[i]] || 0) + 1;\n }\n for (let i = 0; i < removed.length; i++) {\n this._keys[removed[i]]--;\n }\n\n this._updateValue(keys);\n }\n\n /**\n * @param {string[]} keys Sorted array of strings that indicate\n * a superset of possible keys.\n * @private\n */\n _updateValue(keys = this._allKeys) {\n let handleCount = Object.keys(this._handles).length;\n if (handleCount === 0) {\n this._value = null;\n } else {\n this._value = [];\n for (let i = 0; i < keys.length; i++) {\n let count = this._keys[keys[i]];\n if (count === handleCount) {\n this._value.push(keys[i]);\n }\n }\n }\n }\n\n clear(handleId) {\n if (typeof(this._handles[handleId]) === \"undefined\") {\n return;\n }\n\n let keys = this._handles[handleId];\n if (!keys) {\n keys = [];\n }\n\n for (let i = 0; i < keys.length; i++) {\n this._keys[keys[i]]--;\n }\n delete this._handles[handleId];\n\n this._updateValue();\n }\n\n get _allKeys() {\n let allKeys = Object.keys(this._keys);\n allKeys.sort(naturalComparator);\n return allKeys;\n }\n}\n", + "import Var from \"./var\";\n\n// Use a global so that multiple copies of crosstalk.js can be loaded and still\n// have groups behave as singletons across all copies.\nglobal.__crosstalk_groups = global.__crosstalk_groups || {};\nlet groups = global.__crosstalk_groups;\n\nexport default function group(groupName) {\n if (groupName && typeof(groupName) === \"string\") {\n if (!groups.hasOwnProperty(groupName)) {\n groups[groupName] = new Group(groupName);\n }\n return groups[groupName];\n } else if (typeof(groupName) === \"object\" && groupName._vars && groupName.var) {\n // Appears to already be a group object\n return groupName;\n } else if (Array.isArray(groupName) &&\n groupName.length == 1 &&\n typeof(groupName[0]) === \"string\") {\n return group(groupName[0]);\n } else {\n throw new Error(\"Invalid groupName argument\");\n }\n}\n\nclass Group {\n constructor(name) {\n this.name = name;\n this._vars = {};\n }\n\n var(name) {\n if (!name || typeof(name) !== \"string\") {\n throw new Error(\"Invalid var name\");\n }\n\n if (!this._vars.hasOwnProperty(name))\n this._vars[name] = new Var(this, name);\n return this._vars[name];\n }\n\n has(name) {\n if (!name || typeof(name) !== \"string\") {\n throw new Error(\"Invalid var name\");\n }\n\n return this._vars.hasOwnProperty(name);\n }\n}\n", + "import group from \"./group\";\nimport { SelectionHandle } from \"./selection\";\nimport { FilterHandle } from \"./filter\";\nimport { bind } from \"./input\";\nimport \"./input_selectize\";\nimport \"./input_checkboxgroup\";\nimport \"./input_slider\";\n\nconst defaultGroup = group(\"default\");\n\nfunction var_(name) {\n return defaultGroup.var(name);\n}\n\nfunction has(name) {\n return defaultGroup.has(name);\n}\n\nif (global.Shiny) {\n global.Shiny.addCustomMessageHandler(\"update-client-value\", function(message) {\n if (typeof(message.group) === \"string\") {\n group(message.group).var(message.name).set(message.value);\n } else {\n var_(message.name).set(message.value);\n }\n });\n}\n\nconst crosstalk = {\n group: group,\n var: var_,\n has: has,\n SelectionHandle: SelectionHandle,\n FilterHandle: FilterHandle,\n bind: bind\n};\n\n/**\n * @namespace crosstalk\n */\nexport default crosstalk;\nglobal.crosstalk = crosstalk;\n", + "let $ = global.jQuery;\n\nlet bindings = {};\n\nexport function register(reg) {\n bindings[reg.className] = reg;\n if (global.document && global.document.readyState !== \"complete\") {\n $(() => {\n bind();\n });\n } else if (global.document) {\n setTimeout(bind, 100);\n }\n}\n\nexport function bind() {\n Object.keys(bindings).forEach(function(className) {\n let binding = bindings[className];\n $(\".\" + binding.className).not(\".crosstalk-input-bound\").each(function(i, el) {\n bindInstance(binding, el);\n });\n });\n}\n\n// Escape jQuery identifier\nfunction $escape(val) {\n return val.replace(/([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^`{|}~])/g, \"\\\\$1\");\n}\n\nfunction bindEl(el) {\n let $el = $(el);\n Object.keys(bindings).forEach(function(className) {\n if ($el.hasClass(className) && !$el.hasClass(\"crosstalk-input-bound\")) {\n let binding = bindings[className];\n bindInstance(binding, el);\n }\n });\n}\n\nfunction bindInstance(binding, el) {\n let jsonEl = $(el).find(\"script[type='application/json'][data-for='\" + $escape(el.id) + \"']\");\n let data = JSON.parse(jsonEl[0].innerText);\n\n let instance = binding.factory(el, data);\n $(el).data(\"crosstalk-instance\", instance);\n $(el).addClass(\"crosstalk-input-bound\");\n}\n\nif (global.Shiny) {\n let inputBinding = new global.Shiny.InputBinding();\n let $ = global.jQuery;\n $.extend(inputBinding, {\n find: function(scope) {\n return $(scope).find(\".crosstalk-input\");\n },\n initialize: function(el) {\n if (!$(el).hasClass(\"crosstalk-input-bound\")) {\n bindEl(el);\n }\n },\n getId: function(el) {\n return el.id;\n },\n getValue: function(el) {\n\n },\n setValue: function(el, value) {\n\n },\n receiveMessage: function(el, data) {\n\n },\n subscribe: function(el, callback) {\n $(el).data(\"crosstalk-instance\").resume();\n },\n unsubscribe: function(el) {\n $(el).data(\"crosstalk-instance\").suspend();\n }\n });\n global.Shiny.inputBindings.register(inputBinding, \"crosstalk.inputBinding\");\n}\n", + "import * as input from \"./input\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\n\ninput.register({\n className: \"crosstalk-input-checkboxgroup\",\n\n factory: function(el, data) {\n /*\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n let ctHandle = new FilterHandle(data.group);\n\n let lastKnownKeys;\n let $el = $(el);\n $el.on(\"change\", \"input[type='checkbox']\", function() {\n let checked = $el.find(\"input[type='checkbox']:checked\");\n if (checked.length === 0) {\n lastKnownKeys = null;\n ctHandle.clear();\n } else {\n let keys = {};\n checked.each(function() {\n data.map[this.value].forEach(function(key) {\n keys[key] = true;\n });\n });\n let keyArray = Object.keys(keys);\n keyArray.sort();\n lastKnownKeys = keyArray;\n ctHandle.set(keyArray);\n }\n });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n", + "import * as input from \"./input\";\nimport * as util from \"./util\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\n\ninput.register({\n className: \"crosstalk-input-select\",\n\n factory: function(el, data) {\n /*\n * items: {value: [...], label: [...]}\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n\n let first = [{value: \"\", label: \"(All)\"}];\n let items = util.dataframeToD3(data.items);\n let opts = {\n options: first.concat(items),\n valueField: \"value\",\n labelField: \"label\",\n searchField: \"label\"\n };\n\n let select = $(el).find(\"select\")[0];\n\n let selectize = $(select).selectize(opts)[0].selectize;\n\n let ctHandle = new FilterHandle(data.group);\n\n let lastKnownKeys;\n selectize.on(\"change\", function() {\n if (selectize.items.length === 0) {\n lastKnownKeys = null;\n ctHandle.clear();\n } else {\n let keys = {};\n selectize.items.forEach(function(group) {\n data.map[group].forEach(function(key) {\n keys[key] = true;\n });\n });\n let keyArray = Object.keys(keys);\n keyArray.sort();\n lastKnownKeys = keyArray;\n ctHandle.set(keyArray);\n }\n });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n", + "import * as input from \"./input\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\nlet strftime = global.strftime;\n\ninput.register({\n className: \"crosstalk-input-slider\",\n\n factory: function(el, data) {\n /*\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n let ctHandle = new FilterHandle(data.group);\n\n let opts = {};\n let $el = $(el).find(\"input\");\n let dataType = $el.data(\"data-type\");\n let timeFormat = $el.data(\"time-format\");\n let round = $el.data(\"round\");\n let timeFormatter;\n\n // Set up formatting functions\n if (dataType === \"date\") {\n timeFormatter = strftime.utc();\n opts.prettify = function(num) {\n return timeFormatter(timeFormat, new Date(num));\n };\n\n } else if (dataType === \"datetime\") {\n let timezone = $el.data(\"timezone\");\n if (timezone)\n timeFormatter = strftime.timezone(timezone);\n else\n timeFormatter = strftime;\n\n opts.prettify = function(num) {\n return timeFormatter(timeFormat, new Date(num));\n };\n } else if (dataType === \"number\") {\n if (typeof round !== \"undefined\")\n opts.prettify = function(num) {\n let factor = Math.pow(10, round);\n return Math.round(num * factor) / factor;\n };\n }\n\n $el.ionRangeSlider(opts);\n\n function getValue() {\n let result = $el.data(\"ionRangeSlider\").result;\n\n // Function for converting numeric value from slider to appropriate type.\n let convert;\n let dataType = $el.data(\"data-type\");\n if (dataType === \"date\") {\n convert = function(val) {\n return formatDateUTC(new Date(+val));\n };\n } else if (dataType === \"datetime\") {\n convert = function(val) {\n // Convert ms to s\n return +val / 1000;\n };\n } else {\n convert = function(val) { return +val; };\n }\n\n if ($el.data(\"ionRangeSlider\").options.type === \"double\") {\n return [convert(result.from), convert(result.to)];\n } else {\n return convert(result.from);\n }\n }\n\n let lastKnownKeys = null;\n\n $el.on(\"change.crosstalkSliderInput\", function(event) {\n if (!$el.data(\"updating\") && !$el.data(\"animating\")) {\n let [from, to] = getValue();\n let keys = [];\n for (let i = 0; i < data.values.length; i++) {\n let val = data.values[i];\n if (val >= from && val <= to) {\n keys.push(data.keys[i]);\n }\n }\n keys.sort();\n ctHandle.set(keys);\n lastKnownKeys = keys;\n }\n });\n\n\n // let $el = $(el);\n // $el.on(\"change\", \"input[type=\"checkbox\"]\", function() {\n // let checked = $el.find(\"input[type=\"checkbox\"]:checked\");\n // if (checked.length === 0) {\n // ctHandle.clear();\n // } else {\n // let keys = {};\n // checked.each(function() {\n // data.map[this.value].forEach(function(key) {\n // keys[key] = true;\n // });\n // });\n // let keyArray = Object.keys(keys);\n // keyArray.sort();\n // ctHandle.set(keyArray);\n // }\n // });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n\n\n// Convert a number to a string with leading zeros\nfunction padZeros(n, digits) {\n let str = n.toString();\n while (str.length < digits)\n str = \"0\" + str;\n return str;\n}\n\n// Given a Date object, return a string in yyyy-mm-dd format, using the\n// UTC date. This may be a day off from the date in the local time zone.\nfunction formatDateUTC(date) {\n if (date instanceof Date) {\n return date.getUTCFullYear() + \"-\" +\n padZeros(date.getUTCMonth()+1, 2) + \"-\" +\n padZeros(date.getUTCDate(), 2);\n\n } else {\n return null;\n }\n}\n", + "import Events from \"./events\";\nimport grp from \"./group\";\nimport * as util from \"./util\";\n\n/**\n * Use this class to read and write (and listen for changes to) the selection\n * for a Crosstalk group. This is intended to be used for linked brushing.\n *\n * If two (or more) `SelectionHandle` instances in the same webpage share the\n * same group name, they will share the same state. Setting the selection using\n * one `SelectionHandle` instance will result in the `value` property instantly\n * changing across the others, and `\"change\"` event listeners on all instances\n * (including the one that initiated the sending) will fire.\n *\n * @param {string} [group] - The name of the Crosstalk group, or if none,\n * null or undefined (or any other falsy value). This can be changed later\n * via the [SelectionHandle#setGroup](#setGroup) method.\n * @param {Object} [extraInfo] - An object whose properties will be copied to\n * the event object whenever an event is emitted.\n */\nexport class SelectionHandle {\n\n constructor(group = null, extraInfo = null) {\n this._eventRelay = new Events();\n this._emitter = new util.SubscriptionTracker(this._eventRelay);\n\n // Name of the group we're currently tracking, if any. Can change over time.\n this._group = null;\n // The Var we're currently tracking, if any. Can change over time.\n this._var = null;\n // The event handler subscription we currently have on var.on(\"change\").\n this._varOnChangeSub = null;\n\n this._extraInfo = util.extend({ sender: this }, extraInfo);\n\n this.setGroup(group);\n }\n\n /**\n * Changes the Crosstalk group membership of this SelectionHandle. The group\n * being switched away from (if any) will not have its selection value\n * modified as a result of calling `setGroup`, even if this handle was the\n * most recent handle to set the selection of the group.\n *\n * The group being switched to (if any) will also not have its selection value\n * modified as a result of calling `setGroup`. If you want to set the\n * selection value of the new group, call `set` explicitly.\n *\n * @param {string} group - The name of the Crosstalk group, or null (or\n * undefined) to clear the group.\n */\n setGroup(group) {\n // If group is unchanged, do nothing\n if (this._group === group)\n return;\n // Treat null, undefined, and other falsy values the same\n if (!this._group && !group)\n return;\n\n if (this._var) {\n this._var.off(\"change\", this._varOnChangeSub);\n this._var = null;\n this._varOnChangeSub = null;\n }\n\n this._group = group;\n\n if (group) {\n this._var = grp(group).var(\"selection\");\n let sub = this._var.on(\"change\", (e) => {\n this._eventRelay.trigger(\"change\", e, this);\n });\n this._varOnChangeSub = sub;\n }\n }\n\n /**\n * Retrieves the current selection for the group represented by this\n * `SelectionHandle`.\n *\n * - If no selection is active, then this value will be falsy.\n * - If a selection is active, but no data points are selected, then this\n * value will be an empty array.\n * - If a selection is active, and data points are selected, then the keys\n * of the selected data points will be present in the array.\n */\n get value() {\n return this._var ? this._var.get() : null;\n }\n\n /**\n * Combines the given `extraInfo` (if any) with the handle's default\n * `_extraInfo` (if any).\n * @private\n */\n _mergeExtraInfo(extraInfo) {\n // Important incidental effect: shallow clone is returned\n return util.extend({},\n this._extraInfo ? this._extraInfo : null,\n extraInfo ? extraInfo : null);\n }\n\n /**\n * Overwrites the current selection for the group, and raises the `\"change\"`\n * event among all of the group's '`SelectionHandle` instances (including\n * this one).\n *\n * @fires SelectionHandle#change\n * @param {string[]} selectedKeys - Falsy, empty array, or array of keys (see\n * {@link SelectionHandle#value}).\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `SelectionHandle` constructor).\n */\n set(selectedKeys, extraInfo) {\n if (this._var)\n this._var.set(selectedKeys, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * Overwrites the current selection for the group, and raises the `\"change\"`\n * event among all of the group's '`SelectionHandle` instances (including\n * this one).\n *\n * @fires SelectionHandle#change\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any that were passed\n * into the `SelectionHandle` constructor).\n */\n clear(extraInfo) {\n if (this._var)\n this.set(void 0, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * Subscribes to events on this `SelectionHandle`.\n *\n * @param {string} eventType - Indicates the type of events to listen to.\n * Currently, only `\"change\"` is supported.\n * @param {SelectionHandle~listener} listener - The callback function that\n * will be invoked when the event occurs.\n * @return {string} - A token to pass to {@link SelectionHandle#off} to cancel\n * this subscription.\n */\n on(eventType, listener) {\n return this._emitter.on(eventType, listener);\n }\n\n /**\n * Cancels event subscriptions created by {@link SelectionHandle#on}.\n *\n * @param {string} eventType - The type of event to unsubscribe.\n * @param {string|SelectionHandle~listener} listener - Either the callback\n * function previously passed into {@link SelectionHandle#on}, or the\n * string that was returned from {@link SelectionHandle#on}.\n */\n off(eventType, listener) {\n return this._emitter.off(eventType, listener);\n }\n\n /**\n * Shuts down the `SelectionHandle` object.\n *\n * Removes all event listeners that were added through this handle.\n */\n close() {\n this._emitter.removeAllListeners();\n this.setGroup(null);\n }\n}\n\n/**\n * @callback SelectionHandle~listener\n * @param {Object} event - An object containing details of the event. For\n * `\"change\"` events, this includes the properties `value` (the new\n * value of the selection, or `undefined` if no selection is active),\n * `oldValue` (the previous value of the selection), and `sender` (the\n * `SelectionHandle` instance that made the change).\n */\n\n/**\n * @event SelectionHandle#change\n * @type {object}\n * @property {object} value - The new value of the selection, or `undefined`\n * if no selection is active.\n * @property {object} oldValue - The previous value of the selection.\n * @property {SelectionHandle} sender - The `SelectionHandle` instance that\n * changed the value.\n */\n", + "export function extend(target, ...sources) {\n for (let i = 0; i < sources.length; i++) {\n let src = sources[i];\n if (typeof(src) === \"undefined\" || src === null)\n continue;\n\n for (let key in src) {\n if (src.hasOwnProperty(key)) {\n target[key] = src[key];\n }\n }\n }\n return target;\n}\n\nexport function checkSorted(list) {\n for (let i = 1; i < list.length; i++) {\n if (list[i] <= list[i-1]) {\n throw new Error(\"List is not sorted or contains duplicate\");\n }\n }\n}\n\nexport function diffSortedLists(a, b) {\n let i_a = 0;\n let i_b = 0;\n\n if (!a) a = [];\n if (!b) b = [];\n\n let a_only = [];\n let b_only = [];\n\n checkSorted(a);\n checkSorted(b);\n\n while (i_a < a.length && i_b < b.length) {\n if (a[i_a] === b[i_b]) {\n i_a++;\n i_b++;\n } else if (a[i_a] < b[i_b]) {\n a_only.push(a[i_a++]);\n } else {\n b_only.push(b[i_b++]);\n }\n }\n\n if (i_a < a.length)\n a_only = a_only.concat(a.slice(i_a));\n if (i_b < b.length)\n b_only = b_only.concat(b.slice(i_b));\n return {\n removed: a_only,\n added: b_only\n };\n}\n\n// Convert from wide: { colA: [1,2,3], colB: [4,5,6], ... }\n// to long: [ {colA: 1, colB: 4}, {colA: 2, colB: 5}, ... ]\nexport function dataframeToD3(df) {\n let names = [];\n let length;\n for (let name in df) {\n if (df.hasOwnProperty(name))\n names.push(name);\n if (typeof(df[name]) !== \"object\" || typeof(df[name].length) === \"undefined\") {\n throw new Error(\"All fields must be arrays\");\n } else if (typeof(length) !== \"undefined\" && length !== df[name].length) {\n throw new Error(\"All fields must be arrays of the same length\");\n }\n length = df[name].length;\n }\n let results = [];\n let item;\n for (let row = 0; row < length; row++) {\n item = {};\n for (let col = 0; col < names.length; col++) {\n item[names[col]] = df[names[col]][row];\n }\n results.push(item);\n }\n return results;\n}\n\n/**\n * Keeps track of all event listener additions/removals and lets all active\n * listeners be removed with a single operation.\n *\n * @private\n */\nexport class SubscriptionTracker {\n constructor(emitter) {\n this._emitter = emitter;\n this._subs = {};\n }\n\n on(eventType, listener) {\n let sub = this._emitter.on(eventType, listener);\n this._subs[sub] = eventType;\n return sub;\n }\n\n off(eventType, listener) {\n let sub = this._emitter.off(eventType, listener);\n if (sub) {\n delete this._subs[sub];\n }\n return sub;\n }\n\n removeAllListeners() {\n let current_subs = this._subs;\n this._subs = {};\n Object.keys(current_subs).forEach((sub) => {\n this._emitter.off(current_subs[sub], sub);\n });\n }\n}\n", + "import Events from \"./events\";\n\nexport default class Var {\n constructor(group, name, /*optional*/ value) {\n this._group = group;\n this._name = name;\n this._value = value;\n this._events = new Events();\n }\n\n get() {\n return this._value;\n }\n\n set(value, /*optional*/ event) {\n if (this._value === value) {\n // Do nothing; the value hasn't changed\n return;\n }\n let oldValue = this._value;\n this._value = value;\n // Alert JavaScript listeners that the value has changed\n let evt = {};\n if (event && typeof(event) === \"object\") {\n for (let k in event) {\n if (event.hasOwnProperty(k))\n evt[k] = event[k];\n }\n }\n evt.oldValue = oldValue;\n evt.value = value;\n this._events.trigger(\"change\", evt, this);\n\n // TODO: Make this extensible, to let arbitrary back-ends know that\n // something has changed\n if (global.Shiny && global.Shiny.onInputChange) {\n global.Shiny.onInputChange(\n \".clientValue-\" +\n (this._group.name !== null ? this._group.name + \"-\" : \"\") +\n this._name,\n typeof(value) === \"undefined\" ? null : value\n );\n }\n }\n\n on(eventType, listener) {\n return this._events.on(eventType, listener);\n }\n\n off(eventType, listener) {\n return this._events.off(eventType, listener);\n }\n}\n" + ] +} \ No newline at end of file diff --git a/docs/site_libs/crosstalk-1.2.0/js/crosstalk.min.js b/docs/site_libs/crosstalk-1.2.0/js/crosstalk.min.js new file mode 100644 index 0000000..b7ec0ac --- /dev/null +++ b/docs/site_libs/crosstalk-1.2.0/js/crosstalk.min.js @@ -0,0 +1,2 @@ +!function o(u,a,l){function s(n,e){if(!a[n]){if(!u[n]){var t="function"==typeof require&&require;if(!e&&t)return t(n,!0);if(f)return f(n,!0);var r=new Error("Cannot find module '"+n+"'");throw r.code="MODULE_NOT_FOUND",r}var i=a[n]={exports:{}};u[n][0].call(i.exports,function(e){var t=u[n][1][e];return s(t||e)},i,i.exports,o,u,a,l)}return a[n].exports}for(var f="function"==typeof require&&require,e=0;e?@[\\\]^`{|}~])/g,"\\$1")+"']"),r=JSON.parse(n[0].innerText),i=e.factory(t,r);o(t).data("crosstalk-instance",i),o(t).addClass("crosstalk-input-bound")}if(t.Shiny){var e=new t.Shiny.InputBinding,u=t.jQuery;u.extend(e,{find:function(e){return u(e).find(".crosstalk-input")},initialize:function(e){var t,n;u(e).hasClass("crosstalk-input-bound")||(n=o(t=e),Object.keys(r).forEach(function(e){n.hasClass(e)&&!n.hasClass("crosstalk-input-bound")&&i(r[e],t)}))},getId:function(e){return e.id},getValue:function(e){},setValue:function(e,t){},receiveMessage:function(e,t){},subscribe:function(e,t){u(e).data("crosstalk-instance").resume()},unsubscribe:function(e){u(e).data("crosstalk-instance").suspend()}}),t.Shiny.inputBindings.register(e,"crosstalk.inputBinding")}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],7:[function(r,e,t){(function(e){"use strict";var t=function(e){{if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}}(r("./input")),n=r("./filter");var a=e.jQuery;t.register({className:"crosstalk-input-checkboxgroup",factory:function(e,r){var i=new n.FilterHandle(r.group),o=void 0,u=a(e);return u.on("change","input[type='checkbox']",function(){var e=u.find("input[type='checkbox']:checked");if(0===e.length)o=null,i.clear();else{var t={};e.each(function(){r.map[this.value].forEach(function(e){t[e]=!0})});var n=Object.keys(t);n.sort(),o=n,i.set(n)}}),{suspend:function(){i.clear()},resume:function(){o&&i.set(o)}}}})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./filter":2,"./input":6}],8:[function(r,e,t){(function(e){"use strict";var t=n(r("./input")),l=n(r("./util")),s=r("./filter");function n(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}var f=e.jQuery;t.register({className:"crosstalk-input-select",factory:function(e,n){var t=l.dataframeToD3(n.items),r={options:[{value:"",label:"(All)"}].concat(t),valueField:"value",labelField:"label",searchField:"label"},i=f(e).find("select")[0],o=f(i).selectize(r)[0].selectize,u=new s.FilterHandle(n.group),a=void 0;return o.on("change",function(){if(0===o.items.length)a=null,u.clear();else{var t={};o.items.forEach(function(e){n.map[e].forEach(function(e){t[e]=!0})});var e=Object.keys(t);e.sort(),a=e,u.set(e)}}),{suspend:function(){u.clear()},resume:function(){a&&u.set(a)}}}})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./filter":2,"./input":6,"./util":11}],9:[function(n,e,t){(function(e){"use strict";var d=function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,i=!1,o=void 0;try{for(var u,a=e[Symbol.iterator]();!(r=(u=a.next()).done)&&(n.push(u.value),!t||n.length!==t);r=!0);}catch(e){i=!0,o=e}finally{try{!r&&a.return&&a.return()}finally{if(i)throw o}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")},t=function(e){{if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}}(n("./input")),a=n("./filter");var v=e.jQuery,p=e.strftime;function y(e,t){for(var n=e.toString();n.length {\n this._eventRelay.trigger(\"change\", e, this);\n });\n this._varOnChangeSub = sub;\n }\n }\n\n /**\n * Combine the given `extraInfo` (if any) with the handle's default\n * `_extraInfo` (if any).\n * @private\n */\n _mergeExtraInfo(extraInfo) {\n return util.extend({},\n this._extraInfo ? this._extraInfo : null,\n extraInfo ? extraInfo : null);\n }\n\n /**\n * Close the handle. This clears this handle's contribution to the filter set,\n * and unsubscribes all event listeners.\n */\n close() {\n this._emitter.removeAllListeners();\n this.clear();\n this.setGroup(null);\n }\n\n /**\n * Clear this handle's contribution to the filter set.\n *\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `FilterHandle` constructor).\n * \n * @fires FilterHandle#change\n */\n clear(extraInfo) {\n if (!this._filterSet)\n return;\n this._filterSet.clear(this._id);\n this._onChange(extraInfo);\n }\n\n /**\n * Set this handle's contribution to the filter set. This array should consist\n * of the keys of the rows that _should_ be displayed; any keys that are not\n * present in the array will be considered _filtered out_. Note that multiple\n * `FilterHandle` instances in the group may each contribute an array of keys,\n * and only those keys that appear in _all_ of the arrays make it through the\n * filter.\n *\n * @param {string[]} keys - Empty array, or array of keys. To clear the\n * filter, don't pass an empty array; instead, use the\n * {@link FilterHandle#clear} method.\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `FilterHandle` constructor).\n * \n * @fires FilterHandle#change\n */\n set(keys, extraInfo) {\n if (!this._filterSet)\n return;\n this._filterSet.update(this._id, keys);\n this._onChange(extraInfo);\n }\n\n /**\n * @return {string[]|null} - Either: 1) an array of keys that made it through\n * all of the `FilterHandle` instances, or, 2) `null`, which means no filter\n * is being applied (all data should be displayed).\n */\n get filteredKeys() {\n return this._filterSet ? this._filterSet.value : null;\n }\n\n /**\n * Subscribe to events on this `FilterHandle`.\n *\n * @param {string} eventType - Indicates the type of events to listen to.\n * Currently, only `\"change\"` is supported.\n * @param {FilterHandle~listener} listener - The callback function that\n * will be invoked when the event occurs.\n * @return {string} - A token to pass to {@link FilterHandle#off} to cancel\n * this subscription.\n */\n on(eventType, listener) {\n return this._emitter.on(eventType, listener);\n }\n\n /**\n * Cancel event subscriptions created by {@link FilterHandle#on}.\n *\n * @param {string} eventType - The type of event to unsubscribe.\n * @param {string|FilterHandle~listener} listener - Either the callback\n * function previously passed into {@link FilterHandle#on}, or the\n * string that was returned from {@link FilterHandle#on}.\n */\n off(eventType, listener) {\n return this._emitter.off(eventType, listener);\n }\n\n _onChange(extraInfo) {\n if (!this._filterSet)\n return;\n this._filterVar.set(this._filterSet.value, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * @callback FilterHandle~listener\n * @param {Object} event - An object containing details of the event. For\n * `\"change\"` events, this includes the properties `value` (the new\n * value of the filter set, or `null` if no filter set is active),\n * `oldValue` (the previous value of the filter set), and `sender` (the\n * `FilterHandle` instance that made the change).\n */\n\n}\n\n/**\n * @event FilterHandle#change\n * @type {object}\n * @property {object} value - The new value of the filter set, or `null`\n * if no filter set is active.\n * @property {object} oldValue - The previous value of the filter set.\n * @property {FilterHandle} sender - The `FilterHandle` instance that\n * changed the value.\n */\n","import { diffSortedLists } from \"./util\";\n\nfunction naturalComparator(a, b) {\n if (a === b) {\n return 0;\n } else if (a < b) {\n return -1;\n } else if (a > b) {\n return 1;\n }\n}\n\n/**\n * @private\n */\nexport default class FilterSet {\n constructor() {\n this.reset();\n }\n\n reset() {\n // Key: handle ID, Value: array of selected keys, or null\n this._handles = {};\n // Key: key string, Value: count of handles that include it\n this._keys = {};\n this._value = null;\n this._activeHandles = 0;\n }\n\n get value() {\n return this._value;\n }\n\n update(handleId, keys) {\n if (keys !== null) {\n keys = keys.slice(0); // clone before sorting\n keys.sort(naturalComparator);\n }\n\n let {added, removed} = diffSortedLists(this._handles[handleId], keys);\n this._handles[handleId] = keys;\n\n for (let i = 0; i < added.length; i++) {\n this._keys[added[i]] = (this._keys[added[i]] || 0) + 1;\n }\n for (let i = 0; i < removed.length; i++) {\n this._keys[removed[i]]--;\n }\n\n this._updateValue(keys);\n }\n\n /**\n * @param {string[]} keys Sorted array of strings that indicate\n * a superset of possible keys.\n * @private\n */\n _updateValue(keys = this._allKeys) {\n let handleCount = Object.keys(this._handles).length;\n if (handleCount === 0) {\n this._value = null;\n } else {\n this._value = [];\n for (let i = 0; i < keys.length; i++) {\n let count = this._keys[keys[i]];\n if (count === handleCount) {\n this._value.push(keys[i]);\n }\n }\n }\n }\n\n clear(handleId) {\n if (typeof(this._handles[handleId]) === \"undefined\") {\n return;\n }\n\n let keys = this._handles[handleId];\n if (!keys) {\n keys = [];\n }\n\n for (let i = 0; i < keys.length; i++) {\n this._keys[keys[i]]--;\n }\n delete this._handles[handleId];\n\n this._updateValue();\n }\n\n get _allKeys() {\n let allKeys = Object.keys(this._keys);\n allKeys.sort(naturalComparator);\n return allKeys;\n }\n}\n","import Var from \"./var\";\n\n// Use a global so that multiple copies of crosstalk.js can be loaded and still\n// have groups behave as singletons across all copies.\nglobal.__crosstalk_groups = global.__crosstalk_groups || {};\nlet groups = global.__crosstalk_groups;\n\nexport default function group(groupName) {\n if (groupName && typeof(groupName) === \"string\") {\n if (!groups.hasOwnProperty(groupName)) {\n groups[groupName] = new Group(groupName);\n }\n return groups[groupName];\n } else if (typeof(groupName) === \"object\" && groupName._vars && groupName.var) {\n // Appears to already be a group object\n return groupName;\n } else if (Array.isArray(groupName) &&\n groupName.length == 1 &&\n typeof(groupName[0]) === \"string\") {\n return group(groupName[0]);\n } else {\n throw new Error(\"Invalid groupName argument\");\n }\n}\n\nclass Group {\n constructor(name) {\n this.name = name;\n this._vars = {};\n }\n\n var(name) {\n if (!name || typeof(name) !== \"string\") {\n throw new Error(\"Invalid var name\");\n }\n\n if (!this._vars.hasOwnProperty(name))\n this._vars[name] = new Var(this, name);\n return this._vars[name];\n }\n\n has(name) {\n if (!name || typeof(name) !== \"string\") {\n throw new Error(\"Invalid var name\");\n }\n\n return this._vars.hasOwnProperty(name);\n }\n}\n","import group from \"./group\";\nimport { SelectionHandle } from \"./selection\";\nimport { FilterHandle } from \"./filter\";\nimport { bind } from \"./input\";\nimport \"./input_selectize\";\nimport \"./input_checkboxgroup\";\nimport \"./input_slider\";\n\nconst defaultGroup = group(\"default\");\n\nfunction var_(name) {\n return defaultGroup.var(name);\n}\n\nfunction has(name) {\n return defaultGroup.has(name);\n}\n\nif (global.Shiny) {\n global.Shiny.addCustomMessageHandler(\"update-client-value\", function(message) {\n if (typeof(message.group) === \"string\") {\n group(message.group).var(message.name).set(message.value);\n } else {\n var_(message.name).set(message.value);\n }\n });\n}\n\nconst crosstalk = {\n group: group,\n var: var_,\n has: has,\n SelectionHandle: SelectionHandle,\n FilterHandle: FilterHandle,\n bind: bind\n};\n\n/**\n * @namespace crosstalk\n */\nexport default crosstalk;\nglobal.crosstalk = crosstalk;\n","let $ = global.jQuery;\n\nlet bindings = {};\n\nexport function register(reg) {\n bindings[reg.className] = reg;\n if (global.document && global.document.readyState !== \"complete\") {\n $(() => {\n bind();\n });\n } else if (global.document) {\n setTimeout(bind, 100);\n }\n}\n\nexport function bind() {\n Object.keys(bindings).forEach(function(className) {\n let binding = bindings[className];\n $(\".\" + binding.className).not(\".crosstalk-input-bound\").each(function(i, el) {\n bindInstance(binding, el);\n });\n });\n}\n\n// Escape jQuery identifier\nfunction $escape(val) {\n return val.replace(/([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^`{|}~])/g, \"\\\\$1\");\n}\n\nfunction bindEl(el) {\n let $el = $(el);\n Object.keys(bindings).forEach(function(className) {\n if ($el.hasClass(className) && !$el.hasClass(\"crosstalk-input-bound\")) {\n let binding = bindings[className];\n bindInstance(binding, el);\n }\n });\n}\n\nfunction bindInstance(binding, el) {\n let jsonEl = $(el).find(\"script[type='application/json'][data-for='\" + $escape(el.id) + \"']\");\n let data = JSON.parse(jsonEl[0].innerText);\n\n let instance = binding.factory(el, data);\n $(el).data(\"crosstalk-instance\", instance);\n $(el).addClass(\"crosstalk-input-bound\");\n}\n\nif (global.Shiny) {\n let inputBinding = new global.Shiny.InputBinding();\n let $ = global.jQuery;\n $.extend(inputBinding, {\n find: function(scope) {\n return $(scope).find(\".crosstalk-input\");\n },\n initialize: function(el) {\n if (!$(el).hasClass(\"crosstalk-input-bound\")) {\n bindEl(el);\n }\n },\n getId: function(el) {\n return el.id;\n },\n getValue: function(el) {\n\n },\n setValue: function(el, value) {\n\n },\n receiveMessage: function(el, data) {\n\n },\n subscribe: function(el, callback) {\n $(el).data(\"crosstalk-instance\").resume();\n },\n unsubscribe: function(el) {\n $(el).data(\"crosstalk-instance\").suspend();\n }\n });\n global.Shiny.inputBindings.register(inputBinding, \"crosstalk.inputBinding\");\n}\n","import * as input from \"./input\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\n\ninput.register({\n className: \"crosstalk-input-checkboxgroup\",\n\n factory: function(el, data) {\n /*\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n let ctHandle = new FilterHandle(data.group);\n\n let lastKnownKeys;\n let $el = $(el);\n $el.on(\"change\", \"input[type='checkbox']\", function() {\n let checked = $el.find(\"input[type='checkbox']:checked\");\n if (checked.length === 0) {\n lastKnownKeys = null;\n ctHandle.clear();\n } else {\n let keys = {};\n checked.each(function() {\n data.map[this.value].forEach(function(key) {\n keys[key] = true;\n });\n });\n let keyArray = Object.keys(keys);\n keyArray.sort();\n lastKnownKeys = keyArray;\n ctHandle.set(keyArray);\n }\n });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n","import * as input from \"./input\";\nimport * as util from \"./util\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\n\ninput.register({\n className: \"crosstalk-input-select\",\n\n factory: function(el, data) {\n /*\n * items: {value: [...], label: [...]}\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n\n let first = [{value: \"\", label: \"(All)\"}];\n let items = util.dataframeToD3(data.items);\n let opts = {\n options: first.concat(items),\n valueField: \"value\",\n labelField: \"label\",\n searchField: \"label\"\n };\n\n let select = $(el).find(\"select\")[0];\n\n let selectize = $(select).selectize(opts)[0].selectize;\n\n let ctHandle = new FilterHandle(data.group);\n\n let lastKnownKeys;\n selectize.on(\"change\", function() {\n if (selectize.items.length === 0) {\n lastKnownKeys = null;\n ctHandle.clear();\n } else {\n let keys = {};\n selectize.items.forEach(function(group) {\n data.map[group].forEach(function(key) {\n keys[key] = true;\n });\n });\n let keyArray = Object.keys(keys);\n keyArray.sort();\n lastKnownKeys = keyArray;\n ctHandle.set(keyArray);\n }\n });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n","import * as input from \"./input\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\nlet strftime = global.strftime;\n\ninput.register({\n className: \"crosstalk-input-slider\",\n\n factory: function(el, data) {\n /*\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n let ctHandle = new FilterHandle(data.group);\n\n let opts = {};\n let $el = $(el).find(\"input\");\n let dataType = $el.data(\"data-type\");\n let timeFormat = $el.data(\"time-format\");\n let round = $el.data(\"round\");\n let timeFormatter;\n\n // Set up formatting functions\n if (dataType === \"date\") {\n timeFormatter = strftime.utc();\n opts.prettify = function(num) {\n return timeFormatter(timeFormat, new Date(num));\n };\n\n } else if (dataType === \"datetime\") {\n let timezone = $el.data(\"timezone\");\n if (timezone)\n timeFormatter = strftime.timezone(timezone);\n else\n timeFormatter = strftime;\n\n opts.prettify = function(num) {\n return timeFormatter(timeFormat, new Date(num));\n };\n } else if (dataType === \"number\") {\n if (typeof round !== \"undefined\")\n opts.prettify = function(num) {\n let factor = Math.pow(10, round);\n return Math.round(num * factor) / factor;\n };\n }\n\n $el.ionRangeSlider(opts);\n\n function getValue() {\n let result = $el.data(\"ionRangeSlider\").result;\n\n // Function for converting numeric value from slider to appropriate type.\n let convert;\n let dataType = $el.data(\"data-type\");\n if (dataType === \"date\") {\n convert = function(val) {\n return formatDateUTC(new Date(+val));\n };\n } else if (dataType === \"datetime\") {\n convert = function(val) {\n // Convert ms to s\n return +val / 1000;\n };\n } else {\n convert = function(val) { return +val; };\n }\n\n if ($el.data(\"ionRangeSlider\").options.type === \"double\") {\n return [convert(result.from), convert(result.to)];\n } else {\n return convert(result.from);\n }\n }\n\n let lastKnownKeys = null;\n\n $el.on(\"change.crosstalkSliderInput\", function(event) {\n if (!$el.data(\"updating\") && !$el.data(\"animating\")) {\n let [from, to] = getValue();\n let keys = [];\n for (let i = 0; i < data.values.length; i++) {\n let val = data.values[i];\n if (val >= from && val <= to) {\n keys.push(data.keys[i]);\n }\n }\n keys.sort();\n ctHandle.set(keys);\n lastKnownKeys = keys;\n }\n });\n\n\n // let $el = $(el);\n // $el.on(\"change\", \"input[type=\"checkbox\"]\", function() {\n // let checked = $el.find(\"input[type=\"checkbox\"]:checked\");\n // if (checked.length === 0) {\n // ctHandle.clear();\n // } else {\n // let keys = {};\n // checked.each(function() {\n // data.map[this.value].forEach(function(key) {\n // keys[key] = true;\n // });\n // });\n // let keyArray = Object.keys(keys);\n // keyArray.sort();\n // ctHandle.set(keyArray);\n // }\n // });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n\n\n// Convert a number to a string with leading zeros\nfunction padZeros(n, digits) {\n let str = n.toString();\n while (str.length < digits)\n str = \"0\" + str;\n return str;\n}\n\n// Given a Date object, return a string in yyyy-mm-dd format, using the\n// UTC date. This may be a day off from the date in the local time zone.\nfunction formatDateUTC(date) {\n if (date instanceof Date) {\n return date.getUTCFullYear() + \"-\" +\n padZeros(date.getUTCMonth()+1, 2) + \"-\" +\n padZeros(date.getUTCDate(), 2);\n\n } else {\n return null;\n }\n}\n","import Events from \"./events\";\nimport grp from \"./group\";\nimport * as util from \"./util\";\n\n/**\n * Use this class to read and write (and listen for changes to) the selection\n * for a Crosstalk group. This is intended to be used for linked brushing.\n *\n * If two (or more) `SelectionHandle` instances in the same webpage share the\n * same group name, they will share the same state. Setting the selection using\n * one `SelectionHandle` instance will result in the `value` property instantly\n * changing across the others, and `\"change\"` event listeners on all instances\n * (including the one that initiated the sending) will fire.\n *\n * @param {string} [group] - The name of the Crosstalk group, or if none,\n * null or undefined (or any other falsy value). This can be changed later\n * via the [SelectionHandle#setGroup](#setGroup) method.\n * @param {Object} [extraInfo] - An object whose properties will be copied to\n * the event object whenever an event is emitted.\n */\nexport class SelectionHandle {\n\n constructor(group = null, extraInfo = null) {\n this._eventRelay = new Events();\n this._emitter = new util.SubscriptionTracker(this._eventRelay);\n\n // Name of the group we're currently tracking, if any. Can change over time.\n this._group = null;\n // The Var we're currently tracking, if any. Can change over time.\n this._var = null;\n // The event handler subscription we currently have on var.on(\"change\").\n this._varOnChangeSub = null;\n\n this._extraInfo = util.extend({ sender: this }, extraInfo);\n\n this.setGroup(group);\n }\n\n /**\n * Changes the Crosstalk group membership of this SelectionHandle. The group\n * being switched away from (if any) will not have its selection value\n * modified as a result of calling `setGroup`, even if this handle was the\n * most recent handle to set the selection of the group.\n *\n * The group being switched to (if any) will also not have its selection value\n * modified as a result of calling `setGroup`. If you want to set the\n * selection value of the new group, call `set` explicitly.\n *\n * @param {string} group - The name of the Crosstalk group, or null (or\n * undefined) to clear the group.\n */\n setGroup(group) {\n // If group is unchanged, do nothing\n if (this._group === group)\n return;\n // Treat null, undefined, and other falsy values the same\n if (!this._group && !group)\n return;\n\n if (this._var) {\n this._var.off(\"change\", this._varOnChangeSub);\n this._var = null;\n this._varOnChangeSub = null;\n }\n\n this._group = group;\n\n if (group) {\n this._var = grp(group).var(\"selection\");\n let sub = this._var.on(\"change\", (e) => {\n this._eventRelay.trigger(\"change\", e, this);\n });\n this._varOnChangeSub = sub;\n }\n }\n\n /**\n * Retrieves the current selection for the group represented by this\n * `SelectionHandle`.\n *\n * - If no selection is active, then this value will be falsy.\n * - If a selection is active, but no data points are selected, then this\n * value will be an empty array.\n * - If a selection is active, and data points are selected, then the keys\n * of the selected data points will be present in the array.\n */\n get value() {\n return this._var ? this._var.get() : null;\n }\n\n /**\n * Combines the given `extraInfo` (if any) with the handle's default\n * `_extraInfo` (if any).\n * @private\n */\n _mergeExtraInfo(extraInfo) {\n // Important incidental effect: shallow clone is returned\n return util.extend({},\n this._extraInfo ? this._extraInfo : null,\n extraInfo ? extraInfo : null);\n }\n\n /**\n * Overwrites the current selection for the group, and raises the `\"change\"`\n * event among all of the group's '`SelectionHandle` instances (including\n * this one).\n *\n * @fires SelectionHandle#change\n * @param {string[]} selectedKeys - Falsy, empty array, or array of keys (see\n * {@link SelectionHandle#value}).\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `SelectionHandle` constructor).\n */\n set(selectedKeys, extraInfo) {\n if (this._var)\n this._var.set(selectedKeys, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * Overwrites the current selection for the group, and raises the `\"change\"`\n * event among all of the group's '`SelectionHandle` instances (including\n * this one).\n *\n * @fires SelectionHandle#change\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any that were passed\n * into the `SelectionHandle` constructor).\n */\n clear(extraInfo) {\n if (this._var)\n this.set(void 0, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * Subscribes to events on this `SelectionHandle`.\n *\n * @param {string} eventType - Indicates the type of events to listen to.\n * Currently, only `\"change\"` is supported.\n * @param {SelectionHandle~listener} listener - The callback function that\n * will be invoked when the event occurs.\n * @return {string} - A token to pass to {@link SelectionHandle#off} to cancel\n * this subscription.\n */\n on(eventType, listener) {\n return this._emitter.on(eventType, listener);\n }\n\n /**\n * Cancels event subscriptions created by {@link SelectionHandle#on}.\n *\n * @param {string} eventType - The type of event to unsubscribe.\n * @param {string|SelectionHandle~listener} listener - Either the callback\n * function previously passed into {@link SelectionHandle#on}, or the\n * string that was returned from {@link SelectionHandle#on}.\n */\n off(eventType, listener) {\n return this._emitter.off(eventType, listener);\n }\n\n /**\n * Shuts down the `SelectionHandle` object.\n *\n * Removes all event listeners that were added through this handle.\n */\n close() {\n this._emitter.removeAllListeners();\n this.setGroup(null);\n }\n}\n\n/**\n * @callback SelectionHandle~listener\n * @param {Object} event - An object containing details of the event. For\n * `\"change\"` events, this includes the properties `value` (the new\n * value of the selection, or `undefined` if no selection is active),\n * `oldValue` (the previous value of the selection), and `sender` (the\n * `SelectionHandle` instance that made the change).\n */\n\n/**\n * @event SelectionHandle#change\n * @type {object}\n * @property {object} value - The new value of the selection, or `undefined`\n * if no selection is active.\n * @property {object} oldValue - The previous value of the selection.\n * @property {SelectionHandle} sender - The `SelectionHandle` instance that\n * changed the value.\n */\n","export function extend(target, ...sources) {\n for (let i = 0; i < sources.length; i++) {\n let src = sources[i];\n if (typeof(src) === \"undefined\" || src === null)\n continue;\n\n for (let key in src) {\n if (src.hasOwnProperty(key)) {\n target[key] = src[key];\n }\n }\n }\n return target;\n}\n\nexport function checkSorted(list) {\n for (let i = 1; i < list.length; i++) {\n if (list[i] <= list[i-1]) {\n throw new Error(\"List is not sorted or contains duplicate\");\n }\n }\n}\n\nexport function diffSortedLists(a, b) {\n let i_a = 0;\n let i_b = 0;\n\n if (!a) a = [];\n if (!b) b = [];\n\n let a_only = [];\n let b_only = [];\n\n checkSorted(a);\n checkSorted(b);\n\n while (i_a < a.length && i_b < b.length) {\n if (a[i_a] === b[i_b]) {\n i_a++;\n i_b++;\n } else if (a[i_a] < b[i_b]) {\n a_only.push(a[i_a++]);\n } else {\n b_only.push(b[i_b++]);\n }\n }\n\n if (i_a < a.length)\n a_only = a_only.concat(a.slice(i_a));\n if (i_b < b.length)\n b_only = b_only.concat(b.slice(i_b));\n return {\n removed: a_only,\n added: b_only\n };\n}\n\n// Convert from wide: { colA: [1,2,3], colB: [4,5,6], ... }\n// to long: [ {colA: 1, colB: 4}, {colA: 2, colB: 5}, ... ]\nexport function dataframeToD3(df) {\n let names = [];\n let length;\n for (let name in df) {\n if (df.hasOwnProperty(name))\n names.push(name);\n if (typeof(df[name]) !== \"object\" || typeof(df[name].length) === \"undefined\") {\n throw new Error(\"All fields must be arrays\");\n } else if (typeof(length) !== \"undefined\" && length !== df[name].length) {\n throw new Error(\"All fields must be arrays of the same length\");\n }\n length = df[name].length;\n }\n let results = [];\n let item;\n for (let row = 0; row < length; row++) {\n item = {};\n for (let col = 0; col < names.length; col++) {\n item[names[col]] = df[names[col]][row];\n }\n results.push(item);\n }\n return results;\n}\n\n/**\n * Keeps track of all event listener additions/removals and lets all active\n * listeners be removed with a single operation.\n *\n * @private\n */\nexport class SubscriptionTracker {\n constructor(emitter) {\n this._emitter = emitter;\n this._subs = {};\n }\n\n on(eventType, listener) {\n let sub = this._emitter.on(eventType, listener);\n this._subs[sub] = eventType;\n return sub;\n }\n\n off(eventType, listener) {\n let sub = this._emitter.off(eventType, listener);\n if (sub) {\n delete this._subs[sub];\n }\n return sub;\n }\n\n removeAllListeners() {\n let current_subs = this._subs;\n this._subs = {};\n Object.keys(current_subs).forEach((sub) => {\n this._emitter.off(current_subs[sub], sub);\n });\n }\n}\n","import Events from \"./events\";\n\nexport default class Var {\n constructor(group, name, /*optional*/ value) {\n this._group = group;\n this._name = name;\n this._value = value;\n this._events = new Events();\n }\n\n get() {\n return this._value;\n }\n\n set(value, /*optional*/ event) {\n if (this._value === value) {\n // Do nothing; the value hasn't changed\n return;\n }\n let oldValue = this._value;\n this._value = value;\n // Alert JavaScript listeners that the value has changed\n let evt = {};\n if (event && typeof(event) === \"object\") {\n for (let k in event) {\n if (event.hasOwnProperty(k))\n evt[k] = event[k];\n }\n }\n evt.oldValue = oldValue;\n evt.value = value;\n this._events.trigger(\"change\", evt, this);\n\n // TODO: Make this extensible, to let arbitrary back-ends know that\n // something has changed\n if (global.Shiny && global.Shiny.onInputChange) {\n global.Shiny.onInputChange(\n \".clientValue-\" +\n (this._group.name !== null ? this._group.name + \"-\" : \"\") +\n this._name,\n typeof(value) === \"undefined\" ? null : value\n );\n }\n }\n\n on(eventType, listener) {\n return this._events.on(eventType, listener);\n }\n\n off(eventType, listener) {\n return this._events.off(eventType, listener);\n }\n}\n"]} \ No newline at end of file diff --git a/docs/site_libs/crosstalk-1.2.0/scss/crosstalk.scss b/docs/site_libs/crosstalk-1.2.0/scss/crosstalk.scss new file mode 100644 index 0000000..3566561 --- /dev/null +++ b/docs/site_libs/crosstalk-1.2.0/scss/crosstalk.scss @@ -0,0 +1,75 @@ +/* Adjust margins outwards, so column contents line up with the edges of the + parent of container-fluid. */ +.container-fluid.crosstalk-bscols { + margin-left: -30px; + margin-right: -30px; + white-space: normal; +} + +/* But don't adjust the margins outwards if we're directly under the body, + i.e. we were the top-level of something at the console. */ +body > .container-fluid.crosstalk-bscols { + margin-left: auto; + margin-right: auto; +} + +.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { + display: inline-block; + padding-right: 12px; + vertical-align: top; +} + +@media only screen and (max-width:480px) { + .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { + display: block; + padding-right: inherit; + } +} + +/* Relevant BS3 styles to make filter_checkbox() look reasonable without Bootstrap */ +.crosstalk-input { + margin-bottom: 15px; /* a la .form-group */ + .control-label { + margin-bottom: 0; + vertical-align: middle; + } + input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px; + line-height: normal; + } + .checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; + } + .checkbox > label{ + padding-left: 20px; + margin-bottom: 0; + font-weight: 400; + cursor: pointer; + } + .checkbox input[type="checkbox"], + .checkbox-inline input[type="checkbox"] { + position: absolute; + margin-top: 2px; + margin-left: -20px; + } + .checkbox + .checkbox { + margin-top: -5px; + } + .checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: 400; + vertical-align: middle; + cursor: pointer; + } + .checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; + } +} diff --git a/docs/site_libs/d3-3.5.3/CONTRIBUTING.md b/docs/site_libs/d3-3.5.3/CONTRIBUTING.md new file mode 100644 index 0000000..76126d5 --- /dev/null +++ b/docs/site_libs/d3-3.5.3/CONTRIBUTING.md @@ -0,0 +1,25 @@ +# Contributing + +If you’re looking for ways to contribute, please [peruse open issues](https://github.com/mbostock/d3/issues?milestone=&page=1&state=open). The icebox is a good place to find ideas that are not currently in development. If you already have an idea, please check past issues to see whether your idea or a similar one was previously discussed. + +Before submitting a pull request, consider implementing a live example first, say using [bl.ocks.org](http://bl.ocks.org). Real-world use cases go a long way to demonstrating the usefulness of a proposed feature. The more complex a feature’s implementation, the more usefulness it should provide. Share your demo using the #d3js tag on Twitter or by sending it to the d3-js Google group. + +If your proposed feature does not involve changing core functionality, consider submitting it instead as a [D3 plugin](https://github.com/d3/d3-plugins). New core features should be for general use, whereas plugins are suitable for more specialized use cases. When in doubt, it’s easier to start with a plugin before “graduating” to core. + +To contribute new documentation or add examples to the gallery, just [edit the Wiki](https://github.com/mbostock/d3/wiki)! + +## How to Submit a Pull Request + +1. Click the “Fork” button to create your personal fork of the D3 repository. + +2. After cloning your fork of the D3 repository in the terminal, run `npm install` to install D3’s dependencies. + +3. Create a new branch for your new feature. For example: `git checkout -b my-awesome-feature`. A dedicated branch for your pull request means you can develop multiple features at the same time, and ensures that your pull request is stable even if you later decide to develop an unrelated feature. + +4. The `d3.js` and `d3.min.js` files are built from source files in the `src` directory. _Do not edit `d3.js` directly._ Instead, edit the source files, and then run `make` to build the generated files. + +5. Use `make test` to run tests and verify your changes. If you are adding a new feature, you should add new tests! If you are changing existing functionality, make sure the existing tests run, or update them as appropriate. + +6. Sign D3’s [Individual Contributor License Agreement](https://docs.google.com/forms/d/1CzjdBKtDuA8WeuFJinadx956xLQ4Xriv7-oDvXnZMaI/viewform). Unless you are submitting a trivial patch (such as fixing a typo), this form is needed to verify that you are able to contribute. + +7. Submit your pull request, and good luck! diff --git a/docs/site_libs/d3-3.5.3/LICENSE b/docs/site_libs/d3-3.5.3/LICENSE new file mode 100644 index 0000000..8301346 --- /dev/null +++ b/docs/site_libs/d3-3.5.3/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2010-2014, Michael Bostock +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* The name Michael Bostock may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/docs/site_libs/d3-3.5.3/bower.json b/docs/site_libs/d3-3.5.3/bower.json new file mode 100644 index 0000000..f07197e --- /dev/null +++ b/docs/site_libs/d3-3.5.3/bower.json @@ -0,0 +1,26 @@ +{ + "name": "d3", + "version": "3.5.3", + "main": "d3.js", + "scripts": [ + "d3.js" + ], + "ignore": [ + ".DS_Store", + ".git", + ".gitignore", + ".npmignore", + ".spmignore", + ".travis.yml", + "Makefile", + "bin", + "component.json", + "composer.json", + "index.js", + "lib", + "node_modules", + "package.json", + "src", + "test" + ] +} diff --git a/docs/site_libs/d3-3.5.3/d3.js b/docs/site_libs/d3-3.5.3/d3.js new file mode 100644 index 0000000..e4d8664 --- /dev/null +++ b/docs/site_libs/d3-3.5.3/d3.js @@ -0,0 +1,9503 @@ +!function() { + var d3 = { + version: "3.5.6" + }; + var d3_arraySlice = [].slice, d3_array = function(list) { + return d3_arraySlice.call(list); + }; + var d3_document = this.document; + function d3_documentElement(node) { + return node && (node.ownerDocument || node.document || node).documentElement; + } + function d3_window(node) { + return node && (node.ownerDocument && node.ownerDocument.defaultView || node.document && node || node.defaultView); + } + if (d3_document) { + try { + d3_array(d3_document.documentElement.childNodes)[0].nodeType; + } catch (e) { + d3_array = function(list) { + var i = list.length, array = new Array(i); + while (i--) array[i] = list[i]; + return array; + }; + } + } + if (!Date.now) Date.now = function() { + return +new Date(); + }; + if (d3_document) { + try { + d3_document.createElement("DIV").style.setProperty("opacity", 0, ""); + } catch (error) { + var d3_element_prototype = this.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = this.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty; + d3_element_prototype.setAttribute = function(name, value) { + d3_element_setAttribute.call(this, name, value + ""); + }; + d3_element_prototype.setAttributeNS = function(space, local, value) { + d3_element_setAttributeNS.call(this, space, local, value + ""); + }; + d3_style_prototype.setProperty = function(name, value, priority) { + d3_style_setProperty.call(this, name, value + "", priority); + }; + } + } + d3.ascending = d3_ascending; + function d3_ascending(a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; + } + d3.descending = function(a, b) { + return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; + }; + d3.min = function(array, f) { + var i = -1, n = array.length, a, b; + if (arguments.length === 1) { + while (++i < n) if ((b = array[i]) != null && b >= b) { + a = b; + break; + } + while (++i < n) if ((b = array[i]) != null && a > b) a = b; + } else { + while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { + a = b; + break; + } + while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; + } + return a; + }; + d3.max = function(array, f) { + var i = -1, n = array.length, a, b; + if (arguments.length === 1) { + while (++i < n) if ((b = array[i]) != null && b >= b) { + a = b; + break; + } + while (++i < n) if ((b = array[i]) != null && b > a) a = b; + } else { + while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { + a = b; + break; + } + while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; + } + return a; + }; + d3.extent = function(array, f) { + var i = -1, n = array.length, a, b, c; + if (arguments.length === 1) { + while (++i < n) if ((b = array[i]) != null && b >= b) { + a = c = b; + break; + } + while (++i < n) if ((b = array[i]) != null) { + if (a > b) a = b; + if (c < b) c = b; + } + } else { + while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { + a = c = b; + break; + } + while (++i < n) if ((b = f.call(array, array[i], i)) != null) { + if (a > b) a = b; + if (c < b) c = b; + } + } + return [ a, c ]; + }; + function d3_number(x) { + return x === null ? NaN : +x; + } + function d3_numeric(x) { + return !isNaN(x); + } + d3.sum = function(array, f) { + var s = 0, n = array.length, a, i = -1; + if (arguments.length === 1) { + while (++i < n) if (d3_numeric(a = +array[i])) s += a; + } else { + while (++i < n) if (d3_numeric(a = +f.call(array, array[i], i))) s += a; + } + return s; + }; + d3.mean = function(array, f) { + var s = 0, n = array.length, a, i = -1, j = n; + if (arguments.length === 1) { + while (++i < n) if (d3_numeric(a = d3_number(array[i]))) s += a; else --j; + } else { + while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) s += a; else --j; + } + if (j) return s / j; + }; + d3.quantile = function(values, p) { + var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; + return e ? v + e * (values[h] - v) : v; + }; + d3.median = function(array, f) { + var numbers = [], n = array.length, a, i = -1; + if (arguments.length === 1) { + while (++i < n) if (d3_numeric(a = d3_number(array[i]))) numbers.push(a); + } else { + while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) numbers.push(a); + } + if (numbers.length) return d3.quantile(numbers.sort(d3_ascending), .5); + }; + d3.variance = function(array, f) { + var n = array.length, m = 0, a, d, s = 0, i = -1, j = 0; + if (arguments.length === 1) { + while (++i < n) { + if (d3_numeric(a = d3_number(array[i]))) { + d = a - m; + m += d / ++j; + s += d * (a - m); + } + } + } else { + while (++i < n) { + if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) { + d = a - m; + m += d / ++j; + s += d * (a - m); + } + } + } + if (j > 1) return s / (j - 1); + }; + d3.deviation = function() { + var v = d3.variance.apply(this, arguments); + return v ? Math.sqrt(v) : v; + }; + function d3_bisector(compare) { + return { + left: function(a, x, lo, hi) { + if (arguments.length < 3) lo = 0; + if (arguments.length < 4) hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid; + } + return lo; + }, + right: function(a, x, lo, hi) { + if (arguments.length < 3) lo = 0; + if (arguments.length < 4) hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1; + } + return lo; + } + }; + } + var d3_bisect = d3_bisector(d3_ascending); + d3.bisectLeft = d3_bisect.left; + d3.bisect = d3.bisectRight = d3_bisect.right; + d3.bisector = function(f) { + return d3_bisector(f.length === 1 ? function(d, x) { + return d3_ascending(f(d), x); + } : f); + }; + d3.shuffle = function(array, i0, i1) { + if ((m = arguments.length) < 3) { + i1 = array.length; + if (m < 2) i0 = 0; + } + var m = i1 - i0, t, i; + while (m) { + i = Math.random() * m-- | 0; + t = array[m + i0], array[m + i0] = array[i + i0], array[i + i0] = t; + } + return array; + }; + d3.permute = function(array, indexes) { + var i = indexes.length, permutes = new Array(i); + while (i--) permutes[i] = array[indexes[i]]; + return permutes; + }; + d3.pairs = function(array) { + var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n); + while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ]; + return pairs; + }; + d3.zip = function() { + if (!(n = arguments.length)) return []; + for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { + for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { + zip[j] = arguments[j][i]; + } + } + return zips; + }; + function d3_zipLength(d) { + return d.length; + } + d3.transpose = function(matrix) { + return d3.zip.apply(d3, matrix); + }; + d3.keys = function(map) { + var keys = []; + for (var key in map) keys.push(key); + return keys; + }; + d3.values = function(map) { + var values = []; + for (var key in map) values.push(map[key]); + return values; + }; + d3.entries = function(map) { + var entries = []; + for (var key in map) entries.push({ + key: key, + value: map[key] + }); + return entries; + }; + d3.merge = function(arrays) { + var n = arrays.length, m, i = -1, j = 0, merged, array; + while (++i < n) j += arrays[i].length; + merged = new Array(j); + while (--n >= 0) { + array = arrays[n]; + m = array.length; + while (--m >= 0) { + merged[--j] = array[m]; + } + } + return merged; + }; + var abs = Math.abs; + d3.range = function(start, stop, step) { + if (arguments.length < 3) { + step = 1; + if (arguments.length < 2) { + stop = start; + start = 0; + } + } + if ((stop - start) / step === Infinity) throw new Error("infinite range"); + var range = [], k = d3_range_integerScale(abs(step)), i = -1, j; + start *= k, stop *= k, step *= k; + if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); + return range; + }; + function d3_range_integerScale(x) { + var k = 1; + while (x * k % 1) k *= 10; + return k; + } + function d3_class(ctor, properties) { + for (var key in properties) { + Object.defineProperty(ctor.prototype, key, { + value: properties[key], + enumerable: false + }); + } + } + d3.map = function(object, f) { + var map = new d3_Map(); + if (object instanceof d3_Map) { + object.forEach(function(key, value) { + map.set(key, value); + }); + } else if (Array.isArray(object)) { + var i = -1, n = object.length, o; + if (arguments.length === 1) while (++i < n) map.set(i, object[i]); else while (++i < n) map.set(f.call(object, o = object[i], i), o); + } else { + for (var key in object) map.set(key, object[key]); + } + return map; + }; + function d3_Map() { + this._ = Object.create(null); + } + var d3_map_proto = "__proto__", d3_map_zero = "\x00"; + d3_class(d3_Map, { + has: d3_map_has, + get: function(key) { + return this._[d3_map_escape(key)]; + }, + set: function(key, value) { + return this._[d3_map_escape(key)] = value; + }, + remove: d3_map_remove, + keys: d3_map_keys, + values: function() { + var values = []; + for (var key in this._) values.push(this._[key]); + return values; + }, + entries: function() { + var entries = []; + for (var key in this._) entries.push({ + key: d3_map_unescape(key), + value: this._[key] + }); + return entries; + }, + size: d3_map_size, + empty: d3_map_empty, + forEach: function(f) { + for (var key in this._) f.call(this, d3_map_unescape(key), this._[key]); + } + }); + function d3_map_escape(key) { + return (key += "") === d3_map_proto || key[0] === d3_map_zero ? d3_map_zero + key : key; + } + function d3_map_unescape(key) { + return (key += "")[0] === d3_map_zero ? key.slice(1) : key; + } + function d3_map_has(key) { + return d3_map_escape(key) in this._; + } + function d3_map_remove(key) { + return (key = d3_map_escape(key)) in this._ && delete this._[key]; + } + function d3_map_keys() { + var keys = []; + for (var key in this._) keys.push(d3_map_unescape(key)); + return keys; + } + function d3_map_size() { + var size = 0; + for (var key in this._) ++size; + return size; + } + function d3_map_empty() { + for (var key in this._) return false; + return true; + } + d3.nest = function() { + var nest = {}, keys = [], sortKeys = [], sortValues, rollup; + function map(mapType, array, depth) { + if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; + var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values; + while (++i < n) { + if (values = valuesByKey.get(keyValue = key(object = array[i]))) { + values.push(object); + } else { + valuesByKey.set(keyValue, [ object ]); + } + } + if (mapType) { + object = mapType(); + setter = function(keyValue, values) { + object.set(keyValue, map(mapType, values, depth)); + }; + } else { + object = {}; + setter = function(keyValue, values) { + object[keyValue] = map(mapType, values, depth); + }; + } + valuesByKey.forEach(setter); + return object; + } + function entries(map, depth) { + if (depth >= keys.length) return map; + var array = [], sortKey = sortKeys[depth++]; + map.forEach(function(key, keyMap) { + array.push({ + key: key, + values: entries(keyMap, depth) + }); + }); + return sortKey ? array.sort(function(a, b) { + return sortKey(a.key, b.key); + }) : array; + } + nest.map = function(array, mapType) { + return map(mapType, array, 0); + }; + nest.entries = function(array) { + return entries(map(d3.map, array, 0), 0); + }; + nest.key = function(d) { + keys.push(d); + return nest; + }; + nest.sortKeys = function(order) { + sortKeys[keys.length - 1] = order; + return nest; + }; + nest.sortValues = function(order) { + sortValues = order; + return nest; + }; + nest.rollup = function(f) { + rollup = f; + return nest; + }; + return nest; + }; + d3.set = function(array) { + var set = new d3_Set(); + if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]); + return set; + }; + function d3_Set() { + this._ = Object.create(null); + } + d3_class(d3_Set, { + has: d3_map_has, + add: function(key) { + this._[d3_map_escape(key += "")] = true; + return key; + }, + remove: d3_map_remove, + values: d3_map_keys, + size: d3_map_size, + empty: d3_map_empty, + forEach: function(f) { + for (var key in this._) f.call(this, d3_map_unescape(key)); + } + }); + d3.behavior = {}; + function d3_identity(d) { + return d; + } + d3.rebind = function(target, source) { + var i = 1, n = arguments.length, method; + while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); + return target; + }; + function d3_rebind(target, source, method) { + return function() { + var value = method.apply(source, arguments); + return value === source ? target : value; + }; + } + function d3_vendorSymbol(object, name) { + if (name in object) return name; + name = name.charAt(0).toUpperCase() + name.slice(1); + for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) { + var prefixName = d3_vendorPrefixes[i] + name; + if (prefixName in object) return prefixName; + } + } + var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ]; + function d3_noop() {} + d3.dispatch = function() { + var dispatch = new d3_dispatch(), i = -1, n = arguments.length; + while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); + return dispatch; + }; + function d3_dispatch() {} + d3_dispatch.prototype.on = function(type, listener) { + var i = type.indexOf("."), name = ""; + if (i >= 0) { + name = type.slice(i + 1); + type = type.slice(0, i); + } + if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); + if (arguments.length === 2) { + if (listener == null) for (type in this) { + if (this.hasOwnProperty(type)) this[type].on(name, null); + } + return this; + } + }; + function d3_dispatch_event(dispatch) { + var listeners = [], listenerByName = new d3_Map(); + function event() { + var z = listeners, i = -1, n = z.length, l; + while (++i < n) if (l = z[i].on) l.apply(this, arguments); + return dispatch; + } + event.on = function(name, listener) { + var l = listenerByName.get(name), i; + if (arguments.length < 2) return l && l.on; + if (l) { + l.on = null; + listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); + listenerByName.remove(name); + } + if (listener) listeners.push(listenerByName.set(name, { + on: listener + })); + return dispatch; + }; + return event; + } + d3.event = null; + function d3_eventPreventDefault() { + d3.event.preventDefault(); + } + function d3_eventSource() { + var e = d3.event, s; + while (s = e.sourceEvent) e = s; + return e; + } + function d3_eventDispatch(target) { + var dispatch = new d3_dispatch(), i = 0, n = arguments.length; + while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); + dispatch.of = function(thiz, argumentz) { + return function(e1) { + try { + var e0 = e1.sourceEvent = d3.event; + e1.target = target; + d3.event = e1; + dispatch[e1.type].apply(thiz, argumentz); + } finally { + d3.event = e0; + } + }; + }; + return dispatch; + } + d3.requote = function(s) { + return s.replace(d3_requote_re, "\\$&"); + }; + var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; + var d3_subclass = {}.__proto__ ? function(object, prototype) { + object.__proto__ = prototype; + } : function(object, prototype) { + for (var property in prototype) object[property] = prototype[property]; + }; + function d3_selection(groups) { + d3_subclass(groups, d3_selectionPrototype); + return groups; + } + var d3_select = function(s, n) { + return n.querySelector(s); + }, d3_selectAll = function(s, n) { + return n.querySelectorAll(s); + }, d3_selectMatches = function(n, s) { + var d3_selectMatcher = n.matches || n[d3_vendorSymbol(n, "matchesSelector")]; + d3_selectMatches = function(n, s) { + return d3_selectMatcher.call(n, s); + }; + return d3_selectMatches(n, s); + }; + if (typeof Sizzle === "function") { + d3_select = function(s, n) { + return Sizzle(s, n)[0] || null; + }; + d3_selectAll = Sizzle; + d3_selectMatches = Sizzle.matchesSelector; + } + d3.selection = function() { + return d3.select(d3_document.documentElement); + }; + var d3_selectionPrototype = d3.selection.prototype = []; + d3_selectionPrototype.select = function(selector) { + var subgroups = [], subgroup, subnode, group, node; + selector = d3_selection_selector(selector); + for (var j = -1, m = this.length; ++j < m; ) { + subgroups.push(subgroup = []); + subgroup.parentNode = (group = this[j]).parentNode; + for (var i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) { + subgroup.push(subnode = selector.call(node, node.__data__, i, j)); + if (subnode && "__data__" in node) subnode.__data__ = node.__data__; + } else { + subgroup.push(null); + } + } + } + return d3_selection(subgroups); + }; + function d3_selection_selector(selector) { + return typeof selector === "function" ? selector : function() { + return d3_select(selector, this); + }; + } + d3_selectionPrototype.selectAll = function(selector) { + var subgroups = [], subgroup, node; + selector = d3_selection_selectorAll(selector); + for (var j = -1, m = this.length; ++j < m; ) { + for (var group = this[j], i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) { + subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j))); + subgroup.parentNode = node; + } + } + } + return d3_selection(subgroups); + }; + function d3_selection_selectorAll(selector) { + return typeof selector === "function" ? selector : function() { + return d3_selectAll(selector, this); + }; + } + var d3_nsPrefix = { + svg: "http://www.w3.org/2000/svg", + xhtml: "http://www.w3.org/1999/xhtml", + xlink: "http://www.w3.org/1999/xlink", + xml: "http://www.w3.org/XML/1998/namespace", + xmlns: "http://www.w3.org/2000/xmlns/" + }; + d3.ns = { + prefix: d3_nsPrefix, + qualify: function(name) { + var i = name.indexOf(":"), prefix = name; + if (i >= 0) { + prefix = name.slice(0, i); + name = name.slice(i + 1); + } + return d3_nsPrefix.hasOwnProperty(prefix) ? { + space: d3_nsPrefix[prefix], + local: name + } : name; + } + }; + d3_selectionPrototype.attr = function(name, value) { + if (arguments.length < 2) { + if (typeof name === "string") { + var node = this.node(); + name = d3.ns.qualify(name); + return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name); + } + for (value in name) this.each(d3_selection_attr(value, name[value])); + return this; + } + return this.each(d3_selection_attr(name, value)); + }; + function d3_selection_attr(name, value) { + name = d3.ns.qualify(name); + function attrNull() { + this.removeAttribute(name); + } + function attrNullNS() { + this.removeAttributeNS(name.space, name.local); + } + function attrConstant() { + this.setAttribute(name, value); + } + function attrConstantNS() { + this.setAttributeNS(name.space, name.local, value); + } + function attrFunction() { + var x = value.apply(this, arguments); + if (x == null) this.removeAttribute(name); else this.setAttribute(name, x); + } + function attrFunctionNS() { + var x = value.apply(this, arguments); + if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x); + } + return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant; + } + function d3_collapse(s) { + return s.trim().replace(/\s+/g, " "); + } + d3_selectionPrototype.classed = function(name, value) { + if (arguments.length < 2) { + if (typeof name === "string") { + var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1; + if (value = node.classList) { + while (++i < n) if (!value.contains(name[i])) return false; + } else { + value = node.getAttribute("class"); + while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; + } + return true; + } + for (value in name) this.each(d3_selection_classed(value, name[value])); + return this; + } + return this.each(d3_selection_classed(name, value)); + }; + function d3_selection_classedRe(name) { + return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); + } + function d3_selection_classes(name) { + return (name + "").trim().split(/^|\s+/); + } + function d3_selection_classed(name, value) { + name = d3_selection_classes(name).map(d3_selection_classedName); + var n = name.length; + function classedConstant() { + var i = -1; + while (++i < n) name[i](this, value); + } + function classedFunction() { + var i = -1, x = value.apply(this, arguments); + while (++i < n) name[i](this, x); + } + return typeof value === "function" ? classedFunction : classedConstant; + } + function d3_selection_classedName(name) { + var re = d3_selection_classedRe(name); + return function(node, value) { + if (c = node.classList) return value ? c.add(name) : c.remove(name); + var c = node.getAttribute("class") || ""; + if (value) { + re.lastIndex = 0; + if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name)); + } else { + node.setAttribute("class", d3_collapse(c.replace(re, " "))); + } + }; + } + d3_selectionPrototype.style = function(name, value, priority) { + var n = arguments.length; + if (n < 3) { + if (typeof name !== "string") { + if (n < 2) value = ""; + for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); + return this; + } + if (n < 2) { + var node = this.node(); + return d3_window(node).getComputedStyle(node, null).getPropertyValue(name); + } + priority = ""; + } + return this.each(d3_selection_style(name, value, priority)); + }; + function d3_selection_style(name, value, priority) { + function styleNull() { + this.style.removeProperty(name); + } + function styleConstant() { + this.style.setProperty(name, value, priority); + } + function styleFunction() { + var x = value.apply(this, arguments); + if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority); + } + return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant; + } + d3_selectionPrototype.property = function(name, value) { + if (arguments.length < 2) { + if (typeof name === "string") return this.node()[name]; + for (value in name) this.each(d3_selection_property(value, name[value])); + return this; + } + return this.each(d3_selection_property(name, value)); + }; + function d3_selection_property(name, value) { + function propertyNull() { + delete this[name]; + } + function propertyConstant() { + this[name] = value; + } + function propertyFunction() { + var x = value.apply(this, arguments); + if (x == null) delete this[name]; else this[name] = x; + } + return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant; + } + d3_selectionPrototype.text = function(value) { + return arguments.length ? this.each(typeof value === "function" ? function() { + var v = value.apply(this, arguments); + this.textContent = v == null ? "" : v; + } : value == null ? function() { + this.textContent = ""; + } : function() { + this.textContent = value; + }) : this.node().textContent; + }; + d3_selectionPrototype.html = function(value) { + return arguments.length ? this.each(typeof value === "function" ? function() { + var v = value.apply(this, arguments); + this.innerHTML = v == null ? "" : v; + } : value == null ? function() { + this.innerHTML = ""; + } : function() { + this.innerHTML = value; + }) : this.node().innerHTML; + }; + d3_selectionPrototype.append = function(name) { + name = d3_selection_creator(name); + return this.select(function() { + return this.appendChild(name.apply(this, arguments)); + }); + }; + function d3_selection_creator(name) { + function create() { + var document = this.ownerDocument, namespace = this.namespaceURI; + return namespace ? document.createElementNS(namespace, name) : document.createElement(name); + } + function createNS() { + return this.ownerDocument.createElementNS(name.space, name.local); + } + return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? createNS : create; + } + d3_selectionPrototype.insert = function(name, before) { + name = d3_selection_creator(name); + before = d3_selection_selector(before); + return this.select(function() { + return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null); + }); + }; + d3_selectionPrototype.remove = function() { + return this.each(d3_selectionRemove); + }; + function d3_selectionRemove() { + var parent = this.parentNode; + if (parent) parent.removeChild(this); + } + d3_selectionPrototype.data = function(value, key) { + var i = -1, n = this.length, group, node; + if (!arguments.length) { + value = new Array(n = (group = this[0]).length); + while (++i < n) { + if (node = group[i]) { + value[i] = node.__data__; + } + } + return value; + } + function bind(group, groupData) { + var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData; + if (key) { + var nodeByKeyValue = new d3_Map(), keyValues = new Array(n), keyValue; + for (i = -1; ++i < n; ) { + if (nodeByKeyValue.has(keyValue = key.call(node = group[i], node.__data__, i))) { + exitNodes[i] = node; + } else { + nodeByKeyValue.set(keyValue, node); + } + keyValues[i] = keyValue; + } + for (i = -1; ++i < m; ) { + if (!(node = nodeByKeyValue.get(keyValue = key.call(groupData, nodeData = groupData[i], i)))) { + enterNodes[i] = d3_selection_dataNode(nodeData); + } else if (node !== true) { + updateNodes[i] = node; + node.__data__ = nodeData; + } + nodeByKeyValue.set(keyValue, true); + } + for (i = -1; ++i < n; ) { + if (nodeByKeyValue.get(keyValues[i]) !== true) { + exitNodes[i] = group[i]; + } + } + } else { + for (i = -1; ++i < n0; ) { + node = group[i]; + nodeData = groupData[i]; + if (node) { + node.__data__ = nodeData; + updateNodes[i] = node; + } else { + enterNodes[i] = d3_selection_dataNode(nodeData); + } + } + for (;i < m; ++i) { + enterNodes[i] = d3_selection_dataNode(groupData[i]); + } + for (;i < n; ++i) { + exitNodes[i] = group[i]; + } + } + enterNodes.update = updateNodes; + enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode; + enter.push(enterNodes); + update.push(updateNodes); + exit.push(exitNodes); + } + var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); + if (typeof value === "function") { + while (++i < n) { + bind(group = this[i], value.call(group, group.parentNode.__data__, i)); + } + } else { + while (++i < n) { + bind(group = this[i], value); + } + } + update.enter = function() { + return enter; + }; + update.exit = function() { + return exit; + }; + return update; + }; + function d3_selection_dataNode(data) { + return { + __data__: data + }; + } + d3_selectionPrototype.datum = function(value) { + return arguments.length ? this.property("__data__", value) : this.property("__data__"); + }; + d3_selectionPrototype.filter = function(filter) { + var subgroups = [], subgroup, group, node; + if (typeof filter !== "function") filter = d3_selection_filter(filter); + for (var j = 0, m = this.length; j < m; j++) { + subgroups.push(subgroup = []); + subgroup.parentNode = (group = this[j]).parentNode; + for (var i = 0, n = group.length; i < n; i++) { + if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { + subgroup.push(node); + } + } + } + return d3_selection(subgroups); + }; + function d3_selection_filter(selector) { + return function() { + return d3_selectMatches(this, selector); + }; + } + d3_selectionPrototype.order = function() { + for (var j = -1, m = this.length; ++j < m; ) { + for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) { + if (node = group[i]) { + if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); + next = node; + } + } + } + return this; + }; + d3_selectionPrototype.sort = function(comparator) { + comparator = d3_selection_sortComparator.apply(this, arguments); + for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator); + return this.order(); + }; + function d3_selection_sortComparator(comparator) { + if (!arguments.length) comparator = d3_ascending; + return function(a, b) { + return a && b ? comparator(a.__data__, b.__data__) : !a - !b; + }; + } + d3_selectionPrototype.each = function(callback) { + return d3_selection_each(this, function(node, i, j) { + callback.call(node, node.__data__, i, j); + }); + }; + function d3_selection_each(groups, callback) { + for (var j = 0, m = groups.length; j < m; j++) { + for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) { + if (node = group[i]) callback(node, i, j); + } + } + return groups; + } + d3_selectionPrototype.call = function(callback) { + var args = d3_array(arguments); + callback.apply(args[0] = this, args); + return this; + }; + d3_selectionPrototype.empty = function() { + return !this.node(); + }; + d3_selectionPrototype.node = function() { + for (var j = 0, m = this.length; j < m; j++) { + for (var group = this[j], i = 0, n = group.length; i < n; i++) { + var node = group[i]; + if (node) return node; + } + } + return null; + }; + d3_selectionPrototype.size = function() { + var n = 0; + d3_selection_each(this, function() { + ++n; + }); + return n; + }; + function d3_selection_enter(selection) { + d3_subclass(selection, d3_selection_enterPrototype); + return selection; + } + var d3_selection_enterPrototype = []; + d3.selection.enter = d3_selection_enter; + d3.selection.enter.prototype = d3_selection_enterPrototype; + d3_selection_enterPrototype.append = d3_selectionPrototype.append; + d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; + d3_selection_enterPrototype.node = d3_selectionPrototype.node; + d3_selection_enterPrototype.call = d3_selectionPrototype.call; + d3_selection_enterPrototype.size = d3_selectionPrototype.size; + d3_selection_enterPrototype.select = function(selector) { + var subgroups = [], subgroup, subnode, upgroup, group, node; + for (var j = -1, m = this.length; ++j < m; ) { + upgroup = (group = this[j]).update; + subgroups.push(subgroup = []); + subgroup.parentNode = group.parentNode; + for (var i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) { + subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j)); + subnode.__data__ = node.__data__; + } else { + subgroup.push(null); + } + } + } + return d3_selection(subgroups); + }; + d3_selection_enterPrototype.insert = function(name, before) { + if (arguments.length < 2) before = d3_selection_enterInsertBefore(this); + return d3_selectionPrototype.insert.call(this, name, before); + }; + function d3_selection_enterInsertBefore(enter) { + var i0, j0; + return function(d, i, j) { + var group = enter[j].update, n = group.length, node; + if (j != j0) j0 = j, i0 = 0; + if (i >= i0) i0 = i + 1; + while (!(node = group[i0]) && ++i0 < n) ; + return node; + }; + } + d3.select = function(node) { + var group; + if (typeof node === "string") { + group = [ d3_select(node, d3_document) ]; + group.parentNode = d3_document.documentElement; + } else { + group = [ node ]; + group.parentNode = d3_documentElement(node); + } + return d3_selection([ group ]); + }; + d3.selectAll = function(nodes) { + var group; + if (typeof nodes === "string") { + group = d3_array(d3_selectAll(nodes, d3_document)); + group.parentNode = d3_document.documentElement; + } else { + group = nodes; + group.parentNode = null; + } + return d3_selection([ group ]); + }; + d3_selectionPrototype.on = function(type, listener, capture) { + var n = arguments.length; + if (n < 3) { + if (typeof type !== "string") { + if (n < 2) listener = false; + for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); + return this; + } + if (n < 2) return (n = this.node()["__on" + type]) && n._; + capture = false; + } + return this.each(d3_selection_on(type, listener, capture)); + }; + function d3_selection_on(type, listener, capture) { + var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener; + if (i > 0) type = type.slice(0, i); + var filter = d3_selection_onFilters.get(type); + if (filter) type = filter, wrap = d3_selection_onFilter; + function onRemove() { + var l = this[name]; + if (l) { + this.removeEventListener(type, l, l.$); + delete this[name]; + } + } + function onAdd() { + var l = wrap(listener, d3_array(arguments)); + onRemove.call(this); + this.addEventListener(type, this[name] = l, l.$ = capture); + l._ = listener; + } + function removeAll() { + var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match; + for (var name in this) { + if (match = name.match(re)) { + var l = this[name]; + this.removeEventListener(match[1], l, l.$); + delete this[name]; + } + } + } + return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll; + } + var d3_selection_onFilters = d3.map({ + mouseenter: "mouseover", + mouseleave: "mouseout" + }); + if (d3_document) { + d3_selection_onFilters.forEach(function(k) { + if ("on" + k in d3_document) d3_selection_onFilters.remove(k); + }); + } + function d3_selection_onListener(listener, argumentz) { + return function(e) { + var o = d3.event; + d3.event = e; + argumentz[0] = this.__data__; + try { + listener.apply(this, argumentz); + } finally { + d3.event = o; + } + }; + } + function d3_selection_onFilter(listener, argumentz) { + var l = d3_selection_onListener(listener, argumentz); + return function(e) { + var target = this, related = e.relatedTarget; + if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) { + l.call(target, e); + } + }; + } + var d3_event_dragSelect, d3_event_dragId = 0; + function d3_event_dragSuppress(node) { + var name = ".dragsuppress-" + ++d3_event_dragId, click = "click" + name, w = d3.select(d3_window(node)).on("touchmove" + name, d3_eventPreventDefault).on("dragstart" + name, d3_eventPreventDefault).on("selectstart" + name, d3_eventPreventDefault); + if (d3_event_dragSelect == null) { + d3_event_dragSelect = "onselectstart" in node ? false : d3_vendorSymbol(node.style, "userSelect"); + } + if (d3_event_dragSelect) { + var style = d3_documentElement(node).style, select = style[d3_event_dragSelect]; + style[d3_event_dragSelect] = "none"; + } + return function(suppressClick) { + w.on(name, null); + if (d3_event_dragSelect) style[d3_event_dragSelect] = select; + if (suppressClick) { + var off = function() { + w.on(click, null); + }; + w.on(click, function() { + d3_eventPreventDefault(); + off(); + }, true); + setTimeout(off, 0); + } + }; + } + d3.mouse = function(container) { + return d3_mousePoint(container, d3_eventSource()); + }; + var d3_mouse_bug44083 = this.navigator && /WebKit/.test(this.navigator.userAgent) ? -1 : 0; + function d3_mousePoint(container, e) { + if (e.changedTouches) e = e.changedTouches[0]; + var svg = container.ownerSVGElement || container; + if (svg.createSVGPoint) { + var point = svg.createSVGPoint(); + if (d3_mouse_bug44083 < 0) { + var window = d3_window(container); + if (window.scrollX || window.scrollY) { + svg = d3.select("body").append("svg").style({ + position: "absolute", + top: 0, + left: 0, + margin: 0, + padding: 0, + border: "none" + }, "important"); + var ctm = svg[0][0].getScreenCTM(); + d3_mouse_bug44083 = !(ctm.f || ctm.e); + svg.remove(); + } + } + if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX, + point.y = e.clientY; + point = point.matrixTransform(container.getScreenCTM().inverse()); + return [ point.x, point.y ]; + } + var rect = container.getBoundingClientRect(); + return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ]; + } + d3.touch = function(container, touches, identifier) { + if (arguments.length < 3) identifier = touches, touches = d3_eventSource().changedTouches; + if (touches) for (var i = 0, n = touches.length, touch; i < n; ++i) { + if ((touch = touches[i]).identifier === identifier) { + return d3_mousePoint(container, touch); + } + } + }; + d3.behavior.drag = function() { + var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, d3_window, "mousemove", "mouseup"), touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_identity, "touchmove", "touchend"); + function drag() { + this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart); + } + function dragstart(id, position, subject, move, end) { + return function() { + var that = this, target = d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragSubject = d3.select(subject(target)).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(target), position0 = position(parent, dragId); + if (origin) { + dragOffset = origin.apply(that, arguments); + dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ]; + } else { + dragOffset = [ 0, 0 ]; + } + dispatch({ + type: "dragstart" + }); + function moved() { + var position1 = position(parent, dragId), dx, dy; + if (!position1) return; + dx = position1[0] - position0[0]; + dy = position1[1] - position0[1]; + dragged |= dx | dy; + position0 = position1; + dispatch({ + type: "drag", + x: position1[0] + dragOffset[0], + y: position1[1] + dragOffset[1], + dx: dx, + dy: dy + }); + } + function ended() { + if (!position(parent, dragId)) return; + dragSubject.on(move + dragName, null).on(end + dragName, null); + dragRestore(dragged && d3.event.target === target); + dispatch({ + type: "dragend" + }); + } + }; + } + drag.origin = function(x) { + if (!arguments.length) return origin; + origin = x; + return drag; + }; + return d3.rebind(drag, event, "on"); + }; + function d3_behavior_dragTouchId() { + return d3.event.changedTouches[0].identifier; + } + d3.touches = function(container, touches) { + if (arguments.length < 2) touches = d3_eventSource().touches; + return touches ? d3_array(touches).map(function(touch) { + var point = d3_mousePoint(container, touch); + point.identifier = touch.identifier; + return point; + }) : []; + }; + var ε = 1e-6, ε2 = ε * ε, π = Math.PI, τ = 2 * π, τε = τ - ε, halfπ = π / 2, d3_radians = π / 180, d3_degrees = 180 / π; + function d3_sgn(x) { + return x > 0 ? 1 : x < 0 ? -1 : 0; + } + function d3_cross2d(a, b, c) { + return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]); + } + function d3_acos(x) { + return x > 1 ? 0 : x < -1 ? π : Math.acos(x); + } + function d3_asin(x) { + return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x); + } + function d3_sinh(x) { + return ((x = Math.exp(x)) - 1 / x) / 2; + } + function d3_cosh(x) { + return ((x = Math.exp(x)) + 1 / x) / 2; + } + function d3_tanh(x) { + return ((x = Math.exp(2 * x)) - 1) / (x + 1); + } + function d3_haversin(x) { + return (x = Math.sin(x / 2)) * x; + } + var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4; + d3.interpolateZoom = function(p0, p1) { + var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2]; + var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / ρ; + function interpolate(t) { + var s = t * S; + if (dr) { + var coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0)); + return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ]; + } + return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * s) ]; + } + interpolate.duration = S * 1e3; + return interpolate; + }; + d3.behavior.zoom = function() { + var view = { + x: 0, + y: 0, + k: 1 + }, translate0, center0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, duration = 250, zooming = 0, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1; + if (!d3_behavior_zoomWheel) { + d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { + return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); + }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { + return d3.event.wheelDelta; + }, "mousewheel") : (d3_behavior_zoomDelta = function() { + return -d3.event.detail; + }, "MozMousePixelScroll"); + } + function zoom(g) { + g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted); + } + zoom.event = function(g) { + g.each(function() { + var dispatch = event.of(this, arguments), view1 = view; + if (d3_transitionInheritId) { + d3.select(this).transition().each("start.zoom", function() { + view = this.__chart__ || { + x: 0, + y: 0, + k: 1 + }; + zoomstarted(dispatch); + }).tween("zoom:zoom", function() { + var dx = size[0], dy = size[1], cx = center0 ? center0[0] : dx / 2, cy = center0 ? center0[1] : dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]); + return function(t) { + var l = i(t), k = dx / l[2]; + this.__chart__ = view = { + x: cx - l[0] * k, + y: cy - l[1] * k, + k: k + }; + zoomed(dispatch); + }; + }).each("interrupt.zoom", function() { + zoomended(dispatch); + }).each("end.zoom", function() { + zoomended(dispatch); + }); + } else { + this.__chart__ = view; + zoomstarted(dispatch); + zoomed(dispatch); + zoomended(dispatch); + } + }); + }; + zoom.translate = function(_) { + if (!arguments.length) return [ view.x, view.y ]; + view = { + x: +_[0], + y: +_[1], + k: view.k + }; + rescale(); + return zoom; + }; + zoom.scale = function(_) { + if (!arguments.length) return view.k; + view = { + x: view.x, + y: view.y, + k: +_ + }; + rescale(); + return zoom; + }; + zoom.scaleExtent = function(_) { + if (!arguments.length) return scaleExtent; + scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ]; + return zoom; + }; + zoom.center = function(_) { + if (!arguments.length) return center; + center = _ && [ +_[0], +_[1] ]; + return zoom; + }; + zoom.size = function(_) { + if (!arguments.length) return size; + size = _ && [ +_[0], +_[1] ]; + return zoom; + }; + zoom.duration = function(_) { + if (!arguments.length) return duration; + duration = +_; + return zoom; + }; + zoom.x = function(z) { + if (!arguments.length) return x1; + x1 = z; + x0 = z.copy(); + view = { + x: 0, + y: 0, + k: 1 + }; + return zoom; + }; + zoom.y = function(z) { + if (!arguments.length) return y1; + y1 = z; + y0 = z.copy(); + view = { + x: 0, + y: 0, + k: 1 + }; + return zoom; + }; + function location(p) { + return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ]; + } + function point(l) { + return [ l[0] * view.k + view.x, l[1] * view.k + view.y ]; + } + function scaleTo(s) { + view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); + } + function translateTo(p, l) { + l = point(l); + view.x += p[0] - l[0]; + view.y += p[1] - l[1]; + } + function zoomTo(that, p, l, k) { + that.__chart__ = { + x: view.x, + y: view.y, + k: view.k + }; + scaleTo(Math.pow(2, k)); + translateTo(center0 = p, l); + that = d3.select(that); + if (duration > 0) that = that.transition().duration(duration); + that.call(zoom.event); + } + function rescale() { + if (x1) x1.domain(x0.range().map(function(x) { + return (x - view.x) / view.k; + }).map(x0.invert)); + if (y1) y1.domain(y0.range().map(function(y) { + return (y - view.y) / view.k; + }).map(y0.invert)); + } + function zoomstarted(dispatch) { + if (!zooming++) dispatch({ + type: "zoomstart" + }); + } + function zoomed(dispatch) { + rescale(); + dispatch({ + type: "zoom", + scale: view.k, + translate: [ view.x, view.y ] + }); + } + function zoomended(dispatch) { + if (!--zooming) dispatch({ + type: "zoomend" + }), center0 = null; + } + function mousedowned() { + var that = this, target = d3.event.target, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window(that)).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress(that); + d3_selection_interrupt.call(that); + zoomstarted(dispatch); + function moved() { + dragged = 1; + translateTo(d3.mouse(that), location0); + zoomed(dispatch); + } + function ended() { + subject.on(mousemove, null).on(mouseup, null); + dragRestore(dragged && d3.event.target === target); + zoomended(dispatch); + } + } + function touchstarted() { + var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = ".zoom-" + d3.event.changedTouches[0].identifier, touchmove = "touchmove" + zoomName, touchend = "touchend" + zoomName, targets = [], subject = d3.select(that), dragRestore = d3_event_dragSuppress(that); + started(); + zoomstarted(dispatch); + subject.on(mousedown, null).on(touchstart, started); + function relocate() { + var touches = d3.touches(that); + scale0 = view.k; + touches.forEach(function(t) { + if (t.identifier in locations0) locations0[t.identifier] = location(t); + }); + return touches; + } + function started() { + var target = d3.event.target; + d3.select(target).on(touchmove, moved).on(touchend, ended); + targets.push(target); + var changed = d3.event.changedTouches; + for (var i = 0, n = changed.length; i < n; ++i) { + locations0[changed[i].identifier] = null; + } + var touches = relocate(), now = Date.now(); + if (touches.length === 1) { + if (now - touchtime < 500) { + var p = touches[0]; + zoomTo(that, p, locations0[p.identifier], Math.floor(Math.log(view.k) / Math.LN2) + 1); + d3_eventPreventDefault(); + } + touchtime = now; + } else if (touches.length > 1) { + var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1]; + distance0 = dx * dx + dy * dy; + } + } + function moved() { + var touches = d3.touches(that), p0, l0, p1, l1; + d3_selection_interrupt.call(that); + for (var i = 0, n = touches.length; i < n; ++i, l1 = null) { + p1 = touches[i]; + if (l1 = locations0[p1.identifier]) { + if (l0) break; + p0 = p1, l0 = l1; + } + } + if (l1) { + var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0); + p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ]; + l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ]; + scaleTo(scale1 * scale0); + } + touchtime = null; + translateTo(p0, l0); + zoomed(dispatch); + } + function ended() { + if (d3.event.touches.length) { + var changed = d3.event.changedTouches; + for (var i = 0, n = changed.length; i < n; ++i) { + delete locations0[changed[i].identifier]; + } + for (var identifier in locations0) { + return void relocate(); + } + } + d3.selectAll(targets).on(zoomName, null); + subject.on(mousedown, mousedowned).on(touchstart, touchstarted); + dragRestore(); + zoomended(dispatch); + } + } + function mousewheeled() { + var dispatch = event.of(this, arguments); + if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this), + translate0 = location(center0 = center || d3.mouse(this)), zoomstarted(dispatch); + mousewheelTimer = setTimeout(function() { + mousewheelTimer = null; + zoomended(dispatch); + }, 50); + d3_eventPreventDefault(); + scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k); + translateTo(center0, translate0); + zoomed(dispatch); + } + function dblclicked() { + var p = d3.mouse(this), k = Math.log(view.k) / Math.LN2; + zoomTo(this, p, location(p), d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1); + } + return d3.rebind(zoom, event, "on"); + }; + var d3_behavior_zoomInfinity = [ 0, Infinity ], d3_behavior_zoomDelta, d3_behavior_zoomWheel; + d3.color = d3_color; + function d3_color() {} + d3_color.prototype.toString = function() { + return this.rgb() + ""; + }; + d3.hsl = d3_hsl; + function d3_hsl(h, s, l) { + return this instanceof d3_hsl ? void (this.h = +h, this.s = +s, this.l = +l) : arguments.length < 2 ? h instanceof d3_hsl ? new d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : new d3_hsl(h, s, l); + } + var d3_hslPrototype = d3_hsl.prototype = new d3_color(); + d3_hslPrototype.brighter = function(k) { + k = Math.pow(.7, arguments.length ? k : 1); + return new d3_hsl(this.h, this.s, this.l / k); + }; + d3_hslPrototype.darker = function(k) { + k = Math.pow(.7, arguments.length ? k : 1); + return new d3_hsl(this.h, this.s, k * this.l); + }; + d3_hslPrototype.rgb = function() { + return d3_hsl_rgb(this.h, this.s, this.l); + }; + function d3_hsl_rgb(h, s, l) { + var m1, m2; + h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h; + s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s; + l = l < 0 ? 0 : l > 1 ? 1 : l; + m2 = l <= .5 ? l * (1 + s) : l + s - l * s; + m1 = 2 * l - m2; + function v(h) { + if (h > 360) h -= 360; else if (h < 0) h += 360; + if (h < 60) return m1 + (m2 - m1) * h / 60; + if (h < 180) return m2; + if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; + return m1; + } + function vv(h) { + return Math.round(v(h) * 255); + } + return new d3_rgb(vv(h + 120), vv(h), vv(h - 120)); + } + d3.hcl = d3_hcl; + function d3_hcl(h, c, l) { + return this instanceof d3_hcl ? void (this.h = +h, this.c = +c, this.l = +l) : arguments.length < 2 ? h instanceof d3_hcl ? new d3_hcl(h.h, h.c, h.l) : h instanceof d3_lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : new d3_hcl(h, c, l); + } + var d3_hclPrototype = d3_hcl.prototype = new d3_color(); + d3_hclPrototype.brighter = function(k) { + return new d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); + }; + d3_hclPrototype.darker = function(k) { + return new d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); + }; + d3_hclPrototype.rgb = function() { + return d3_hcl_lab(this.h, this.c, this.l).rgb(); + }; + function d3_hcl_lab(h, c, l) { + if (isNaN(h)) h = 0; + if (isNaN(c)) c = 0; + return new d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); + } + d3.lab = d3_lab; + function d3_lab(l, a, b) { + return this instanceof d3_lab ? void (this.l = +l, this.a = +a, this.b = +b) : arguments.length < 2 ? l instanceof d3_lab ? new d3_lab(l.l, l.a, l.b) : l instanceof d3_hcl ? d3_hcl_lab(l.h, l.c, l.l) : d3_rgb_lab((l = d3_rgb(l)).r, l.g, l.b) : new d3_lab(l, a, b); + } + var d3_lab_K = 18; + var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883; + var d3_labPrototype = d3_lab.prototype = new d3_color(); + d3_labPrototype.brighter = function(k) { + return new d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); + }; + d3_labPrototype.darker = function(k) { + return new d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); + }; + d3_labPrototype.rgb = function() { + return d3_lab_rgb(this.l, this.a, this.b); + }; + function d3_lab_rgb(l, a, b) { + var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200; + x = d3_lab_xyz(x) * d3_lab_X; + y = d3_lab_xyz(y) * d3_lab_Y; + z = d3_lab_xyz(z) * d3_lab_Z; + return new d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z)); + } + function d3_lab_hcl(l, a, b) { + return l > 0 ? new d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : new d3_hcl(NaN, NaN, l); + } + function d3_lab_xyz(x) { + return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037; + } + function d3_xyz_lab(x) { + return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; + } + function d3_xyz_rgb(r) { + return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055)); + } + d3.rgb = d3_rgb; + function d3_rgb(r, g, b) { + return this instanceof d3_rgb ? void (this.r = ~~r, this.g = ~~g, this.b = ~~b) : arguments.length < 2 ? r instanceof d3_rgb ? new d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : new d3_rgb(r, g, b); + } + function d3_rgbNumber(value) { + return new d3_rgb(value >> 16, value >> 8 & 255, value & 255); + } + function d3_rgbString(value) { + return d3_rgbNumber(value) + ""; + } + var d3_rgbPrototype = d3_rgb.prototype = new d3_color(); + d3_rgbPrototype.brighter = function(k) { + k = Math.pow(.7, arguments.length ? k : 1); + var r = this.r, g = this.g, b = this.b, i = 30; + if (!r && !g && !b) return new d3_rgb(i, i, i); + if (r && r < i) r = i; + if (g && g < i) g = i; + if (b && b < i) b = i; + return new d3_rgb(Math.min(255, r / k), Math.min(255, g / k), Math.min(255, b / k)); + }; + d3_rgbPrototype.darker = function(k) { + k = Math.pow(.7, arguments.length ? k : 1); + return new d3_rgb(k * this.r, k * this.g, k * this.b); + }; + d3_rgbPrototype.hsl = function() { + return d3_rgb_hsl(this.r, this.g, this.b); + }; + d3_rgbPrototype.toString = function() { + return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); + }; + function d3_rgb_hex(v) { + return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16); + } + function d3_rgb_parse(format, rgb, hsl) { + var r = 0, g = 0, b = 0, m1, m2, color; + m1 = /([a-z]+)\((.*)\)/.exec(format = format.toLowerCase()); + if (m1) { + m2 = m1[2].split(","); + switch (m1[1]) { + case "hsl": + { + return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100); + } + + case "rgb": + { + return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2])); + } + } + } + if (color = d3_rgb_names.get(format)) { + return rgb(color.r, color.g, color.b); + } + if (format != null && format.charAt(0) === "#" && !isNaN(color = parseInt(format.slice(1), 16))) { + if (format.length === 4) { + r = (color & 3840) >> 4; + r = r >> 4 | r; + g = color & 240; + g = g >> 4 | g; + b = color & 15; + b = b << 4 | b; + } else if (format.length === 7) { + r = (color & 16711680) >> 16; + g = (color & 65280) >> 8; + b = color & 255; + } + } + return rgb(r, g, b); + } + function d3_rgb_hsl(r, g, b) { + var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2; + if (d) { + s = l < .5 ? d / (max + min) : d / (2 - max - min); + if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4; + h *= 60; + } else { + h = NaN; + s = l > 0 && l < 1 ? 0 : h; + } + return new d3_hsl(h, s, l); + } + function d3_rgb_lab(r, g, b) { + r = d3_rgb_xyz(r); + g = d3_rgb_xyz(g); + b = d3_rgb_xyz(b); + var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z); + return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); + } + function d3_rgb_xyz(r) { + return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4); + } + function d3_rgb_parseNumber(c) { + var f = parseFloat(c); + return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; + } + var d3_rgb_names = d3.map({ + aliceblue: 15792383, + antiquewhite: 16444375, + aqua: 65535, + aquamarine: 8388564, + azure: 15794175, + beige: 16119260, + bisque: 16770244, + black: 0, + blanchedalmond: 16772045, + blue: 255, + blueviolet: 9055202, + brown: 10824234, + burlywood: 14596231, + cadetblue: 6266528, + chartreuse: 8388352, + chocolate: 13789470, + coral: 16744272, + cornflowerblue: 6591981, + cornsilk: 16775388, + crimson: 14423100, + cyan: 65535, + darkblue: 139, + darkcyan: 35723, + darkgoldenrod: 12092939, + darkgray: 11119017, + darkgreen: 25600, + darkgrey: 11119017, + darkkhaki: 12433259, + darkmagenta: 9109643, + darkolivegreen: 5597999, + darkorange: 16747520, + darkorchid: 10040012, + darkred: 9109504, + darksalmon: 15308410, + darkseagreen: 9419919, + darkslateblue: 4734347, + darkslategray: 3100495, + darkslategrey: 3100495, + darkturquoise: 52945, + darkviolet: 9699539, + deeppink: 16716947, + deepskyblue: 49151, + dimgray: 6908265, + dimgrey: 6908265, + dodgerblue: 2003199, + firebrick: 11674146, + floralwhite: 16775920, + forestgreen: 2263842, + fuchsia: 16711935, + gainsboro: 14474460, + ghostwhite: 16316671, + gold: 16766720, + goldenrod: 14329120, + gray: 8421504, + green: 32768, + greenyellow: 11403055, + grey: 8421504, + honeydew: 15794160, + hotpink: 16738740, + indianred: 13458524, + indigo: 4915330, + ivory: 16777200, + khaki: 15787660, + lavender: 15132410, + lavenderblush: 16773365, + lawngreen: 8190976, + lemonchiffon: 16775885, + lightblue: 11393254, + lightcoral: 15761536, + lightcyan: 14745599, + lightgoldenrodyellow: 16448210, + lightgray: 13882323, + lightgreen: 9498256, + lightgrey: 13882323, + lightpink: 16758465, + lightsalmon: 16752762, + lightseagreen: 2142890, + lightskyblue: 8900346, + lightslategray: 7833753, + lightslategrey: 7833753, + lightsteelblue: 11584734, + lightyellow: 16777184, + lime: 65280, + limegreen: 3329330, + linen: 16445670, + magenta: 16711935, + maroon: 8388608, + mediumaquamarine: 6737322, + mediumblue: 205, + mediumorchid: 12211667, + mediumpurple: 9662683, + mediumseagreen: 3978097, + mediumslateblue: 8087790, + mediumspringgreen: 64154, + mediumturquoise: 4772300, + mediumvioletred: 13047173, + midnightblue: 1644912, + mintcream: 16121850, + mistyrose: 16770273, + moccasin: 16770229, + navajowhite: 16768685, + navy: 128, + oldlace: 16643558, + olive: 8421376, + olivedrab: 7048739, + orange: 16753920, + orangered: 16729344, + orchid: 14315734, + palegoldenrod: 15657130, + palegreen: 10025880, + paleturquoise: 11529966, + palevioletred: 14381203, + papayawhip: 16773077, + peachpuff: 16767673, + peru: 13468991, + pink: 16761035, + plum: 14524637, + powderblue: 11591910, + purple: 8388736, + rebeccapurple: 6697881, + red: 16711680, + rosybrown: 12357519, + royalblue: 4286945, + saddlebrown: 9127187, + salmon: 16416882, + sandybrown: 16032864, + seagreen: 3050327, + seashell: 16774638, + sienna: 10506797, + silver: 12632256, + skyblue: 8900331, + slateblue: 6970061, + slategray: 7372944, + slategrey: 7372944, + snow: 16775930, + springgreen: 65407, + steelblue: 4620980, + tan: 13808780, + teal: 32896, + thistle: 14204888, + tomato: 16737095, + turquoise: 4251856, + violet: 15631086, + wheat: 16113331, + white: 16777215, + whitesmoke: 16119285, + yellow: 16776960, + yellowgreen: 10145074 + }); + d3_rgb_names.forEach(function(key, value) { + d3_rgb_names.set(key, d3_rgbNumber(value)); + }); + function d3_functor(v) { + return typeof v === "function" ? v : function() { + return v; + }; + } + d3.functor = d3_functor; + d3.xhr = d3_xhrType(d3_identity); + function d3_xhrType(response) { + return function(url, mimeType, callback) { + if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, + mimeType = null; + return d3_xhr(url, mimeType, response, callback); + }; + } + function d3_xhr(url, mimeType, response, callback) { + var xhr = {}, dispatch = d3.dispatch("beforesend", "progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null; + if (this.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); + "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() { + request.readyState > 3 && respond(); + }; + function respond() { + var status = request.status, result; + if (!status && d3_xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) { + try { + result = response.call(xhr, request); + } catch (e) { + dispatch.error.call(xhr, e); + return; + } + dispatch.load.call(xhr, result); + } else { + dispatch.error.call(xhr, request); + } + } + request.onprogress = function(event) { + var o = d3.event; + d3.event = event; + try { + dispatch.progress.call(xhr, request); + } finally { + d3.event = o; + } + }; + xhr.header = function(name, value) { + name = (name + "").toLowerCase(); + if (arguments.length < 2) return headers[name]; + if (value == null) delete headers[name]; else headers[name] = value + ""; + return xhr; + }; + xhr.mimeType = function(value) { + if (!arguments.length) return mimeType; + mimeType = value == null ? null : value + ""; + return xhr; + }; + xhr.responseType = function(value) { + if (!arguments.length) return responseType; + responseType = value; + return xhr; + }; + xhr.response = function(value) { + response = value; + return xhr; + }; + [ "get", "post" ].forEach(function(method) { + xhr[method] = function() { + return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments))); + }; + }); + xhr.send = function(method, data, callback) { + if (arguments.length === 2 && typeof data === "function") callback = data, data = null; + request.open(method, url, true); + if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; + if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); + if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); + if (responseType != null) request.responseType = responseType; + if (callback != null) xhr.on("error", callback).on("load", function(request) { + callback(null, request); + }); + dispatch.beforesend.call(xhr, request); + request.send(data == null ? null : data); + return xhr; + }; + xhr.abort = function() { + request.abort(); + return xhr; + }; + d3.rebind(xhr, dispatch, "on"); + return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); + } + function d3_xhr_fixCallback(callback) { + return callback.length === 1 ? function(error, request) { + callback(error == null ? request : null); + } : callback; + } + function d3_xhrHasResponse(request) { + var type = request.responseType; + return type && type !== "text" ? request.response : request.responseText; + } + d3.dsv = function(delimiter, mimeType) { + var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0); + function dsv(url, row, callback) { + if (arguments.length < 3) callback = row, row = null; + var xhr = d3_xhr(url, mimeType, row == null ? response : typedResponse(row), callback); + xhr.row = function(_) { + return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row; + }; + return xhr; + } + function response(request) { + return dsv.parse(request.responseText); + } + function typedResponse(f) { + return function(request) { + return dsv.parse(request.responseText, f); + }; + } + dsv.parse = function(text, f) { + var o; + return dsv.parseRows(text, function(row, i) { + if (o) return o(row, i - 1); + var a = new Function("d", "return {" + row.map(function(name, i) { + return JSON.stringify(name) + ": d[" + i + "]"; + }).join(",") + "}"); + o = f ? function(row, i) { + return f(a(row), i); + } : a; + }); + }; + dsv.parseRows = function(text, f) { + var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol; + function token() { + if (I >= N) return EOF; + if (eol) return eol = false, EOL; + var j = I; + if (text.charCodeAt(j) === 34) { + var i = j; + while (i++ < N) { + if (text.charCodeAt(i) === 34) { + if (text.charCodeAt(i + 1) !== 34) break; + ++i; + } + } + I = i + 2; + var c = text.charCodeAt(i + 1); + if (c === 13) { + eol = true; + if (text.charCodeAt(i + 2) === 10) ++I; + } else if (c === 10) { + eol = true; + } + return text.slice(j + 1, i).replace(/""/g, '"'); + } + while (I < N) { + var c = text.charCodeAt(I++), k = 1; + if (c === 10) eol = true; else if (c === 13) { + eol = true; + if (text.charCodeAt(I) === 10) ++I, ++k; + } else if (c !== delimiterCode) continue; + return text.slice(j, I - k); + } + return text.slice(j); + } + while ((t = token()) !== EOF) { + var a = []; + while (t !== EOL && t !== EOF) { + a.push(t); + t = token(); + } + if (f && (a = f(a, n++)) == null) continue; + rows.push(a); + } + return rows; + }; + dsv.format = function(rows) { + if (Array.isArray(rows[0])) return dsv.formatRows(rows); + var fieldSet = new d3_Set(), fields = []; + rows.forEach(function(row) { + for (var field in row) { + if (!fieldSet.has(field)) { + fields.push(fieldSet.add(field)); + } + } + }); + return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) { + return fields.map(function(field) { + return formatValue(row[field]); + }).join(delimiter); + })).join("\n"); + }; + dsv.formatRows = function(rows) { + return rows.map(formatRow).join("\n"); + }; + function formatRow(row) { + return row.map(formatValue).join(delimiter); + } + function formatValue(text) { + return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text; + } + return dsv; + }; + d3.csv = d3.dsv(",", "text/csv"); + d3.tsv = d3.dsv(" ", "text/tab-separated-values"); + var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_active, d3_timer_frame = this[d3_vendorSymbol(this, "requestAnimationFrame")] || function(callback) { + setTimeout(callback, 17); + }; + d3.timer = function(callback, delay, then) { + var n = arguments.length; + if (n < 2) delay = 0; + if (n < 3) then = Date.now(); + var time = then + delay, timer = { + c: callback, + t: time, + f: false, + n: null + }; + if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer; + d3_timer_queueTail = timer; + if (!d3_timer_interval) { + d3_timer_timeout = clearTimeout(d3_timer_timeout); + d3_timer_interval = 1; + d3_timer_frame(d3_timer_step); + } + }; + function d3_timer_step() { + var now = d3_timer_mark(), delay = d3_timer_sweep() - now; + if (delay > 24) { + if (isFinite(delay)) { + clearTimeout(d3_timer_timeout); + d3_timer_timeout = setTimeout(d3_timer_step, delay); + } + d3_timer_interval = 0; + } else { + d3_timer_interval = 1; + d3_timer_frame(d3_timer_step); + } + } + d3.timer.flush = function() { + d3_timer_mark(); + d3_timer_sweep(); + }; + function d3_timer_mark() { + var now = Date.now(); + d3_timer_active = d3_timer_queueHead; + while (d3_timer_active) { + if (now >= d3_timer_active.t) d3_timer_active.f = d3_timer_active.c(now - d3_timer_active.t); + d3_timer_active = d3_timer_active.n; + } + return now; + } + function d3_timer_sweep() { + var t0, t1 = d3_timer_queueHead, time = Infinity; + while (t1) { + if (t1.f) { + t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n; + } else { + if (t1.t < time) time = t1.t; + t1 = (t0 = t1).n; + } + } + d3_timer_queueTail = t0; + return time; + } + function d3_format_precision(x, p) { + return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1); + } + d3.round = function(x, n) { + return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x); + }; + var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix); + d3.formatPrefix = function(value, precision) { + var i = 0; + if (value) { + if (value < 0) value *= -1; + if (precision) value = d3.round(value, d3_format_precision(value, precision)); + i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); + i = Math.max(-24, Math.min(24, Math.floor((i - 1) / 3) * 3)); + } + return d3_formatPrefixes[8 + i / 3]; + }; + function d3_formatPrefix(d, i) { + var k = Math.pow(10, abs(8 - i) * 3); + return { + scale: i > 8 ? function(d) { + return d / k; + } : function(d) { + return d * k; + }, + symbol: d + }; + } + function d3_locale_numberFormat(locale) { + var locale_decimal = locale.decimal, locale_thousands = locale.thousands, locale_grouping = locale.grouping, locale_currency = locale.currency, formatGroup = locale_grouping && locale_thousands ? function(value, width) { + var i = value.length, t = [], j = 0, g = locale_grouping[0], length = 0; + while (i > 0 && g > 0) { + if (length + g + 1 > width) g = Math.max(1, width - length); + t.push(value.substring(i -= g, i + g)); + if ((length += g + 1) > width) break; + g = locale_grouping[j = (j + 1) % locale_grouping.length]; + } + return t.reverse().join(locale_thousands); + } : d3_identity; + return function(specifier) { + var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "-", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = "", suffix = "", integer = false, exponent = true; + if (precision) precision = +precision.substring(1); + if (zfill || fill === "0" && align === "=") { + zfill = fill = "0"; + align = "="; + } + switch (type) { + case "n": + comma = true; + type = "g"; + break; + + case "%": + scale = 100; + suffix = "%"; + type = "f"; + break; + + case "p": + scale = 100; + suffix = "%"; + type = "r"; + break; + + case "b": + case "o": + case "x": + case "X": + if (symbol === "#") prefix = "0" + type.toLowerCase(); + + case "c": + exponent = false; + + case "d": + integer = true; + precision = 0; + break; + + case "s": + scale = -1; + type = "r"; + break; + } + if (symbol === "$") prefix = locale_currency[0], suffix = locale_currency[1]; + if (type == "r" && !precision) type = "g"; + if (precision != null) { + if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); + } + type = d3_format_types.get(type) || d3_format_typeDefault; + var zcomma = zfill && comma; + return function(value) { + var fullSuffix = suffix; + if (integer && value % 1) return ""; + var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign === "-" ? "" : sign; + if (scale < 0) { + var unit = d3.formatPrefix(value, precision); + value = unit.scale(value); + fullSuffix = unit.symbol + suffix; + } else { + value *= scale; + } + value = type(value, precision); + var i = value.lastIndexOf("."), before, after; + if (i < 0) { + var j = exponent ? value.lastIndexOf("e") : -1; + if (j < 0) before = value, after = ""; else before = value.substring(0, j), after = value.substring(j); + } else { + before = value.substring(0, i); + after = locale_decimal + value.substring(i + 1); + } + if (!zfill && comma) before = formatGroup(before, Infinity); + var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; + if (zcomma) before = formatGroup(padding + before, padding.length ? width - after.length : Infinity); + negative += prefix; + value = before + after; + return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + fullSuffix; + }; + }; + } + var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; + var d3_format_types = d3.map({ + b: function(x) { + return x.toString(2); + }, + c: function(x) { + return String.fromCharCode(x); + }, + o: function(x) { + return x.toString(8); + }, + x: function(x) { + return x.toString(16); + }, + X: function(x) { + return x.toString(16).toUpperCase(); + }, + g: function(x, p) { + return x.toPrecision(p); + }, + e: function(x, p) { + return x.toExponential(p); + }, + f: function(x, p) { + return x.toFixed(p); + }, + r: function(x, p) { + return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); + } + }); + function d3_format_typeDefault(x) { + return x + ""; + } + var d3_time = d3.time = {}, d3_date = Date; + function d3_date_utc() { + this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]); + } + d3_date_utc.prototype = { + getDate: function() { + return this._.getUTCDate(); + }, + getDay: function() { + return this._.getUTCDay(); + }, + getFullYear: function() { + return this._.getUTCFullYear(); + }, + getHours: function() { + return this._.getUTCHours(); + }, + getMilliseconds: function() { + return this._.getUTCMilliseconds(); + }, + getMinutes: function() { + return this._.getUTCMinutes(); + }, + getMonth: function() { + return this._.getUTCMonth(); + }, + getSeconds: function() { + return this._.getUTCSeconds(); + }, + getTime: function() { + return this._.getTime(); + }, + getTimezoneOffset: function() { + return 0; + }, + valueOf: function() { + return this._.valueOf(); + }, + setDate: function() { + d3_time_prototype.setUTCDate.apply(this._, arguments); + }, + setDay: function() { + d3_time_prototype.setUTCDay.apply(this._, arguments); + }, + setFullYear: function() { + d3_time_prototype.setUTCFullYear.apply(this._, arguments); + }, + setHours: function() { + d3_time_prototype.setUTCHours.apply(this._, arguments); + }, + setMilliseconds: function() { + d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); + }, + setMinutes: function() { + d3_time_prototype.setUTCMinutes.apply(this._, arguments); + }, + setMonth: function() { + d3_time_prototype.setUTCMonth.apply(this._, arguments); + }, + setSeconds: function() { + d3_time_prototype.setUTCSeconds.apply(this._, arguments); + }, + setTime: function() { + d3_time_prototype.setTime.apply(this._, arguments); + } + }; + var d3_time_prototype = Date.prototype; + function d3_time_interval(local, step, number) { + function round(date) { + var d0 = local(date), d1 = offset(d0, 1); + return date - d0 < d1 - date ? d0 : d1; + } + function ceil(date) { + step(date = local(new d3_date(date - 1)), 1); + return date; + } + function offset(date, k) { + step(date = new d3_date(+date), k); + return date; + } + function range(t0, t1, dt) { + var time = ceil(t0), times = []; + if (dt > 1) { + while (time < t1) { + if (!(number(time) % dt)) times.push(new Date(+time)); + step(time, 1); + } + } else { + while (time < t1) times.push(new Date(+time)), step(time, 1); + } + return times; + } + function range_utc(t0, t1, dt) { + try { + d3_date = d3_date_utc; + var utc = new d3_date_utc(); + utc._ = t0; + return range(utc, t1, dt); + } finally { + d3_date = Date; + } + } + local.floor = local; + local.round = round; + local.ceil = ceil; + local.offset = offset; + local.range = range; + var utc = local.utc = d3_time_interval_utc(local); + utc.floor = utc; + utc.round = d3_time_interval_utc(round); + utc.ceil = d3_time_interval_utc(ceil); + utc.offset = d3_time_interval_utc(offset); + utc.range = range_utc; + return local; + } + function d3_time_interval_utc(method) { + return function(date, k) { + try { + d3_date = d3_date_utc; + var utc = new d3_date_utc(); + utc._ = date; + return method(utc, k)._; + } finally { + d3_date = Date; + } + }; + } + d3_time.year = d3_time_interval(function(date) { + date = d3_time.day(date); + date.setMonth(0, 1); + return date; + }, function(date, offset) { + date.setFullYear(date.getFullYear() + offset); + }, function(date) { + return date.getFullYear(); + }); + d3_time.years = d3_time.year.range; + d3_time.years.utc = d3_time.year.utc.range; + d3_time.day = d3_time_interval(function(date) { + var day = new d3_date(2e3, 0); + day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); + return day; + }, function(date, offset) { + date.setDate(date.getDate() + offset); + }, function(date) { + return date.getDate() - 1; + }); + d3_time.days = d3_time.day.range; + d3_time.days.utc = d3_time.day.utc.range; + d3_time.dayOfYear = function(date) { + var year = d3_time.year(date); + return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); + }; + [ "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ].forEach(function(day, i) { + i = 7 - i; + var interval = d3_time[day] = d3_time_interval(function(date) { + (date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); + return date; + }, function(date, offset) { + date.setDate(date.getDate() + Math.floor(offset) * 7); + }, function(date) { + var day = d3_time.year(date).getDay(); + return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); + }); + d3_time[day + "s"] = interval.range; + d3_time[day + "s"].utc = interval.utc.range; + d3_time[day + "OfYear"] = function(date) { + var day = d3_time.year(date).getDay(); + return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7); + }; + }); + d3_time.week = d3_time.sunday; + d3_time.weeks = d3_time.sunday.range; + d3_time.weeks.utc = d3_time.sunday.utc.range; + d3_time.weekOfYear = d3_time.sundayOfYear; + function d3_locale_timeFormat(locale) { + var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_days = locale.days, locale_shortDays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths; + function d3_time_format(template) { + var n = template.length; + function format(date) { + var string = [], i = -1, j = 0, c, p, f; + while (++i < n) { + if (template.charCodeAt(i) === 37) { + string.push(template.slice(j, i)); + if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); + if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p); + string.push(c); + j = i + 1; + } + } + string.push(template.slice(j, i)); + return string.join(""); + } + format.parse = function(string) { + var d = { + y: 1900, + m: 0, + d: 1, + H: 0, + M: 0, + S: 0, + L: 0, + Z: null + }, i = d3_time_parse(d, template, string, 0); + if (i != string.length) return null; + if ("p" in d) d.H = d.H % 12 + d.p * 12; + var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)(); + if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) { + date.setFullYear(d.y, 0, 1); + date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7); + } else date.setFullYear(d.y, d.m, d.d); + date.setHours(d.H + (d.Z / 100 | 0), d.M + d.Z % 100, d.S, d.L); + return localZ ? date._ : date; + }; + format.toString = function() { + return template; + }; + return format; + } + function d3_time_parse(date, template, string, j) { + var c, p, t, i = 0, n = template.length, m = string.length; + while (i < n) { + if (j >= m) return -1; + c = template.charCodeAt(i++); + if (c === 37) { + t = template.charAt(i++); + p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t]; + if (!p || (j = p(date, string, j)) < 0) return -1; + } else if (c != string.charCodeAt(j++)) { + return -1; + } + } + return j; + } + d3_time_format.utc = function(template) { + var local = d3_time_format(template); + function format(date) { + try { + d3_date = d3_date_utc; + var utc = new d3_date(); + utc._ = date; + return local(utc); + } finally { + d3_date = Date; + } + } + format.parse = function(string) { + try { + d3_date = d3_date_utc; + var date = local.parse(string); + return date && date._; + } finally { + d3_date = Date; + } + }; + format.toString = local.toString; + return format; + }; + d3_time_format.multi = d3_time_format.utc.multi = d3_time_formatMulti; + var d3_time_periodLookup = d3.map(), d3_time_dayRe = d3_time_formatRe(locale_days), d3_time_dayLookup = d3_time_formatLookup(locale_days), d3_time_dayAbbrevRe = d3_time_formatRe(locale_shortDays), d3_time_dayAbbrevLookup = d3_time_formatLookup(locale_shortDays), d3_time_monthRe = d3_time_formatRe(locale_months), d3_time_monthLookup = d3_time_formatLookup(locale_months), d3_time_monthAbbrevRe = d3_time_formatRe(locale_shortMonths), d3_time_monthAbbrevLookup = d3_time_formatLookup(locale_shortMonths); + locale_periods.forEach(function(p, i) { + d3_time_periodLookup.set(p.toLowerCase(), i); + }); + var d3_time_formats = { + a: function(d) { + return locale_shortDays[d.getDay()]; + }, + A: function(d) { + return locale_days[d.getDay()]; + }, + b: function(d) { + return locale_shortMonths[d.getMonth()]; + }, + B: function(d) { + return locale_months[d.getMonth()]; + }, + c: d3_time_format(locale_dateTime), + d: function(d, p) { + return d3_time_formatPad(d.getDate(), p, 2); + }, + e: function(d, p) { + return d3_time_formatPad(d.getDate(), p, 2); + }, + H: function(d, p) { + return d3_time_formatPad(d.getHours(), p, 2); + }, + I: function(d, p) { + return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); + }, + j: function(d, p) { + return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3); + }, + L: function(d, p) { + return d3_time_formatPad(d.getMilliseconds(), p, 3); + }, + m: function(d, p) { + return d3_time_formatPad(d.getMonth() + 1, p, 2); + }, + M: function(d, p) { + return d3_time_formatPad(d.getMinutes(), p, 2); + }, + p: function(d) { + return locale_periods[+(d.getHours() >= 12)]; + }, + S: function(d, p) { + return d3_time_formatPad(d.getSeconds(), p, 2); + }, + U: function(d, p) { + return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2); + }, + w: function(d) { + return d.getDay(); + }, + W: function(d, p) { + return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2); + }, + x: d3_time_format(locale_date), + X: d3_time_format(locale_time), + y: function(d, p) { + return d3_time_formatPad(d.getFullYear() % 100, p, 2); + }, + Y: function(d, p) { + return d3_time_formatPad(d.getFullYear() % 1e4, p, 4); + }, + Z: d3_time_zone, + "%": function() { + return "%"; + } + }; + var d3_time_parsers = { + a: d3_time_parseWeekdayAbbrev, + A: d3_time_parseWeekday, + b: d3_time_parseMonthAbbrev, + B: d3_time_parseMonth, + c: d3_time_parseLocaleFull, + d: d3_time_parseDay, + e: d3_time_parseDay, + H: d3_time_parseHour24, + I: d3_time_parseHour24, + j: d3_time_parseDayOfYear, + L: d3_time_parseMilliseconds, + m: d3_time_parseMonthNumber, + M: d3_time_parseMinutes, + p: d3_time_parseAmPm, + S: d3_time_parseSeconds, + U: d3_time_parseWeekNumberSunday, + w: d3_time_parseWeekdayNumber, + W: d3_time_parseWeekNumberMonday, + x: d3_time_parseLocaleDate, + X: d3_time_parseLocaleTime, + y: d3_time_parseYear, + Y: d3_time_parseFullYear, + Z: d3_time_parseZone, + "%": d3_time_parseLiteralPercent + }; + function d3_time_parseWeekdayAbbrev(date, string, i) { + d3_time_dayAbbrevRe.lastIndex = 0; + var n = d3_time_dayAbbrevRe.exec(string.slice(i)); + return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; + } + function d3_time_parseWeekday(date, string, i) { + d3_time_dayRe.lastIndex = 0; + var n = d3_time_dayRe.exec(string.slice(i)); + return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; + } + function d3_time_parseMonthAbbrev(date, string, i) { + d3_time_monthAbbrevRe.lastIndex = 0; + var n = d3_time_monthAbbrevRe.exec(string.slice(i)); + return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; + } + function d3_time_parseMonth(date, string, i) { + d3_time_monthRe.lastIndex = 0; + var n = d3_time_monthRe.exec(string.slice(i)); + return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; + } + function d3_time_parseLocaleFull(date, string, i) { + return d3_time_parse(date, d3_time_formats.c.toString(), string, i); + } + function d3_time_parseLocaleDate(date, string, i) { + return d3_time_parse(date, d3_time_formats.x.toString(), string, i); + } + function d3_time_parseLocaleTime(date, string, i) { + return d3_time_parse(date, d3_time_formats.X.toString(), string, i); + } + function d3_time_parseAmPm(date, string, i) { + var n = d3_time_periodLookup.get(string.slice(i, i += 2).toLowerCase()); + return n == null ? -1 : (date.p = n, i); + } + return d3_time_format; + } + var d3_time_formatPads = { + "-": "", + _: " ", + "0": "0" + }, d3_time_numberRe = /^\s*\d+/, d3_time_percentRe = /^%/; + function d3_time_formatPad(value, fill, width) { + var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length; + return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); + } + function d3_time_formatRe(names) { + return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); + } + function d3_time_formatLookup(names) { + var map = new d3_Map(), i = -1, n = names.length; + while (++i < n) map.set(names[i].toLowerCase(), i); + return map; + } + function d3_time_parseWeekdayNumber(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.slice(i, i + 1)); + return n ? (date.w = +n[0], i + n[0].length) : -1; + } + function d3_time_parseWeekNumberSunday(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.slice(i)); + return n ? (date.U = +n[0], i + n[0].length) : -1; + } + function d3_time_parseWeekNumberMonday(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.slice(i)); + return n ? (date.W = +n[0], i + n[0].length) : -1; + } + function d3_time_parseFullYear(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.slice(i, i + 4)); + return n ? (date.y = +n[0], i + n[0].length) : -1; + } + function d3_time_parseYear(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.slice(i, i + 2)); + return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1; + } + function d3_time_parseZone(date, string, i) { + return /^[+-]\d{4}$/.test(string = string.slice(i, i + 5)) ? (date.Z = -string, + i + 5) : -1; + } + function d3_time_expandYear(d) { + return d + (d > 68 ? 1900 : 2e3); + } + function d3_time_parseMonthNumber(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.slice(i, i + 2)); + return n ? (date.m = n[0] - 1, i + n[0].length) : -1; + } + function d3_time_parseDay(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.slice(i, i + 2)); + return n ? (date.d = +n[0], i + n[0].length) : -1; + } + function d3_time_parseDayOfYear(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.slice(i, i + 3)); + return n ? (date.j = +n[0], i + n[0].length) : -1; + } + function d3_time_parseHour24(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.slice(i, i + 2)); + return n ? (date.H = +n[0], i + n[0].length) : -1; + } + function d3_time_parseMinutes(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.slice(i, i + 2)); + return n ? (date.M = +n[0], i + n[0].length) : -1; + } + function d3_time_parseSeconds(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.slice(i, i + 2)); + return n ? (date.S = +n[0], i + n[0].length) : -1; + } + function d3_time_parseMilliseconds(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.slice(i, i + 3)); + return n ? (date.L = +n[0], i + n[0].length) : -1; + } + function d3_time_zone(d) { + var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = abs(z) / 60 | 0, zm = abs(z) % 60; + return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); + } + function d3_time_parseLiteralPercent(date, string, i) { + d3_time_percentRe.lastIndex = 0; + var n = d3_time_percentRe.exec(string.slice(i, i + 1)); + return n ? i + n[0].length : -1; + } + function d3_time_formatMulti(formats) { + var n = formats.length, i = -1; + while (++i < n) formats[i][0] = this(formats[i][0]); + return function(date) { + var i = 0, f = formats[i]; + while (!f[1](date)) f = formats[++i]; + return f[0](date); + }; + } + d3.locale = function(locale) { + return { + numberFormat: d3_locale_numberFormat(locale), + timeFormat: d3_locale_timeFormat(locale) + }; + }; + var d3_locale_enUS = d3.locale({ + decimal: ".", + thousands: ",", + grouping: [ 3 ], + currency: [ "$", "" ], + dateTime: "%a %b %e %X %Y", + date: "%m/%d/%Y", + time: "%H:%M:%S", + periods: [ "AM", "PM" ], + days: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], + shortDays: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], + months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], + shortMonths: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] + }); + d3.format = d3_locale_enUS.numberFormat; + d3.geo = {}; + function d3_adder() {} + d3_adder.prototype = { + s: 0, + t: 0, + add: function(y) { + d3_adderSum(y, this.t, d3_adderTemp); + d3_adderSum(d3_adderTemp.s, this.s, this); + if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t; + }, + reset: function() { + this.s = this.t = 0; + }, + valueOf: function() { + return this.s; + } + }; + var d3_adderTemp = new d3_adder(); + function d3_adderSum(a, b, o) { + var x = o.s = a + b, bv = x - a, av = x - bv; + o.t = a - av + (b - bv); + } + d3.geo.stream = function(object, listener) { + if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) { + d3_geo_streamObjectType[object.type](object, listener); + } else { + d3_geo_streamGeometry(object, listener); + } + }; + function d3_geo_streamGeometry(geometry, listener) { + if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { + d3_geo_streamGeometryType[geometry.type](geometry, listener); + } + } + var d3_geo_streamObjectType = { + Feature: function(feature, listener) { + d3_geo_streamGeometry(feature.geometry, listener); + }, + FeatureCollection: function(object, listener) { + var features = object.features, i = -1, n = features.length; + while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); + } + }; + var d3_geo_streamGeometryType = { + Sphere: function(object, listener) { + listener.sphere(); + }, + Point: function(object, listener) { + object = object.coordinates; + listener.point(object[0], object[1], object[2]); + }, + MultiPoint: function(object, listener) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]); + }, + LineString: function(object, listener) { + d3_geo_streamLine(object.coordinates, listener, 0); + }, + MultiLineString: function(object, listener) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); + }, + Polygon: function(object, listener) { + d3_geo_streamPolygon(object.coordinates, listener); + }, + MultiPolygon: function(object, listener) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); + }, + GeometryCollection: function(object, listener) { + var geometries = object.geometries, i = -1, n = geometries.length; + while (++i < n) d3_geo_streamGeometry(geometries[i], listener); + } + }; + function d3_geo_streamLine(coordinates, listener, closed) { + var i = -1, n = coordinates.length - closed, coordinate; + listener.lineStart(); + while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]); + listener.lineEnd(); + } + function d3_geo_streamPolygon(coordinates, listener) { + var i = -1, n = coordinates.length; + listener.polygonStart(); + while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); + listener.polygonEnd(); + } + d3.geo.area = function(object) { + d3_geo_areaSum = 0; + d3.geo.stream(object, d3_geo_area); + return d3_geo_areaSum; + }; + var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder(); + var d3_geo_area = { + sphere: function() { + d3_geo_areaSum += 4 * π; + }, + point: d3_noop, + lineStart: d3_noop, + lineEnd: d3_noop, + polygonStart: function() { + d3_geo_areaRingSum.reset(); + d3_geo_area.lineStart = d3_geo_areaRingStart; + }, + polygonEnd: function() { + var area = 2 * d3_geo_areaRingSum; + d3_geo_areaSum += area < 0 ? 4 * π + area : area; + d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; + } + }; + function d3_geo_areaRingStart() { + var λ00, φ00, λ0, cosφ0, sinφ0; + d3_geo_area.point = function(λ, φ) { + d3_geo_area.point = nextPoint; + λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4), + sinφ0 = Math.sin(φ); + }; + function nextPoint(λ, φ) { + λ *= d3_radians; + φ = φ * d3_radians / 2 + π / 4; + var dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(adλ), v = k * sdλ * Math.sin(adλ); + d3_geo_areaRingSum.add(Math.atan2(v, u)); + λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ; + } + d3_geo_area.lineEnd = function() { + nextPoint(λ00, φ00); + }; + } + function d3_geo_cartesian(spherical) { + var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ); + return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ]; + } + function d3_geo_cartesianDot(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + } + function d3_geo_cartesianCross(a, b) { + return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; + } + function d3_geo_cartesianAdd(a, b) { + a[0] += b[0]; + a[1] += b[1]; + a[2] += b[2]; + } + function d3_geo_cartesianScale(vector, k) { + return [ vector[0] * k, vector[1] * k, vector[2] * k ]; + } + function d3_geo_cartesianNormalize(d) { + var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); + d[0] /= l; + d[1] /= l; + d[2] /= l; + } + function d3_geo_spherical(cartesian) { + return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ]; + } + function d3_geo_sphericalEqual(a, b) { + return abs(a[0] - b[0]) < ε && abs(a[1] - b[1]) < ε; + } + d3.geo.bounds = function() { + var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range; + var bound = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + bound.point = ringPoint; + bound.lineStart = ringStart; + bound.lineEnd = ringEnd; + dλSum = 0; + d3_geo_area.polygonStart(); + }, + polygonEnd: function() { + d3_geo_area.polygonEnd(); + bound.point = point; + bound.lineStart = lineStart; + bound.lineEnd = lineEnd; + if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90; + range[0] = λ0, range[1] = λ1; + } + }; + function point(λ, φ) { + ranges.push(range = [ λ0 = λ, λ1 = λ ]); + if (φ < φ0) φ0 = φ; + if (φ > φ1) φ1 = φ; + } + function linePoint(λ, φ) { + var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]); + if (p0) { + var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal); + d3_geo_cartesianNormalize(inflection); + inflection = d3_geo_spherical(inflection); + var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = abs(dλ) > 180; + if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) { + var φi = inflection[1] * d3_degrees; + if (φi > φ1) φ1 = φi; + } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) { + var φi = -inflection[1] * d3_degrees; + if (φi < φ0) φ0 = φi; + } else { + if (φ < φ0) φ0 = φ; + if (φ > φ1) φ1 = φ; + } + if (antimeridian) { + if (λ < λ_) { + if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; + } else { + if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; + } + } else { + if (λ1 >= λ0) { + if (λ < λ0) λ0 = λ; + if (λ > λ1) λ1 = λ; + } else { + if (λ > λ_) { + if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; + } else { + if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; + } + } + } + } else { + point(λ, φ); + } + p0 = p, λ_ = λ; + } + function lineStart() { + bound.point = linePoint; + } + function lineEnd() { + range[0] = λ0, range[1] = λ1; + bound.point = point; + p0 = null; + } + function ringPoint(λ, φ) { + if (p0) { + var dλ = λ - λ_; + dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ; + } else λ__ = λ, φ__ = φ; + d3_geo_area.point(λ, φ); + linePoint(λ, φ); + } + function ringStart() { + d3_geo_area.lineStart(); + } + function ringEnd() { + ringPoint(λ__, φ__); + d3_geo_area.lineEnd(); + if (abs(dλSum) > ε) λ0 = -(λ1 = 180); + range[0] = λ0, range[1] = λ1; + p0 = null; + } + function angle(λ0, λ1) { + return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; + } + function compareRanges(a, b) { + return a[0] - b[0]; + } + function withinRange(x, range) { + return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; + } + return function(feature) { + φ1 = λ1 = -(λ0 = φ0 = Infinity); + ranges = []; + d3.geo.stream(feature, bound); + var n = ranges.length; + if (n) { + ranges.sort(compareRanges); + for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) { + b = ranges[i]; + if (withinRange(b[0], a) || withinRange(b[1], a)) { + if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; + if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; + } else { + merged.push(a = b); + } + } + var best = -Infinity, dλ; + for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) { + b = merged[i]; + if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1]; + } + } + ranges = range = null; + return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ]; + }; + }(); + d3.geo.centroid = function(object) { + d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; + d3.geo.stream(object, d3_geo_centroid); + var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z; + if (m < ε2) { + x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1; + if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0; + m = x * x + y * y + z * z; + if (m < ε2) return [ NaN, NaN ]; + } + return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ]; + }; + var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2; + var d3_geo_centroid = { + sphere: d3_noop, + point: d3_geo_centroidPoint, + lineStart: d3_geo_centroidLineStart, + lineEnd: d3_geo_centroidLineEnd, + polygonStart: function() { + d3_geo_centroid.lineStart = d3_geo_centroidRingStart; + }, + polygonEnd: function() { + d3_geo_centroid.lineStart = d3_geo_centroidLineStart; + } + }; + function d3_geo_centroidPoint(λ, φ) { + λ *= d3_radians; + var cosφ = Math.cos(φ *= d3_radians); + d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ)); + } + function d3_geo_centroidPointXYZ(x, y, z) { + ++d3_geo_centroidW0; + d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0; + d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0; + d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0; + } + function d3_geo_centroidLineStart() { + var x0, y0, z0; + d3_geo_centroid.point = function(λ, φ) { + λ *= d3_radians; + var cosφ = Math.cos(φ *= d3_radians); + x0 = cosφ * Math.cos(λ); + y0 = cosφ * Math.sin(λ); + z0 = Math.sin(φ); + d3_geo_centroid.point = nextPoint; + d3_geo_centroidPointXYZ(x0, y0, z0); + }; + function nextPoint(λ, φ) { + λ *= d3_radians; + var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); + d3_geo_centroidW1 += w; + d3_geo_centroidX1 += w * (x0 + (x0 = x)); + d3_geo_centroidY1 += w * (y0 + (y0 = y)); + d3_geo_centroidZ1 += w * (z0 + (z0 = z)); + d3_geo_centroidPointXYZ(x0, y0, z0); + } + } + function d3_geo_centroidLineEnd() { + d3_geo_centroid.point = d3_geo_centroidPoint; + } + function d3_geo_centroidRingStart() { + var λ00, φ00, x0, y0, z0; + d3_geo_centroid.point = function(λ, φ) { + λ00 = λ, φ00 = φ; + d3_geo_centroid.point = nextPoint; + λ *= d3_radians; + var cosφ = Math.cos(φ *= d3_radians); + x0 = cosφ * Math.cos(λ); + y0 = cosφ * Math.sin(λ); + z0 = Math.sin(φ); + d3_geo_centroidPointXYZ(x0, y0, z0); + }; + d3_geo_centroid.lineEnd = function() { + nextPoint(λ00, φ00); + d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; + d3_geo_centroid.point = d3_geo_centroidPoint; + }; + function nextPoint(λ, φ) { + λ *= d3_radians; + var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u); + d3_geo_centroidX2 += v * cx; + d3_geo_centroidY2 += v * cy; + d3_geo_centroidZ2 += v * cz; + d3_geo_centroidW1 += w; + d3_geo_centroidX1 += w * (x0 + (x0 = x)); + d3_geo_centroidY1 += w * (y0 + (y0 = y)); + d3_geo_centroidZ1 += w * (z0 + (z0 = z)); + d3_geo_centroidPointXYZ(x0, y0, z0); + } + } + function d3_geo_compose(a, b) { + function compose(x, y) { + return x = a(x, y), b(x[0], x[1]); + } + if (a.invert && b.invert) compose.invert = function(x, y) { + return x = b.invert(x, y), x && a.invert(x[0], x[1]); + }; + return compose; + } + function d3_true() { + return true; + } + function d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener) { + var subject = [], clip = []; + segments.forEach(function(segment) { + if ((n = segment.length - 1) <= 0) return; + var n, p0 = segment[0], p1 = segment[n]; + if (d3_geo_sphericalEqual(p0, p1)) { + listener.lineStart(); + for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]); + listener.lineEnd(); + return; + } + var a = new d3_geo_clipPolygonIntersection(p0, segment, null, true), b = new d3_geo_clipPolygonIntersection(p0, null, a, false); + a.o = b; + subject.push(a); + clip.push(b); + a = new d3_geo_clipPolygonIntersection(p1, segment, null, false); + b = new d3_geo_clipPolygonIntersection(p1, null, a, true); + a.o = b; + subject.push(a); + clip.push(b); + }); + clip.sort(compare); + d3_geo_clipPolygonLinkCircular(subject); + d3_geo_clipPolygonLinkCircular(clip); + if (!subject.length) return; + for (var i = 0, entry = clipStartInside, n = clip.length; i < n; ++i) { + clip[i].e = entry = !entry; + } + var start = subject[0], points, point; + while (1) { + var current = start, isSubject = true; + while (current.v) if ((current = current.n) === start) return; + points = current.z; + listener.lineStart(); + do { + current.v = current.o.v = true; + if (current.e) { + if (isSubject) { + for (var i = 0, n = points.length; i < n; ++i) listener.point((point = points[i])[0], point[1]); + } else { + interpolate(current.x, current.n.x, 1, listener); + } + current = current.n; + } else { + if (isSubject) { + points = current.p.z; + for (var i = points.length - 1; i >= 0; --i) listener.point((point = points[i])[0], point[1]); + } else { + interpolate(current.x, current.p.x, -1, listener); + } + current = current.p; + } + current = current.o; + points = current.z; + isSubject = !isSubject; + } while (!current.v); + listener.lineEnd(); + } + } + function d3_geo_clipPolygonLinkCircular(array) { + if (!(n = array.length)) return; + var n, i = 0, a = array[0], b; + while (++i < n) { + a.n = b = array[i]; + b.p = a; + a = b; + } + a.n = b = array[0]; + b.p = a; + } + function d3_geo_clipPolygonIntersection(point, points, other, entry) { + this.x = point; + this.z = points; + this.o = other; + this.e = entry; + this.v = false; + this.n = this.p = null; + } + function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) { + return function(rotate, listener) { + var line = clipLine(listener), rotatedClipStart = rotate.invert(clipStart[0], clipStart[1]); + var clip = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + clip.point = pointRing; + clip.lineStart = ringStart; + clip.lineEnd = ringEnd; + segments = []; + polygon = []; + }, + polygonEnd: function() { + clip.point = point; + clip.lineStart = lineStart; + clip.lineEnd = lineEnd; + segments = d3.merge(segments); + var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon); + if (segments.length) { + if (!polygonStarted) listener.polygonStart(), polygonStarted = true; + d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener); + } else if (clipStartInside) { + if (!polygonStarted) listener.polygonStart(), polygonStarted = true; + listener.lineStart(); + interpolate(null, null, 1, listener); + listener.lineEnd(); + } + if (polygonStarted) listener.polygonEnd(), polygonStarted = false; + segments = polygon = null; + }, + sphere: function() { + listener.polygonStart(); + listener.lineStart(); + interpolate(null, null, 1, listener); + listener.lineEnd(); + listener.polygonEnd(); + } + }; + function point(λ, φ) { + var point = rotate(λ, φ); + if (pointVisible(λ = point[0], φ = point[1])) listener.point(λ, φ); + } + function pointLine(λ, φ) { + var point = rotate(λ, φ); + line.point(point[0], point[1]); + } + function lineStart() { + clip.point = pointLine; + line.lineStart(); + } + function lineEnd() { + clip.point = point; + line.lineEnd(); + } + var segments; + var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygonStarted = false, polygon, ring; + function pointRing(λ, φ) { + ring.push([ λ, φ ]); + var point = rotate(λ, φ); + ringListener.point(point[0], point[1]); + } + function ringStart() { + ringListener.lineStart(); + ring = []; + } + function ringEnd() { + pointRing(ring[0][0], ring[0][1]); + ringListener.lineEnd(); + var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length; + ring.pop(); + polygon.push(ring); + ring = null; + if (!n) return; + if (clean & 1) { + segment = ringSegments[0]; + var n = segment.length - 1, i = -1, point; + if (n > 0) { + if (!polygonStarted) listener.polygonStart(), polygonStarted = true; + listener.lineStart(); + while (++i < n) listener.point((point = segment[i])[0], point[1]); + listener.lineEnd(); + } + return; + } + if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); + segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); + } + return clip; + }; + } + function d3_geo_clipSegmentLength1(segment) { + return segment.length > 1; + } + function d3_geo_clipBufferListener() { + var lines = [], line; + return { + lineStart: function() { + lines.push(line = []); + }, + point: function(λ, φ) { + line.push([ λ, φ ]); + }, + lineEnd: d3_noop, + buffer: function() { + var buffer = lines; + lines = []; + line = null; + return buffer; + }, + rejoin: function() { + if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); + } + }; + } + function d3_geo_clipSort(a, b) { + return ((a = a.x)[0] < 0 ? a[1] - halfπ - ε : halfπ - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfπ - ε : halfπ - b[1]); + } + var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, [ -π, -π / 2 ]); + function d3_geo_clipAntimeridianLine(listener) { + var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; + return { + lineStart: function() { + listener.lineStart(); + clean = 1; + }, + point: function(λ1, φ1) { + var sλ1 = λ1 > 0 ? π : -π, dλ = abs(λ1 - λ0); + if (abs(dλ - π) < ε) { + listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? halfπ : -halfπ); + listener.point(sλ0, φ0); + listener.lineEnd(); + listener.lineStart(); + listener.point(sλ1, φ0); + listener.point(λ1, φ0); + clean = 0; + } else if (sλ0 !== sλ1 && dλ >= π) { + if (abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; + if (abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; + φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); + listener.point(sλ0, φ0); + listener.lineEnd(); + listener.lineStart(); + listener.point(sλ1, φ0); + clean = 0; + } + listener.point(λ0 = λ1, φ0 = φ1); + sλ0 = sλ1; + }, + lineEnd: function() { + listener.lineEnd(); + λ0 = φ0 = NaN; + }, + clean: function() { + return 2 - clean; + } + }; + } + function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { + var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); + return abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2; + } + function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { + var φ; + if (from == null) { + φ = direction * halfπ; + listener.point(-π, φ); + listener.point(0, φ); + listener.point(π, φ); + listener.point(π, 0); + listener.point(π, -φ); + listener.point(0, -φ); + listener.point(-π, -φ); + listener.point(-π, 0); + listener.point(-π, φ); + } else if (abs(from[0] - to[0]) > ε) { + var s = from[0] < to[0] ? π : -π; + φ = direction * s / 2; + listener.point(-s, φ); + listener.point(0, φ); + listener.point(s, φ); + } else { + listener.point(to[0], to[1]); + } + } + function d3_geo_pointInPolygon(point, polygon) { + var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0; + d3_geo_areaRingSum.reset(); + for (var i = 0, n = polygon.length; i < n; ++i) { + var ring = polygon[i], m = ring.length; + if (!m) continue; + var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + π / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1; + while (true) { + if (j === m) j = 0; + point = ring[j]; + var λ = point[0], φ = point[1] / 2 + π / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, antimeridian = adλ > π, k = sinφ0 * sinφ; + d3_geo_areaRingSum.add(Math.atan2(k * sdλ * Math.sin(adλ), cosφ0 * cosφ + k * Math.cos(adλ))); + polarAngle += antimeridian ? dλ + sdλ * τ : dλ; + if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) { + var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point)); + d3_geo_cartesianNormalize(arc); + var intersection = d3_geo_cartesianCross(meridianNormal, arc); + d3_geo_cartesianNormalize(intersection); + var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]); + if (parallel > φarc || parallel === φarc && (arc[0] || arc[1])) { + winding += antimeridian ^ dλ >= 0 ? 1 : -1; + } + } + if (!j++) break; + λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point; + } + } + return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1; + } + function d3_geo_clipCircle(radius) { + var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians); + return d3_geo_clip(visible, clipLine, interpolate, smallRadius ? [ 0, -radius ] : [ -π, radius - π ]); + function visible(λ, φ) { + return Math.cos(λ) * Math.cos(φ) > cr; + } + function clipLine(listener) { + var point0, c0, v0, v00, clean; + return { + lineStart: function() { + v00 = v0 = false; + clean = 1; + }, + point: function(λ, φ) { + var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? π : -π), φ) : 0; + if (!point0 && (v00 = v0 = v)) listener.lineStart(); + if (v !== v0) { + point2 = intersect(point0, point1); + if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { + point1[0] += ε; + point1[1] += ε; + v = visible(point1[0], point1[1]); + } + } + if (v !== v0) { + clean = 0; + if (v) { + listener.lineStart(); + point2 = intersect(point1, point0); + listener.point(point2[0], point2[1]); + } else { + point2 = intersect(point0, point1); + listener.point(point2[0], point2[1]); + listener.lineEnd(); + } + point0 = point2; + } else if (notHemisphere && point0 && smallRadius ^ v) { + var t; + if (!(c & c0) && (t = intersect(point1, point0, true))) { + clean = 0; + if (smallRadius) { + listener.lineStart(); + listener.point(t[0][0], t[0][1]); + listener.point(t[1][0], t[1][1]); + listener.lineEnd(); + } else { + listener.point(t[1][0], t[1][1]); + listener.lineEnd(); + listener.lineStart(); + listener.point(t[0][0], t[0][1]); + } + } + } + if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) { + listener.point(point1[0], point1[1]); + } + point0 = point1, v0 = v, c0 = c; + }, + lineEnd: function() { + if (v0) listener.lineEnd(); + point0 = null; + }, + clean: function() { + return clean | (v00 && v0) << 1; + } + }; + } + function intersect(a, b, two) { + var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b); + var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2; + if (!determinant) return !two && a; + var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2); + d3_geo_cartesianAdd(A, B); + var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1); + if (t2 < 0) return; + var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu); + d3_geo_cartesianAdd(q, A); + q = d3_geo_spherical(q); + if (!two) return q; + var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z; + if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z; + var δλ = λ1 - λ0, polar = abs(δλ - π) < ε, meridian = polar || δλ < ε; + if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z; + if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) { + var q1 = d3_geo_cartesianScale(u, (-w + t) / uu); + d3_geo_cartesianAdd(q1, A); + return [ q, d3_geo_spherical(q1) ]; + } + } + function code(λ, φ) { + var r = smallRadius ? radius : π - radius, code = 0; + if (λ < -r) code |= 1; else if (λ > r) code |= 2; + if (φ < -r) code |= 4; else if (φ > r) code |= 8; + return code; + } + } + function d3_geom_clipLine(x0, y0, x1, y1) { + return function(line) { + var a = line.a, b = line.b, ax = a.x, ay = a.y, bx = b.x, by = b.y, t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r; + r = x0 - ax; + if (!dx && r > 0) return; + r /= dx; + if (dx < 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } else if (dx > 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } + r = x1 - ax; + if (!dx && r < 0) return; + r /= dx; + if (dx < 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } else if (dx > 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } + r = y0 - ay; + if (!dy && r > 0) return; + r /= dy; + if (dy < 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } else if (dy > 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } + r = y1 - ay; + if (!dy && r < 0) return; + r /= dy; + if (dy < 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } else if (dy > 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } + if (t0 > 0) line.a = { + x: ax + t0 * dx, + y: ay + t0 * dy + }; + if (t1 < 1) line.b = { + x: ax + t1 * dx, + y: ay + t1 * dy + }; + return line; + }; + } + var d3_geo_clipExtentMAX = 1e9; + d3.geo.clipExtent = function() { + var x0, y0, x1, y1, stream, clip, clipExtent = { + stream: function(output) { + if (stream) stream.valid = false; + stream = clip(output); + stream.valid = true; + return stream; + }, + extent: function(_) { + if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; + clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]); + if (stream) stream.valid = false, stream = null; + return clipExtent; + } + }; + return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]); + }; + function d3_geo_clipExtent(x0, y0, x1, y1) { + return function(listener) { + var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), clipLine = d3_geom_clipLine(x0, y0, x1, y1), segments, polygon, ring; + var clip = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + listener = bufferListener; + segments = []; + polygon = []; + clean = true; + }, + polygonEnd: function() { + listener = listener_; + segments = d3.merge(segments); + var clipStartInside = insidePolygon([ x0, y1 ]), inside = clean && clipStartInside, visible = segments.length; + if (inside || visible) { + listener.polygonStart(); + if (inside) { + listener.lineStart(); + interpolate(null, null, 1, listener); + listener.lineEnd(); + } + if (visible) { + d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener); + } + listener.polygonEnd(); + } + segments = polygon = ring = null; + } + }; + function insidePolygon(p) { + var wn = 0, n = polygon.length, y = p[1]; + for (var i = 0; i < n; ++i) { + for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { + b = v[j]; + if (a[1] <= y) { + if (b[1] > y && d3_cross2d(a, b, p) > 0) ++wn; + } else { + if (b[1] <= y && d3_cross2d(a, b, p) < 0) --wn; + } + a = b; + } + } + return wn !== 0; + } + function interpolate(from, to, direction, listener) { + var a = 0, a1 = 0; + if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) { + do { + listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); + } while ((a = (a + direction + 4) % 4) !== a1); + } else { + listener.point(to[0], to[1]); + } + } + function pointVisible(x, y) { + return x0 <= x && x <= x1 && y0 <= y && y <= y1; + } + function point(x, y) { + if (pointVisible(x, y)) listener.point(x, y); + } + var x__, y__, v__, x_, y_, v_, first, clean; + function lineStart() { + clip.point = linePoint; + if (polygon) polygon.push(ring = []); + first = true; + v_ = false; + x_ = y_ = NaN; + } + function lineEnd() { + if (segments) { + linePoint(x__, y__); + if (v__ && v_) bufferListener.rejoin(); + segments.push(bufferListener.buffer()); + } + clip.point = point; + if (v_) listener.lineEnd(); + } + function linePoint(x, y) { + x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x)); + y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y)); + var v = pointVisible(x, y); + if (polygon) ring.push([ x, y ]); + if (first) { + x__ = x, y__ = y, v__ = v; + first = false; + if (v) { + listener.lineStart(); + listener.point(x, y); + } + } else { + if (v && v_) listener.point(x, y); else { + var l = { + a: { + x: x_, + y: y_ + }, + b: { + x: x, + y: y + } + }; + if (clipLine(l)) { + if (!v_) { + listener.lineStart(); + listener.point(l.a.x, l.a.y); + } + listener.point(l.b.x, l.b.y); + if (!v) listener.lineEnd(); + clean = false; + } else if (v) { + listener.lineStart(); + listener.point(x, y); + clean = false; + } + } + } + x_ = x, y_ = y, v_ = v; + } + return clip; + }; + function corner(p, direction) { + return abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; + } + function compare(a, b) { + return comparePoints(a.x, b.x); + } + function comparePoints(a, b) { + var ca = corner(a, 1), cb = corner(b, 1); + return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0]; + } + } + function d3_geo_conic(projectAt) { + var φ0 = 0, φ1 = π / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1); + p.parallels = function(_) { + if (!arguments.length) return [ φ0 / π * 180, φ1 / π * 180 ]; + return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180); + }; + return p; + } + function d3_geo_conicEqualArea(φ0, φ1) { + var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n; + function forward(λ, φ) { + var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; + return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ]; + } + forward.invert = function(x, y) { + var ρ0_y = ρ0 - y; + return [ Math.atan2(x, ρ0_y) / n, d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ]; + }; + return forward; + } + (d3.geo.conicEqualArea = function() { + return d3_geo_conic(d3_geo_conicEqualArea); + }).raw = d3_geo_conicEqualArea; + d3.geo.albers = function() { + return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070); + }; + d3.geo.albersUsa = function() { + var lower48 = d3.geo.albers(); + var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]); + var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]); + var point, pointStream = { + point: function(x, y) { + point = [ x, y ]; + } + }, lower48Point, alaskaPoint, hawaiiPoint; + function albersUsa(coordinates) { + var x = coordinates[0], y = coordinates[1]; + point = null; + (lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y); + return point; + } + albersUsa.invert = function(coordinates) { + var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k; + return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates); + }; + albersUsa.stream = function(stream) { + var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream); + return { + point: function(x, y) { + lower48Stream.point(x, y); + alaskaStream.point(x, y); + hawaiiStream.point(x, y); + }, + sphere: function() { + lower48Stream.sphere(); + alaskaStream.sphere(); + hawaiiStream.sphere(); + }, + lineStart: function() { + lower48Stream.lineStart(); + alaskaStream.lineStart(); + hawaiiStream.lineStart(); + }, + lineEnd: function() { + lower48Stream.lineEnd(); + alaskaStream.lineEnd(); + hawaiiStream.lineEnd(); + }, + polygonStart: function() { + lower48Stream.polygonStart(); + alaskaStream.polygonStart(); + hawaiiStream.polygonStart(); + }, + polygonEnd: function() { + lower48Stream.polygonEnd(); + alaskaStream.polygonEnd(); + hawaiiStream.polygonEnd(); + } + }; + }; + albersUsa.precision = function(_) { + if (!arguments.length) return lower48.precision(); + lower48.precision(_); + alaska.precision(_); + hawaii.precision(_); + return albersUsa; + }; + albersUsa.scale = function(_) { + if (!arguments.length) return lower48.scale(); + lower48.scale(_); + alaska.scale(_ * .35); + hawaii.scale(_); + return albersUsa.translate(lower48.translate()); + }; + albersUsa.translate = function(_) { + if (!arguments.length) return lower48.translate(); + var k = lower48.scale(), x = +_[0], y = +_[1]; + lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point; + alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; + hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; + return albersUsa; + }; + return albersUsa.scale(1070); + }; + var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { + point: d3_noop, + lineStart: d3_noop, + lineEnd: d3_noop, + polygonStart: function() { + d3_geo_pathAreaPolygon = 0; + d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; + }, + polygonEnd: function() { + d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; + d3_geo_pathAreaSum += abs(d3_geo_pathAreaPolygon / 2); + } + }; + function d3_geo_pathAreaRingStart() { + var x00, y00, x0, y0; + d3_geo_pathArea.point = function(x, y) { + d3_geo_pathArea.point = nextPoint; + x00 = x0 = x, y00 = y0 = y; + }; + function nextPoint(x, y) { + d3_geo_pathAreaPolygon += y0 * x - x0 * y; + x0 = x, y0 = y; + } + d3_geo_pathArea.lineEnd = function() { + nextPoint(x00, y00); + }; + } + var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1; + var d3_geo_pathBounds = { + point: d3_geo_pathBoundsPoint, + lineStart: d3_noop, + lineEnd: d3_noop, + polygonStart: d3_noop, + polygonEnd: d3_noop + }; + function d3_geo_pathBoundsPoint(x, y) { + if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x; + if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x; + if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y; + if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y; + } + function d3_geo_pathBuffer() { + var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = []; + var stream = { + point: point, + lineStart: function() { + stream.point = pointLineStart; + }, + lineEnd: lineEnd, + polygonStart: function() { + stream.lineEnd = lineEndPolygon; + }, + polygonEnd: function() { + stream.lineEnd = lineEnd; + stream.point = point; + }, + pointRadius: function(_) { + pointCircle = d3_geo_pathBufferCircle(_); + return stream; + }, + result: function() { + if (buffer.length) { + var result = buffer.join(""); + buffer = []; + return result; + } + } + }; + function point(x, y) { + buffer.push("M", x, ",", y, pointCircle); + } + function pointLineStart(x, y) { + buffer.push("M", x, ",", y); + stream.point = pointLine; + } + function pointLine(x, y) { + buffer.push("L", x, ",", y); + } + function lineEnd() { + stream.point = point; + } + function lineEndPolygon() { + buffer.push("Z"); + } + return stream; + } + function d3_geo_pathBufferCircle(radius) { + return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z"; + } + var d3_geo_pathCentroid = { + point: d3_geo_pathCentroidPoint, + lineStart: d3_geo_pathCentroidLineStart, + lineEnd: d3_geo_pathCentroidLineEnd, + polygonStart: function() { + d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; + }, + polygonEnd: function() { + d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; + d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; + d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; + } + }; + function d3_geo_pathCentroidPoint(x, y) { + d3_geo_centroidX0 += x; + d3_geo_centroidY0 += y; + ++d3_geo_centroidZ0; + } + function d3_geo_pathCentroidLineStart() { + var x0, y0; + d3_geo_pathCentroid.point = function(x, y) { + d3_geo_pathCentroid.point = nextPoint; + d3_geo_pathCentroidPoint(x0 = x, y0 = y); + }; + function nextPoint(x, y) { + var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); + d3_geo_centroidX1 += z * (x0 + x) / 2; + d3_geo_centroidY1 += z * (y0 + y) / 2; + d3_geo_centroidZ1 += z; + d3_geo_pathCentroidPoint(x0 = x, y0 = y); + } + } + function d3_geo_pathCentroidLineEnd() { + d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; + } + function d3_geo_pathCentroidRingStart() { + var x00, y00, x0, y0; + d3_geo_pathCentroid.point = function(x, y) { + d3_geo_pathCentroid.point = nextPoint; + d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y); + }; + function nextPoint(x, y) { + var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); + d3_geo_centroidX1 += z * (x0 + x) / 2; + d3_geo_centroidY1 += z * (y0 + y) / 2; + d3_geo_centroidZ1 += z; + z = y0 * x - x0 * y; + d3_geo_centroidX2 += z * (x0 + x); + d3_geo_centroidY2 += z * (y0 + y); + d3_geo_centroidZ2 += z * 3; + d3_geo_pathCentroidPoint(x0 = x, y0 = y); + } + d3_geo_pathCentroid.lineEnd = function() { + nextPoint(x00, y00); + }; + } + function d3_geo_pathContext(context) { + var pointRadius = 4.5; + var stream = { + point: point, + lineStart: function() { + stream.point = pointLineStart; + }, + lineEnd: lineEnd, + polygonStart: function() { + stream.lineEnd = lineEndPolygon; + }, + polygonEnd: function() { + stream.lineEnd = lineEnd; + stream.point = point; + }, + pointRadius: function(_) { + pointRadius = _; + return stream; + }, + result: d3_noop + }; + function point(x, y) { + context.moveTo(x + pointRadius, y); + context.arc(x, y, pointRadius, 0, τ); + } + function pointLineStart(x, y) { + context.moveTo(x, y); + stream.point = pointLine; + } + function pointLine(x, y) { + context.lineTo(x, y); + } + function lineEnd() { + stream.point = point; + } + function lineEndPolygon() { + context.closePath(); + } + return stream; + } + function d3_geo_resample(project) { + var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16; + function resample(stream) { + return (maxDepth ? resampleRecursive : resampleNone)(stream); + } + function resampleNone(stream) { + return d3_geo_transformPoint(stream, function(x, y) { + x = project(x, y); + stream.point(x[0], x[1]); + }); + } + function resampleRecursive(stream) { + var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0; + var resample = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + stream.polygonStart(); + resample.lineStart = ringStart; + }, + polygonEnd: function() { + stream.polygonEnd(); + resample.lineStart = lineStart; + } + }; + function point(x, y) { + x = project(x, y); + stream.point(x[0], x[1]); + } + function lineStart() { + x0 = NaN; + resample.point = linePoint; + stream.lineStart(); + } + function linePoint(λ, φ) { + var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ); + resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); + stream.point(x0, y0); + } + function lineEnd() { + resample.point = point; + stream.lineEnd(); + } + function ringStart() { + lineStart(); + resample.point = ringPoint; + resample.lineEnd = ringEnd; + } + function ringPoint(λ, φ) { + linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; + resample.point = linePoint; + } + function ringEnd() { + resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); + resample.lineEnd = lineEnd; + lineEnd(); + } + return resample; + } + function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { + var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; + if (d2 > 4 * δ2 && depth--) { + var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = abs(abs(c) - 1) < ε || abs(λ0 - λ1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; + if (dz * dz / d2 > δ2 || abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { + resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); + stream.point(x2, y2); + resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); + } + } + } + resample.precision = function(_) { + if (!arguments.length) return Math.sqrt(δ2); + maxDepth = (δ2 = _ * _) > 0 && 16; + return resample; + }; + return resample; + } + d3.geo.path = function() { + var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream; + function path(object) { + if (object) { + if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); + if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream); + d3.geo.stream(object, cacheStream); + } + return contextStream.result(); + } + path.area = function(object) { + d3_geo_pathAreaSum = 0; + d3.geo.stream(object, projectStream(d3_geo_pathArea)); + return d3_geo_pathAreaSum; + }; + path.centroid = function(object) { + d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; + d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); + return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ]; + }; + path.bounds = function(object) { + d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity); + d3.geo.stream(object, projectStream(d3_geo_pathBounds)); + return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ]; + }; + path.projection = function(_) { + if (!arguments.length) return projection; + projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; + return reset(); + }; + path.context = function(_) { + if (!arguments.length) return context; + contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_); + if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); + return reset(); + }; + path.pointRadius = function(_) { + if (!arguments.length) return pointRadius; + pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); + return path; + }; + function reset() { + cacheStream = null; + return path; + } + return path.projection(d3.geo.albersUsa()).context(null); + }; + function d3_geo_pathProjectStream(project) { + var resample = d3_geo_resample(function(x, y) { + return project([ x * d3_degrees, y * d3_degrees ]); + }); + return function(stream) { + return d3_geo_projectionRadians(resample(stream)); + }; + } + d3.geo.transform = function(methods) { + return { + stream: function(stream) { + var transform = new d3_geo_transform(stream); + for (var k in methods) transform[k] = methods[k]; + return transform; + } + }; + }; + function d3_geo_transform(stream) { + this.stream = stream; + } + d3_geo_transform.prototype = { + point: function(x, y) { + this.stream.point(x, y); + }, + sphere: function() { + this.stream.sphere(); + }, + lineStart: function() { + this.stream.lineStart(); + }, + lineEnd: function() { + this.stream.lineEnd(); + }, + polygonStart: function() { + this.stream.polygonStart(); + }, + polygonEnd: function() { + this.stream.polygonEnd(); + } + }; + function d3_geo_transformPoint(stream, point) { + return { + point: point, + sphere: function() { + stream.sphere(); + }, + lineStart: function() { + stream.lineStart(); + }, + lineEnd: function() { + stream.lineEnd(); + }, + polygonStart: function() { + stream.polygonStart(); + }, + polygonEnd: function() { + stream.polygonEnd(); + } + }; + } + d3.geo.projection = d3_geo_projection; + d3.geo.projectionMutator = d3_geo_projectionMutator; + function d3_geo_projection(project) { + return d3_geo_projectionMutator(function() { + return project; + })(); + } + function d3_geo_projectionMutator(projectAt) { + var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) { + x = project(x, y); + return [ x[0] * k + δx, δy - x[1] * k ]; + }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream; + function projection(point) { + point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); + return [ point[0] * k + δx, δy - point[1] * k ]; + } + function invert(point) { + point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); + return point && [ point[0] * d3_degrees, point[1] * d3_degrees ]; + } + projection.stream = function(output) { + if (stream) stream.valid = false; + stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output)))); + stream.valid = true; + return stream; + }; + projection.clipAngle = function(_) { + if (!arguments.length) return clipAngle; + preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians); + return invalidate(); + }; + projection.clipExtent = function(_) { + if (!arguments.length) return clipExtent; + clipExtent = _; + postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity; + return invalidate(); + }; + projection.scale = function(_) { + if (!arguments.length) return k; + k = +_; + return reset(); + }; + projection.translate = function(_) { + if (!arguments.length) return [ x, y ]; + x = +_[0]; + y = +_[1]; + return reset(); + }; + projection.center = function(_) { + if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ]; + λ = _[0] % 360 * d3_radians; + φ = _[1] % 360 * d3_radians; + return reset(); + }; + projection.rotate = function(_) { + if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ]; + δλ = _[0] % 360 * d3_radians; + δφ = _[1] % 360 * d3_radians; + δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; + return reset(); + }; + d3.rebind(projection, projectResample, "precision"); + function reset() { + projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); + var center = project(λ, φ); + δx = x - center[0] * k; + δy = y + center[1] * k; + return invalidate(); + } + function invalidate() { + if (stream) stream.valid = false, stream = null; + return projection; + } + return function() { + project = projectAt.apply(this, arguments); + projection.invert = project.invert && invert; + return reset(); + }; + } + function d3_geo_projectionRadians(stream) { + return d3_geo_transformPoint(stream, function(x, y) { + stream.point(x * d3_radians, y * d3_radians); + }); + } + function d3_geo_equirectangular(λ, φ) { + return [ λ, φ ]; + } + (d3.geo.equirectangular = function() { + return d3_geo_projection(d3_geo_equirectangular); + }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; + d3.geo.rotation = function(rotate) { + rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0); + function forward(coordinates) { + coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians); + return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; + } + forward.invert = function(coordinates) { + coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians); + return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; + }; + return forward; + }; + function d3_geo_identityRotation(λ, φ) { + return [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ]; + } + d3_geo_identityRotation.invert = d3_geo_equirectangular; + function d3_geo_rotation(δλ, δφ, δγ) { + return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation; + } + function d3_geo_forwardRotationλ(δλ) { + return function(λ, φ) { + return λ += δλ, [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ]; + }; + } + function d3_geo_rotationλ(δλ) { + var rotation = d3_geo_forwardRotationλ(δλ); + rotation.invert = d3_geo_forwardRotationλ(-δλ); + return rotation; + } + function d3_geo_rotationφγ(δφ, δγ) { + var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ); + function rotation(λ, φ) { + var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ; + return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ]; + } + rotation.invert = function(λ, φ) { + var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ; + return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ]; + }; + return rotation; + } + d3.geo.circle = function() { + var origin = [ 0, 0 ], angle, precision = 6, interpolate; + function circle() { + var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = []; + interpolate(null, null, 1, { + point: function(x, y) { + ring.push(x = rotate(x, y)); + x[0] *= d3_degrees, x[1] *= d3_degrees; + } + }); + return { + type: "Polygon", + coordinates: [ ring ] + }; + } + circle.origin = function(x) { + if (!arguments.length) return origin; + origin = x; + return circle; + }; + circle.angle = function(x) { + if (!arguments.length) return angle; + interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); + return circle; + }; + circle.precision = function(_) { + if (!arguments.length) return precision; + interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); + return circle; + }; + return circle.angle(90); + }; + function d3_geo_circleInterpolate(radius, precision) { + var cr = Math.cos(radius), sr = Math.sin(radius); + return function(from, to, direction, listener) { + var step = direction * precision; + if (from != null) { + from = d3_geo_circleAngle(cr, from); + to = d3_geo_circleAngle(cr, to); + if (direction > 0 ? from < to : from > to) from += direction * τ; + } else { + from = radius + direction * τ; + to = radius - .5 * step; + } + for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) { + listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]); + } + }; + } + function d3_geo_circleAngle(cr, point) { + var a = d3_geo_cartesian(point); + a[0] -= cr; + d3_geo_cartesianNormalize(a); + var angle = d3_acos(-a[1]); + return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); + } + d3.geo.distance = function(a, b) { + var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t; + return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ); + }; + d3.geo.graticule = function() { + var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5; + function graticule() { + return { + type: "MultiLineString", + coordinates: lines() + }; + } + function lines() { + return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { + return abs(x % DX) > ε; + }).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) { + return abs(y % DY) > ε; + }).map(y)); + } + graticule.lines = function() { + return lines().map(function(coordinates) { + return { + type: "LineString", + coordinates: coordinates + }; + }); + }; + graticule.outline = function() { + return { + type: "Polygon", + coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ] + }; + }; + graticule.extent = function(_) { + if (!arguments.length) return graticule.minorExtent(); + return graticule.majorExtent(_).minorExtent(_); + }; + graticule.majorExtent = function(_) { + if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ]; + X0 = +_[0][0], X1 = +_[1][0]; + Y0 = +_[0][1], Y1 = +_[1][1]; + if (X0 > X1) _ = X0, X0 = X1, X1 = _; + if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; + return graticule.precision(precision); + }; + graticule.minorExtent = function(_) { + if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; + x0 = +_[0][0], x1 = +_[1][0]; + y0 = +_[0][1], y1 = +_[1][1]; + if (x0 > x1) _ = x0, x0 = x1, x1 = _; + if (y0 > y1) _ = y0, y0 = y1, y1 = _; + return graticule.precision(precision); + }; + graticule.step = function(_) { + if (!arguments.length) return graticule.minorStep(); + return graticule.majorStep(_).minorStep(_); + }; + graticule.majorStep = function(_) { + if (!arguments.length) return [ DX, DY ]; + DX = +_[0], DY = +_[1]; + return graticule; + }; + graticule.minorStep = function(_) { + if (!arguments.length) return [ dx, dy ]; + dx = +_[0], dy = +_[1]; + return graticule; + }; + graticule.precision = function(_) { + if (!arguments.length) return precision; + precision = +_; + x = d3_geo_graticuleX(y0, y1, 90); + y = d3_geo_graticuleY(x0, x1, precision); + X = d3_geo_graticuleX(Y0, Y1, 90); + Y = d3_geo_graticuleY(X0, X1, precision); + return graticule; + }; + return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]); + }; + function d3_geo_graticuleX(y0, y1, dy) { + var y = d3.range(y0, y1 - ε, dy).concat(y1); + return function(x) { + return y.map(function(y) { + return [ x, y ]; + }); + }; + } + function d3_geo_graticuleY(x0, x1, dx) { + var x = d3.range(x0, x1 - ε, dx).concat(x1); + return function(y) { + return x.map(function(x) { + return [ x, y ]; + }); + }; + } + function d3_source(d) { + return d.source; + } + function d3_target(d) { + return d.target; + } + d3.geo.greatArc = function() { + var source = d3_source, source_, target = d3_target, target_; + function greatArc() { + return { + type: "LineString", + coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ] + }; + } + greatArc.distance = function() { + return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments)); + }; + greatArc.source = function(_) { + if (!arguments.length) return source; + source = _, source_ = typeof _ === "function" ? null : _; + return greatArc; + }; + greatArc.target = function(_) { + if (!arguments.length) return target; + target = _, target_ = typeof _ === "function" ? null : _; + return greatArc; + }; + greatArc.precision = function() { + return arguments.length ? greatArc : 0; + }; + return greatArc; + }; + d3.geo.interpolate = function(source, target) { + return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians); + }; + function d3_geo_interpolate(x0, y0, x1, y1) { + var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d); + var interpolate = d ? function(t) { + var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; + return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ]; + } : function() { + return [ x0 * d3_degrees, y0 * d3_degrees ]; + }; + interpolate.distance = d; + return interpolate; + } + d3.geo.length = function(object) { + d3_geo_lengthSum = 0; + d3.geo.stream(object, d3_geo_length); + return d3_geo_lengthSum; + }; + var d3_geo_lengthSum; + var d3_geo_length = { + sphere: d3_noop, + point: d3_noop, + lineStart: d3_geo_lengthLineStart, + lineEnd: d3_noop, + polygonStart: d3_noop, + polygonEnd: d3_noop + }; + function d3_geo_lengthLineStart() { + var λ0, sinφ0, cosφ0; + d3_geo_length.point = function(λ, φ) { + λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ); + d3_geo_length.point = nextPoint; + }; + d3_geo_length.lineEnd = function() { + d3_geo_length.point = d3_geo_length.lineEnd = d3_noop; + }; + function nextPoint(λ, φ) { + var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t); + d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ); + λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ; + } + } + function d3_geo_azimuthal(scale, angle) { + function azimuthal(λ, φ) { + var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ); + return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ]; + } + azimuthal.invert = function(x, y) { + var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c); + return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ]; + }; + return azimuthal; + } + var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) { + return Math.sqrt(2 / (1 + cosλcosφ)); + }, function(ρ) { + return 2 * Math.asin(ρ / 2); + }); + (d3.geo.azimuthalEqualArea = function() { + return d3_geo_projection(d3_geo_azimuthalEqualArea); + }).raw = d3_geo_azimuthalEqualArea; + var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) { + var c = Math.acos(cosλcosφ); + return c && c / Math.sin(c); + }, d3_identity); + (d3.geo.azimuthalEquidistant = function() { + return d3_geo_projection(d3_geo_azimuthalEquidistant); + }).raw = d3_geo_azimuthalEquidistant; + function d3_geo_conicConformal(φ0, φ1) { + var cosφ0 = Math.cos(φ0), t = function(φ) { + return Math.tan(π / 4 + φ / 2); + }, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n; + if (!n) return d3_geo_mercator; + function forward(λ, φ) { + if (F > 0) { + if (φ < -halfπ + ε) φ = -halfπ + ε; + } else { + if (φ > halfπ - ε) φ = halfπ - ε; + } + var ρ = F / Math.pow(t(φ), n); + return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ]; + } + forward.invert = function(x, y) { + var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y); + return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - halfπ ]; + }; + return forward; + } + (d3.geo.conicConformal = function() { + return d3_geo_conic(d3_geo_conicConformal); + }).raw = d3_geo_conicConformal; + function d3_geo_conicEquidistant(φ0, φ1) { + var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0; + if (abs(n) < ε) return d3_geo_equirectangular; + function forward(λ, φ) { + var ρ = G - φ; + return [ ρ * Math.sin(n * λ), G - ρ * Math.cos(n * λ) ]; + } + forward.invert = function(x, y) { + var ρ0_y = G - y; + return [ Math.atan2(x, ρ0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) ]; + }; + return forward; + } + (d3.geo.conicEquidistant = function() { + return d3_geo_conic(d3_geo_conicEquidistant); + }).raw = d3_geo_conicEquidistant; + var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) { + return 1 / cosλcosφ; + }, Math.atan); + (d3.geo.gnomonic = function() { + return d3_geo_projection(d3_geo_gnomonic); + }).raw = d3_geo_gnomonic; + function d3_geo_mercator(λ, φ) { + return [ λ, Math.log(Math.tan(π / 4 + φ / 2)) ]; + } + d3_geo_mercator.invert = function(x, y) { + return [ x, 2 * Math.atan(Math.exp(y)) - halfπ ]; + }; + function d3_geo_mercatorProjection(project) { + var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto; + m.scale = function() { + var v = scale.apply(m, arguments); + return v === m ? clipAuto ? m.clipExtent(null) : m : v; + }; + m.translate = function() { + var v = translate.apply(m, arguments); + return v === m ? clipAuto ? m.clipExtent(null) : m : v; + }; + m.clipExtent = function(_) { + var v = clipExtent.apply(m, arguments); + if (v === m) { + if (clipAuto = _ == null) { + var k = π * scale(), t = translate(); + clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]); + } + } else if (clipAuto) { + v = null; + } + return v; + }; + return m.clipExtent(null); + } + (d3.geo.mercator = function() { + return d3_geo_mercatorProjection(d3_geo_mercator); + }).raw = d3_geo_mercator; + var d3_geo_orthographic = d3_geo_azimuthal(function() { + return 1; + }, Math.asin); + (d3.geo.orthographic = function() { + return d3_geo_projection(d3_geo_orthographic); + }).raw = d3_geo_orthographic; + var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) { + return 1 / (1 + cosλcosφ); + }, function(ρ) { + return 2 * Math.atan(ρ); + }); + (d3.geo.stereographic = function() { + return d3_geo_projection(d3_geo_stereographic); + }).raw = d3_geo_stereographic; + function d3_geo_transverseMercator(λ, φ) { + return [ Math.log(Math.tan(π / 4 + φ / 2)), -λ ]; + } + d3_geo_transverseMercator.invert = function(x, y) { + return [ -y, 2 * Math.atan(Math.exp(x)) - halfπ ]; + }; + (d3.geo.transverseMercator = function() { + var projection = d3_geo_mercatorProjection(d3_geo_transverseMercator), center = projection.center, rotate = projection.rotate; + projection.center = function(_) { + return _ ? center([ -_[1], _[0] ]) : (_ = center(), [ _[1], -_[0] ]); + }; + projection.rotate = function(_) { + return _ ? rotate([ _[0], _[1], _.length > 2 ? _[2] + 90 : 90 ]) : (_ = rotate(), + [ _[0], _[1], _[2] - 90 ]); + }; + return rotate([ 0, 0, 90 ]); + }).raw = d3_geo_transverseMercator; + d3.geom = {}; + function d3_geom_pointX(d) { + return d[0]; + } + function d3_geom_pointY(d) { + return d[1]; + } + d3.geom.hull = function(vertices) { + var x = d3_geom_pointX, y = d3_geom_pointY; + if (arguments.length) return hull(vertices); + function hull(data) { + if (data.length < 3) return []; + var fx = d3_functor(x), fy = d3_functor(y), i, n = data.length, points = [], flippedPoints = []; + for (i = 0; i < n; i++) { + points.push([ +fx.call(this, data[i], i), +fy.call(this, data[i], i), i ]); + } + points.sort(d3_geom_hullOrder); + for (i = 0; i < n; i++) flippedPoints.push([ points[i][0], -points[i][1] ]); + var upper = d3_geom_hullUpper(points), lower = d3_geom_hullUpper(flippedPoints); + var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1], polygon = []; + for (i = upper.length - 1; i >= 0; --i) polygon.push(data[points[upper[i]][2]]); + for (i = +skipLeft; i < lower.length - skipRight; ++i) polygon.push(data[points[lower[i]][2]]); + return polygon; + } + hull.x = function(_) { + return arguments.length ? (x = _, hull) : x; + }; + hull.y = function(_) { + return arguments.length ? (y = _, hull) : y; + }; + return hull; + }; + function d3_geom_hullUpper(points) { + var n = points.length, hull = [ 0, 1 ], hs = 2; + for (var i = 2; i < n; i++) { + while (hs > 1 && d3_cross2d(points[hull[hs - 2]], points[hull[hs - 1]], points[i]) <= 0) --hs; + hull[hs++] = i; + } + return hull.slice(0, hs); + } + function d3_geom_hullOrder(a, b) { + return a[0] - b[0] || a[1] - b[1]; + } + d3.geom.polygon = function(coordinates) { + d3_subclass(coordinates, d3_geom_polygonPrototype); + return coordinates; + }; + var d3_geom_polygonPrototype = d3.geom.polygon.prototype = []; + d3_geom_polygonPrototype.area = function() { + var i = -1, n = this.length, a, b = this[n - 1], area = 0; + while (++i < n) { + a = b; + b = this[i]; + area += a[1] * b[0] - a[0] * b[1]; + } + return area * .5; + }; + d3_geom_polygonPrototype.centroid = function(k) { + var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c; + if (!arguments.length) k = -1 / (6 * this.area()); + while (++i < n) { + a = b; + b = this[i]; + c = a[0] * b[1] - b[0] * a[1]; + x += (a[0] + b[0]) * c; + y += (a[1] + b[1]) * c; + } + return [ x * k, y * k ]; + }; + d3_geom_polygonPrototype.clip = function(subject) { + var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d; + while (++i < n) { + input = subject.slice(); + subject.length = 0; + b = this[i]; + c = input[(m = input.length - closed) - 1]; + j = -1; + while (++j < m) { + d = input[j]; + if (d3_geom_polygonInside(d, a, b)) { + if (!d3_geom_polygonInside(c, a, b)) { + subject.push(d3_geom_polygonIntersect(c, d, a, b)); + } + subject.push(d); + } else if (d3_geom_polygonInside(c, a, b)) { + subject.push(d3_geom_polygonIntersect(c, d, a, b)); + } + c = d; + } + if (closed) subject.push(subject[0]); + a = b; + } + return subject; + }; + function d3_geom_polygonInside(p, a, b) { + return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); + } + function d3_geom_polygonIntersect(c, d, a, b) { + var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); + return [ x1 + ua * x21, y1 + ua * y21 ]; + } + function d3_geom_polygonClosed(coordinates) { + var a = coordinates[0], b = coordinates[coordinates.length - 1]; + return !(a[0] - b[0] || a[1] - b[1]); + } + var d3_geom_voronoiEdges, d3_geom_voronoiCells, d3_geom_voronoiBeaches, d3_geom_voronoiBeachPool = [], d3_geom_voronoiFirstCircle, d3_geom_voronoiCircles, d3_geom_voronoiCirclePool = []; + function d3_geom_voronoiBeach() { + d3_geom_voronoiRedBlackNode(this); + this.edge = this.site = this.circle = null; + } + function d3_geom_voronoiCreateBeach(site) { + var beach = d3_geom_voronoiBeachPool.pop() || new d3_geom_voronoiBeach(); + beach.site = site; + return beach; + } + function d3_geom_voronoiDetachBeach(beach) { + d3_geom_voronoiDetachCircle(beach); + d3_geom_voronoiBeaches.remove(beach); + d3_geom_voronoiBeachPool.push(beach); + d3_geom_voronoiRedBlackNode(beach); + } + function d3_geom_voronoiRemoveBeach(beach) { + var circle = beach.circle, x = circle.x, y = circle.cy, vertex = { + x: x, + y: y + }, previous = beach.P, next = beach.N, disappearing = [ beach ]; + d3_geom_voronoiDetachBeach(beach); + var lArc = previous; + while (lArc.circle && abs(x - lArc.circle.x) < ε && abs(y - lArc.circle.cy) < ε) { + previous = lArc.P; + disappearing.unshift(lArc); + d3_geom_voronoiDetachBeach(lArc); + lArc = previous; + } + disappearing.unshift(lArc); + d3_geom_voronoiDetachCircle(lArc); + var rArc = next; + while (rArc.circle && abs(x - rArc.circle.x) < ε && abs(y - rArc.circle.cy) < ε) { + next = rArc.N; + disappearing.push(rArc); + d3_geom_voronoiDetachBeach(rArc); + rArc = next; + } + disappearing.push(rArc); + d3_geom_voronoiDetachCircle(rArc); + var nArcs = disappearing.length, iArc; + for (iArc = 1; iArc < nArcs; ++iArc) { + rArc = disappearing[iArc]; + lArc = disappearing[iArc - 1]; + d3_geom_voronoiSetEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex); + } + lArc = disappearing[0]; + rArc = disappearing[nArcs - 1]; + rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, rArc.site, null, vertex); + d3_geom_voronoiAttachCircle(lArc); + d3_geom_voronoiAttachCircle(rArc); + } + function d3_geom_voronoiAddBeach(site) { + var x = site.x, directrix = site.y, lArc, rArc, dxl, dxr, node = d3_geom_voronoiBeaches._; + while (node) { + dxl = d3_geom_voronoiLeftBreakPoint(node, directrix) - x; + if (dxl > ε) node = node.L; else { + dxr = x - d3_geom_voronoiRightBreakPoint(node, directrix); + if (dxr > ε) { + if (!node.R) { + lArc = node; + break; + } + node = node.R; + } else { + if (dxl > -ε) { + lArc = node.P; + rArc = node; + } else if (dxr > -ε) { + lArc = node; + rArc = node.N; + } else { + lArc = rArc = node; + } + break; + } + } + } + var newArc = d3_geom_voronoiCreateBeach(site); + d3_geom_voronoiBeaches.insert(lArc, newArc); + if (!lArc && !rArc) return; + if (lArc === rArc) { + d3_geom_voronoiDetachCircle(lArc); + rArc = d3_geom_voronoiCreateBeach(lArc.site); + d3_geom_voronoiBeaches.insert(newArc, rArc); + newArc.edge = rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); + d3_geom_voronoiAttachCircle(lArc); + d3_geom_voronoiAttachCircle(rArc); + return; + } + if (!rArc) { + newArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); + return; + } + d3_geom_voronoiDetachCircle(lArc); + d3_geom_voronoiDetachCircle(rArc); + var lSite = lArc.site, ax = lSite.x, ay = lSite.y, bx = site.x - ax, by = site.y - ay, rSite = rArc.site, cx = rSite.x - ax, cy = rSite.y - ay, d = 2 * (bx * cy - by * cx), hb = bx * bx + by * by, hc = cx * cx + cy * cy, vertex = { + x: (cy * hb - by * hc) / d + ax, + y: (bx * hc - cx * hb) / d + ay + }; + d3_geom_voronoiSetEdgeEnd(rArc.edge, lSite, rSite, vertex); + newArc.edge = d3_geom_voronoiCreateEdge(lSite, site, null, vertex); + rArc.edge = d3_geom_voronoiCreateEdge(site, rSite, null, vertex); + d3_geom_voronoiAttachCircle(lArc); + d3_geom_voronoiAttachCircle(rArc); + } + function d3_geom_voronoiLeftBreakPoint(arc, directrix) { + var site = arc.site, rfocx = site.x, rfocy = site.y, pby2 = rfocy - directrix; + if (!pby2) return rfocx; + var lArc = arc.P; + if (!lArc) return -Infinity; + site = lArc.site; + var lfocx = site.x, lfocy = site.y, plby2 = lfocy - directrix; + if (!plby2) return lfocx; + var hl = lfocx - rfocx, aby2 = 1 / pby2 - 1 / plby2, b = hl / plby2; + if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx; + return (rfocx + lfocx) / 2; + } + function d3_geom_voronoiRightBreakPoint(arc, directrix) { + var rArc = arc.N; + if (rArc) return d3_geom_voronoiLeftBreakPoint(rArc, directrix); + var site = arc.site; + return site.y === directrix ? site.x : Infinity; + } + function d3_geom_voronoiCell(site) { + this.site = site; + this.edges = []; + } + d3_geom_voronoiCell.prototype.prepare = function() { + var halfEdges = this.edges, iHalfEdge = halfEdges.length, edge; + while (iHalfEdge--) { + edge = halfEdges[iHalfEdge].edge; + if (!edge.b || !edge.a) halfEdges.splice(iHalfEdge, 1); + } + halfEdges.sort(d3_geom_voronoiHalfEdgeOrder); + return halfEdges.length; + }; + function d3_geom_voronoiCloseCells(extent) { + var x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], x2, y2, x3, y3, cells = d3_geom_voronoiCells, iCell = cells.length, cell, iHalfEdge, halfEdges, nHalfEdges, start, end; + while (iCell--) { + cell = cells[iCell]; + if (!cell || !cell.prepare()) continue; + halfEdges = cell.edges; + nHalfEdges = halfEdges.length; + iHalfEdge = 0; + while (iHalfEdge < nHalfEdges) { + end = halfEdges[iHalfEdge].end(), x3 = end.x, y3 = end.y; + start = halfEdges[++iHalfEdge % nHalfEdges].start(), x2 = start.x, y2 = start.y; + if (abs(x3 - x2) > ε || abs(y3 - y2) > ε) { + halfEdges.splice(iHalfEdge, 0, new d3_geom_voronoiHalfEdge(d3_geom_voronoiCreateBorderEdge(cell.site, end, abs(x3 - x0) < ε && y1 - y3 > ε ? { + x: x0, + y: abs(x2 - x0) < ε ? y2 : y1 + } : abs(y3 - y1) < ε && x1 - x3 > ε ? { + x: abs(y2 - y1) < ε ? x2 : x1, + y: y1 + } : abs(x3 - x1) < ε && y3 - y0 > ε ? { + x: x1, + y: abs(x2 - x1) < ε ? y2 : y0 + } : abs(y3 - y0) < ε && x3 - x0 > ε ? { + x: abs(y2 - y0) < ε ? x2 : x0, + y: y0 + } : null), cell.site, null)); + ++nHalfEdges; + } + } + } + } + function d3_geom_voronoiHalfEdgeOrder(a, b) { + return b.angle - a.angle; + } + function d3_geom_voronoiCircle() { + d3_geom_voronoiRedBlackNode(this); + this.x = this.y = this.arc = this.site = this.cy = null; + } + function d3_geom_voronoiAttachCircle(arc) { + var lArc = arc.P, rArc = arc.N; + if (!lArc || !rArc) return; + var lSite = lArc.site, cSite = arc.site, rSite = rArc.site; + if (lSite === rSite) return; + var bx = cSite.x, by = cSite.y, ax = lSite.x - bx, ay = lSite.y - by, cx = rSite.x - bx, cy = rSite.y - by; + var d = 2 * (ax * cy - ay * cx); + if (d >= -ε2) return; + var ha = ax * ax + ay * ay, hc = cx * cx + cy * cy, x = (cy * ha - ay * hc) / d, y = (ax * hc - cx * ha) / d, cy = y + by; + var circle = d3_geom_voronoiCirclePool.pop() || new d3_geom_voronoiCircle(); + circle.arc = arc; + circle.site = cSite; + circle.x = x + bx; + circle.y = cy + Math.sqrt(x * x + y * y); + circle.cy = cy; + arc.circle = circle; + var before = null, node = d3_geom_voronoiCircles._; + while (node) { + if (circle.y < node.y || circle.y === node.y && circle.x <= node.x) { + if (node.L) node = node.L; else { + before = node.P; + break; + } + } else { + if (node.R) node = node.R; else { + before = node; + break; + } + } + } + d3_geom_voronoiCircles.insert(before, circle); + if (!before) d3_geom_voronoiFirstCircle = circle; + } + function d3_geom_voronoiDetachCircle(arc) { + var circle = arc.circle; + if (circle) { + if (!circle.P) d3_geom_voronoiFirstCircle = circle.N; + d3_geom_voronoiCircles.remove(circle); + d3_geom_voronoiCirclePool.push(circle); + d3_geom_voronoiRedBlackNode(circle); + arc.circle = null; + } + } + function d3_geom_voronoiClipEdges(extent) { + var edges = d3_geom_voronoiEdges, clip = d3_geom_clipLine(extent[0][0], extent[0][1], extent[1][0], extent[1][1]), i = edges.length, e; + while (i--) { + e = edges[i]; + if (!d3_geom_voronoiConnectEdge(e, extent) || !clip(e) || abs(e.a.x - e.b.x) < ε && abs(e.a.y - e.b.y) < ε) { + e.a = e.b = null; + edges.splice(i, 1); + } + } + } + function d3_geom_voronoiConnectEdge(edge, extent) { + var vb = edge.b; + if (vb) return true; + var va = edge.a, x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], lSite = edge.l, rSite = edge.r, lx = lSite.x, ly = lSite.y, rx = rSite.x, ry = rSite.y, fx = (lx + rx) / 2, fy = (ly + ry) / 2, fm, fb; + if (ry === ly) { + if (fx < x0 || fx >= x1) return; + if (lx > rx) { + if (!va) va = { + x: fx, + y: y0 + }; else if (va.y >= y1) return; + vb = { + x: fx, + y: y1 + }; + } else { + if (!va) va = { + x: fx, + y: y1 + }; else if (va.y < y0) return; + vb = { + x: fx, + y: y0 + }; + } + } else { + fm = (lx - rx) / (ry - ly); + fb = fy - fm * fx; + if (fm < -1 || fm > 1) { + if (lx > rx) { + if (!va) va = { + x: (y0 - fb) / fm, + y: y0 + }; else if (va.y >= y1) return; + vb = { + x: (y1 - fb) / fm, + y: y1 + }; + } else { + if (!va) va = { + x: (y1 - fb) / fm, + y: y1 + }; else if (va.y < y0) return; + vb = { + x: (y0 - fb) / fm, + y: y0 + }; + } + } else { + if (ly < ry) { + if (!va) va = { + x: x0, + y: fm * x0 + fb + }; else if (va.x >= x1) return; + vb = { + x: x1, + y: fm * x1 + fb + }; + } else { + if (!va) va = { + x: x1, + y: fm * x1 + fb + }; else if (va.x < x0) return; + vb = { + x: x0, + y: fm * x0 + fb + }; + } + } + } + edge.a = va; + edge.b = vb; + return true; + } + function d3_geom_voronoiEdge(lSite, rSite) { + this.l = lSite; + this.r = rSite; + this.a = this.b = null; + } + function d3_geom_voronoiCreateEdge(lSite, rSite, va, vb) { + var edge = new d3_geom_voronoiEdge(lSite, rSite); + d3_geom_voronoiEdges.push(edge); + if (va) d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, va); + if (vb) d3_geom_voronoiSetEdgeEnd(edge, rSite, lSite, vb); + d3_geom_voronoiCells[lSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, lSite, rSite)); + d3_geom_voronoiCells[rSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, rSite, lSite)); + return edge; + } + function d3_geom_voronoiCreateBorderEdge(lSite, va, vb) { + var edge = new d3_geom_voronoiEdge(lSite, null); + edge.a = va; + edge.b = vb; + d3_geom_voronoiEdges.push(edge); + return edge; + } + function d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, vertex) { + if (!edge.a && !edge.b) { + edge.a = vertex; + edge.l = lSite; + edge.r = rSite; + } else if (edge.l === rSite) { + edge.b = vertex; + } else { + edge.a = vertex; + } + } + function d3_geom_voronoiHalfEdge(edge, lSite, rSite) { + var va = edge.a, vb = edge.b; + this.edge = edge; + this.site = lSite; + this.angle = rSite ? Math.atan2(rSite.y - lSite.y, rSite.x - lSite.x) : edge.l === lSite ? Math.atan2(vb.x - va.x, va.y - vb.y) : Math.atan2(va.x - vb.x, vb.y - va.y); + } + d3_geom_voronoiHalfEdge.prototype = { + start: function() { + return this.edge.l === this.site ? this.edge.a : this.edge.b; + }, + end: function() { + return this.edge.l === this.site ? this.edge.b : this.edge.a; + } + }; + function d3_geom_voronoiRedBlackTree() { + this._ = null; + } + function d3_geom_voronoiRedBlackNode(node) { + node.U = node.C = node.L = node.R = node.P = node.N = null; + } + d3_geom_voronoiRedBlackTree.prototype = { + insert: function(after, node) { + var parent, grandpa, uncle; + if (after) { + node.P = after; + node.N = after.N; + if (after.N) after.N.P = node; + after.N = node; + if (after.R) { + after = after.R; + while (after.L) after = after.L; + after.L = node; + } else { + after.R = node; + } + parent = after; + } else if (this._) { + after = d3_geom_voronoiRedBlackFirst(this._); + node.P = null; + node.N = after; + after.P = after.L = node; + parent = after; + } else { + node.P = node.N = null; + this._ = node; + parent = null; + } + node.L = node.R = null; + node.U = parent; + node.C = true; + after = node; + while (parent && parent.C) { + grandpa = parent.U; + if (parent === grandpa.L) { + uncle = grandpa.R; + if (uncle && uncle.C) { + parent.C = uncle.C = false; + grandpa.C = true; + after = grandpa; + } else { + if (after === parent.R) { + d3_geom_voronoiRedBlackRotateLeft(this, parent); + after = parent; + parent = after.U; + } + parent.C = false; + grandpa.C = true; + d3_geom_voronoiRedBlackRotateRight(this, grandpa); + } + } else { + uncle = grandpa.L; + if (uncle && uncle.C) { + parent.C = uncle.C = false; + grandpa.C = true; + after = grandpa; + } else { + if (after === parent.L) { + d3_geom_voronoiRedBlackRotateRight(this, parent); + after = parent; + parent = after.U; + } + parent.C = false; + grandpa.C = true; + d3_geom_voronoiRedBlackRotateLeft(this, grandpa); + } + } + parent = after.U; + } + this._.C = false; + }, + remove: function(node) { + if (node.N) node.N.P = node.P; + if (node.P) node.P.N = node.N; + node.N = node.P = null; + var parent = node.U, sibling, left = node.L, right = node.R, next, red; + if (!left) next = right; else if (!right) next = left; else next = d3_geom_voronoiRedBlackFirst(right); + if (parent) { + if (parent.L === node) parent.L = next; else parent.R = next; + } else { + this._ = next; + } + if (left && right) { + red = next.C; + next.C = node.C; + next.L = left; + left.U = next; + if (next !== right) { + parent = next.U; + next.U = node.U; + node = next.R; + parent.L = node; + next.R = right; + right.U = next; + } else { + next.U = parent; + parent = next; + node = next.R; + } + } else { + red = node.C; + node = next; + } + if (node) node.U = parent; + if (red) return; + if (node && node.C) { + node.C = false; + return; + } + do { + if (node === this._) break; + if (node === parent.L) { + sibling = parent.R; + if (sibling.C) { + sibling.C = false; + parent.C = true; + d3_geom_voronoiRedBlackRotateLeft(this, parent); + sibling = parent.R; + } + if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { + if (!sibling.R || !sibling.R.C) { + sibling.L.C = false; + sibling.C = true; + d3_geom_voronoiRedBlackRotateRight(this, sibling); + sibling = parent.R; + } + sibling.C = parent.C; + parent.C = sibling.R.C = false; + d3_geom_voronoiRedBlackRotateLeft(this, parent); + node = this._; + break; + } + } else { + sibling = parent.L; + if (sibling.C) { + sibling.C = false; + parent.C = true; + d3_geom_voronoiRedBlackRotateRight(this, parent); + sibling = parent.L; + } + if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { + if (!sibling.L || !sibling.L.C) { + sibling.R.C = false; + sibling.C = true; + d3_geom_voronoiRedBlackRotateLeft(this, sibling); + sibling = parent.L; + } + sibling.C = parent.C; + parent.C = sibling.L.C = false; + d3_geom_voronoiRedBlackRotateRight(this, parent); + node = this._; + break; + } + } + sibling.C = true; + node = parent; + parent = parent.U; + } while (!node.C); + if (node) node.C = false; + } + }; + function d3_geom_voronoiRedBlackRotateLeft(tree, node) { + var p = node, q = node.R, parent = p.U; + if (parent) { + if (parent.L === p) parent.L = q; else parent.R = q; + } else { + tree._ = q; + } + q.U = parent; + p.U = q; + p.R = q.L; + if (p.R) p.R.U = p; + q.L = p; + } + function d3_geom_voronoiRedBlackRotateRight(tree, node) { + var p = node, q = node.L, parent = p.U; + if (parent) { + if (parent.L === p) parent.L = q; else parent.R = q; + } else { + tree._ = q; + } + q.U = parent; + p.U = q; + p.L = q.R; + if (p.L) p.L.U = p; + q.R = p; + } + function d3_geom_voronoiRedBlackFirst(node) { + while (node.L) node = node.L; + return node; + } + function d3_geom_voronoi(sites, bbox) { + var site = sites.sort(d3_geom_voronoiVertexOrder).pop(), x0, y0, circle; + d3_geom_voronoiEdges = []; + d3_geom_voronoiCells = new Array(sites.length); + d3_geom_voronoiBeaches = new d3_geom_voronoiRedBlackTree(); + d3_geom_voronoiCircles = new d3_geom_voronoiRedBlackTree(); + while (true) { + circle = d3_geom_voronoiFirstCircle; + if (site && (!circle || site.y < circle.y || site.y === circle.y && site.x < circle.x)) { + if (site.x !== x0 || site.y !== y0) { + d3_geom_voronoiCells[site.i] = new d3_geom_voronoiCell(site); + d3_geom_voronoiAddBeach(site); + x0 = site.x, y0 = site.y; + } + site = sites.pop(); + } else if (circle) { + d3_geom_voronoiRemoveBeach(circle.arc); + } else { + break; + } + } + if (bbox) d3_geom_voronoiClipEdges(bbox), d3_geom_voronoiCloseCells(bbox); + var diagram = { + cells: d3_geom_voronoiCells, + edges: d3_geom_voronoiEdges + }; + d3_geom_voronoiBeaches = d3_geom_voronoiCircles = d3_geom_voronoiEdges = d3_geom_voronoiCells = null; + return diagram; + } + function d3_geom_voronoiVertexOrder(a, b) { + return b.y - a.y || b.x - a.x; + } + d3.geom.voronoi = function(points) { + var x = d3_geom_pointX, y = d3_geom_pointY, fx = x, fy = y, clipExtent = d3_geom_voronoiClipExtent; + if (points) return voronoi(points); + function voronoi(data) { + var polygons = new Array(data.length), x0 = clipExtent[0][0], y0 = clipExtent[0][1], x1 = clipExtent[1][0], y1 = clipExtent[1][1]; + d3_geom_voronoi(sites(data), clipExtent).cells.forEach(function(cell, i) { + var edges = cell.edges, site = cell.site, polygon = polygons[i] = edges.length ? edges.map(function(e) { + var s = e.start(); + return [ s.x, s.y ]; + }) : site.x >= x0 && site.x <= x1 && site.y >= y0 && site.y <= y1 ? [ [ x0, y1 ], [ x1, y1 ], [ x1, y0 ], [ x0, y0 ] ] : []; + polygon.point = data[i]; + }); + return polygons; + } + function sites(data) { + return data.map(function(d, i) { + return { + x: Math.round(fx(d, i) / ε) * ε, + y: Math.round(fy(d, i) / ε) * ε, + i: i + }; + }); + } + voronoi.links = function(data) { + return d3_geom_voronoi(sites(data)).edges.filter(function(edge) { + return edge.l && edge.r; + }).map(function(edge) { + return { + source: data[edge.l.i], + target: data[edge.r.i] + }; + }); + }; + voronoi.triangles = function(data) { + var triangles = []; + d3_geom_voronoi(sites(data)).cells.forEach(function(cell, i) { + var site = cell.site, edges = cell.edges.sort(d3_geom_voronoiHalfEdgeOrder), j = -1, m = edges.length, e0, s0, e1 = edges[m - 1].edge, s1 = e1.l === site ? e1.r : e1.l; + while (++j < m) { + e0 = e1; + s0 = s1; + e1 = edges[j].edge; + s1 = e1.l === site ? e1.r : e1.l; + if (i < s0.i && i < s1.i && d3_geom_voronoiTriangleArea(site, s0, s1) < 0) { + triangles.push([ data[i], data[s0.i], data[s1.i] ]); + } + } + }); + return triangles; + }; + voronoi.x = function(_) { + return arguments.length ? (fx = d3_functor(x = _), voronoi) : x; + }; + voronoi.y = function(_) { + return arguments.length ? (fy = d3_functor(y = _), voronoi) : y; + }; + voronoi.clipExtent = function(_) { + if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent; + clipExtent = _ == null ? d3_geom_voronoiClipExtent : _; + return voronoi; + }; + voronoi.size = function(_) { + if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent && clipExtent[1]; + return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]); + }; + return voronoi; + }; + var d3_geom_voronoiClipExtent = [ [ -1e6, -1e6 ], [ 1e6, 1e6 ] ]; + function d3_geom_voronoiTriangleArea(a, b, c) { + return (a.x - c.x) * (b.y - a.y) - (a.x - b.x) * (c.y - a.y); + } + d3.geom.delaunay = function(vertices) { + return d3.geom.voronoi().triangles(vertices); + }; + d3.geom.quadtree = function(points, x1, y1, x2, y2) { + var x = d3_geom_pointX, y = d3_geom_pointY, compat; + if (compat = arguments.length) { + x = d3_geom_quadtreeCompatX; + y = d3_geom_quadtreeCompatY; + if (compat === 3) { + y2 = y1; + x2 = x1; + y1 = x1 = 0; + } + return quadtree(points); + } + function quadtree(data) { + var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_; + if (x1 != null) { + x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2; + } else { + x2_ = y2_ = -(x1_ = y1_ = Infinity); + xs = [], ys = []; + n = data.length; + if (compat) for (i = 0; i < n; ++i) { + d = data[i]; + if (d.x < x1_) x1_ = d.x; + if (d.y < y1_) y1_ = d.y; + if (d.x > x2_) x2_ = d.x; + if (d.y > y2_) y2_ = d.y; + xs.push(d.x); + ys.push(d.y); + } else for (i = 0; i < n; ++i) { + var x_ = +fx(d = data[i], i), y_ = +fy(d, i); + if (x_ < x1_) x1_ = x_; + if (y_ < y1_) y1_ = y_; + if (x_ > x2_) x2_ = x_; + if (y_ > y2_) y2_ = y_; + xs.push(x_); + ys.push(y_); + } + } + var dx = x2_ - x1_, dy = y2_ - y1_; + if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy; + function insert(n, d, x, y, x1, y1, x2, y2) { + if (isNaN(x) || isNaN(y)) return; + if (n.leaf) { + var nx = n.x, ny = n.y; + if (nx != null) { + if (abs(nx - x) + abs(ny - y) < .01) { + insertChild(n, d, x, y, x1, y1, x2, y2); + } else { + var nPoint = n.point; + n.x = n.y = n.point = null; + insertChild(n, nPoint, nx, ny, x1, y1, x2, y2); + insertChild(n, d, x, y, x1, y1, x2, y2); + } + } else { + n.x = x, n.y = y, n.point = d; + } + } else { + insertChild(n, d, x, y, x1, y1, x2, y2); + } + } + function insertChild(n, d, x, y, x1, y1, x2, y2) { + var xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym, i = below << 1 | right; + n.leaf = false; + n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); + if (right) x1 = xm; else x2 = xm; + if (below) y1 = ym; else y2 = ym; + insert(n, d, x, y, x1, y1, x2, y2); + } + var root = d3_geom_quadtreeNode(); + root.add = function(d) { + insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_); + }; + root.visit = function(f) { + d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_); + }; + root.find = function(point) { + return d3_geom_quadtreeFind(root, point[0], point[1], x1_, y1_, x2_, y2_); + }; + i = -1; + if (x1 == null) { + while (++i < n) { + insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_); + } + --i; + } else data.forEach(root.add); + xs = ys = data = d = null; + return root; + } + quadtree.x = function(_) { + return arguments.length ? (x = _, quadtree) : x; + }; + quadtree.y = function(_) { + return arguments.length ? (y = _, quadtree) : y; + }; + quadtree.extent = function(_) { + if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ]; + if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], + y2 = +_[1][1]; + return quadtree; + }; + quadtree.size = function(_) { + if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ]; + if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1]; + return quadtree; + }; + return quadtree; + }; + function d3_geom_quadtreeCompatX(d) { + return d.x; + } + function d3_geom_quadtreeCompatY(d) { + return d.y; + } + function d3_geom_quadtreeNode() { + return { + leaf: true, + nodes: [], + point: null, + x: null, + y: null + }; + } + function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { + if (!f(node, x1, y1, x2, y2)) { + var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes; + if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); + if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); + if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); + if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); + } + } + function d3_geom_quadtreeFind(root, x, y, x0, y0, x3, y3) { + var minDistance2 = Infinity, closestPoint; + (function find(node, x1, y1, x2, y2) { + if (x1 > x3 || y1 > y3 || x2 < x0 || y2 < y0) return; + if (point = node.point) { + var point, dx = x - node.x, dy = y - node.y, distance2 = dx * dx + dy * dy; + if (distance2 < minDistance2) { + var distance = Math.sqrt(minDistance2 = distance2); + x0 = x - distance, y0 = y - distance; + x3 = x + distance, y3 = y + distance; + closestPoint = point; + } + } + var children = node.nodes, xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym; + for (var i = below << 1 | right, j = i + 4; i < j; ++i) { + if (node = children[i & 3]) switch (i & 3) { + case 0: + find(node, x1, y1, xm, ym); + break; + + case 1: + find(node, xm, y1, x2, ym); + break; + + case 2: + find(node, x1, ym, xm, y2); + break; + + case 3: + find(node, xm, ym, x2, y2); + break; + } + } + })(root, x0, y0, x3, y3); + return closestPoint; + } + d3.interpolateRgb = d3_interpolateRgb; + function d3_interpolateRgb(a, b) { + a = d3.rgb(a); + b = d3.rgb(b); + var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab; + return function(t) { + return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t)); + }; + } + d3.interpolateObject = d3_interpolateObject; + function d3_interpolateObject(a, b) { + var i = {}, c = {}, k; + for (k in a) { + if (k in b) { + i[k] = d3_interpolate(a[k], b[k]); + } else { + c[k] = a[k]; + } + } + for (k in b) { + if (!(k in a)) { + c[k] = b[k]; + } + } + return function(t) { + for (k in i) c[k] = i[k](t); + return c; + }; + } + d3.interpolateNumber = d3_interpolateNumber; + function d3_interpolateNumber(a, b) { + a = +a, b = +b; + return function(t) { + return a * (1 - t) + b * t; + }; + } + d3.interpolateString = d3_interpolateString; + function d3_interpolateString(a, b) { + var bi = d3_interpolate_numberA.lastIndex = d3_interpolate_numberB.lastIndex = 0, am, bm, bs, i = -1, s = [], q = []; + a = a + "", b = b + ""; + while ((am = d3_interpolate_numberA.exec(a)) && (bm = d3_interpolate_numberB.exec(b))) { + if ((bs = bm.index) > bi) { + bs = b.slice(bi, bs); + if (s[i]) s[i] += bs; else s[++i] = bs; + } + if ((am = am[0]) === (bm = bm[0])) { + if (s[i]) s[i] += bm; else s[++i] = bm; + } else { + s[++i] = null; + q.push({ + i: i, + x: d3_interpolateNumber(am, bm) + }); + } + bi = d3_interpolate_numberB.lastIndex; + } + if (bi < b.length) { + bs = b.slice(bi); + if (s[i]) s[i] += bs; else s[++i] = bs; + } + return s.length < 2 ? q[0] ? (b = q[0].x, function(t) { + return b(t) + ""; + }) : function() { + return b; + } : (b = q.length, function(t) { + for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }); + } + var d3_interpolate_numberA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, d3_interpolate_numberB = new RegExp(d3_interpolate_numberA.source, "g"); + d3.interpolate = d3_interpolate; + function d3_interpolate(a, b) { + var i = d3.interpolators.length, f; + while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ; + return f; + } + d3.interpolators = [ function(a, b) { + var t = typeof b; + return (t === "string" ? d3_rgb_names.has(b.toLowerCase()) || /^(#|rgb\(|hsl\()/i.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_color ? d3_interpolateRgb : Array.isArray(b) ? d3_interpolateArray : t === "object" && isNaN(b) ? d3_interpolateObject : d3_interpolateNumber)(a, b); + } ]; + d3.interpolateArray = d3_interpolateArray; + function d3_interpolateArray(a, b) { + var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i; + for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i])); + for (;i < na; ++i) c[i] = a[i]; + for (;i < nb; ++i) c[i] = b[i]; + return function(t) { + for (i = 0; i < n0; ++i) c[i] = x[i](t); + return c; + }; + } + var d3_ease_default = function() { + return d3_identity; + }; + var d3_ease = d3.map({ + linear: d3_ease_default, + poly: d3_ease_poly, + quad: function() { + return d3_ease_quad; + }, + cubic: function() { + return d3_ease_cubic; + }, + sin: function() { + return d3_ease_sin; + }, + exp: function() { + return d3_ease_exp; + }, + circle: function() { + return d3_ease_circle; + }, + elastic: d3_ease_elastic, + back: d3_ease_back, + bounce: function() { + return d3_ease_bounce; + } + }); + var d3_ease_mode = d3.map({ + "in": d3_identity, + out: d3_ease_reverse, + "in-out": d3_ease_reflect, + "out-in": function(f) { + return d3_ease_reflect(d3_ease_reverse(f)); + } + }); + d3.ease = function(name) { + var i = name.indexOf("-"), t = i >= 0 ? name.slice(0, i) : name, m = i >= 0 ? name.slice(i + 1) : "in"; + t = d3_ease.get(t) || d3_ease_default; + m = d3_ease_mode.get(m) || d3_identity; + return d3_ease_clamp(m(t.apply(null, d3_arraySlice.call(arguments, 1)))); + }; + function d3_ease_clamp(f) { + return function(t) { + return t <= 0 ? 0 : t >= 1 ? 1 : f(t); + }; + } + function d3_ease_reverse(f) { + return function(t) { + return 1 - f(1 - t); + }; + } + function d3_ease_reflect(f) { + return function(t) { + return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t)); + }; + } + function d3_ease_quad(t) { + return t * t; + } + function d3_ease_cubic(t) { + return t * t * t; + } + function d3_ease_cubicInOut(t) { + if (t <= 0) return 0; + if (t >= 1) return 1; + var t2 = t * t, t3 = t2 * t; + return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); + } + function d3_ease_poly(e) { + return function(t) { + return Math.pow(t, e); + }; + } + function d3_ease_sin(t) { + return 1 - Math.cos(t * halfπ); + } + function d3_ease_exp(t) { + return Math.pow(2, 10 * (t - 1)); + } + function d3_ease_circle(t) { + return 1 - Math.sqrt(1 - t * t); + } + function d3_ease_elastic(a, p) { + var s; + if (arguments.length < 2) p = .45; + if (arguments.length) s = p / τ * Math.asin(1 / a); else a = 1, s = p / 4; + return function(t) { + return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * τ / p); + }; + } + function d3_ease_back(s) { + if (!s) s = 1.70158; + return function(t) { + return t * t * ((s + 1) * t - s); + }; + } + function d3_ease_bounce(t) { + return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; + } + d3.interpolateHcl = d3_interpolateHcl; + function d3_interpolateHcl(a, b) { + a = d3.hcl(a); + b = d3.hcl(b); + var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al; + if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac; + if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; + return function(t) { + return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; + }; + } + d3.interpolateHsl = d3_interpolateHsl; + function d3_interpolateHsl(a, b) { + a = d3.hsl(a); + b = d3.hsl(b); + var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al; + if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as; + if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; + return function(t) { + return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + ""; + }; + } + d3.interpolateLab = d3_interpolateLab; + function d3_interpolateLab(a, b) { + a = d3.lab(a); + b = d3.lab(b); + var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab; + return function(t) { + return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; + }; + } + d3.interpolateRound = d3_interpolateRound; + function d3_interpolateRound(a, b) { + b -= a; + return function(t) { + return Math.round(a + b * t); + }; + } + d3.transform = function(string) { + var g = d3_document.createElementNS(d3.ns.prefix.svg, "g"); + return (d3.transform = function(string) { + if (string != null) { + g.setAttribute("transform", string); + var t = g.transform.baseVal.consolidate(); + } + return new d3_transform(t ? t.matrix : d3_transformIdentity); + })(string); + }; + function d3_transform(m) { + var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; + if (r0[0] * r1[1] < r1[0] * r0[1]) { + r0[0] *= -1; + r0[1] *= -1; + kx *= -1; + kz *= -1; + } + this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; + this.translate = [ m.e, m.f ]; + this.scale = [ kx, ky ]; + this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; + } + d3_transform.prototype.toString = function() { + return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")"; + }; + function d3_transformDot(a, b) { + return a[0] * b[0] + a[1] * b[1]; + } + function d3_transformNormalize(a) { + var k = Math.sqrt(d3_transformDot(a, a)); + if (k) { + a[0] /= k; + a[1] /= k; + } + return k; + } + function d3_transformCombine(a, b, k) { + a[0] += k * b[0]; + a[1] += k * b[1]; + return a; + } + var d3_transformIdentity = { + a: 1, + b: 0, + c: 0, + d: 1, + e: 0, + f: 0 + }; + d3.interpolateTransform = d3_interpolateTransform; + function d3_interpolateTransform(a, b) { + var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale; + if (ta[0] != tb[0] || ta[1] != tb[1]) { + s.push("translate(", null, ",", null, ")"); + q.push({ + i: 1, + x: d3_interpolateNumber(ta[0], tb[0]) + }, { + i: 3, + x: d3_interpolateNumber(ta[1], tb[1]) + }); + } else if (tb[0] || tb[1]) { + s.push("translate(" + tb + ")"); + } else { + s.push(""); + } + if (ra != rb) { + if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; + q.push({ + i: s.push(s.pop() + "rotate(", null, ")") - 2, + x: d3_interpolateNumber(ra, rb) + }); + } else if (rb) { + s.push(s.pop() + "rotate(" + rb + ")"); + } + if (wa != wb) { + q.push({ + i: s.push(s.pop() + "skewX(", null, ")") - 2, + x: d3_interpolateNumber(wa, wb) + }); + } else if (wb) { + s.push(s.pop() + "skewX(" + wb + ")"); + } + if (ka[0] != kb[0] || ka[1] != kb[1]) { + n = s.push(s.pop() + "scale(", null, ",", null, ")"); + q.push({ + i: n - 4, + x: d3_interpolateNumber(ka[0], kb[0]) + }, { + i: n - 2, + x: d3_interpolateNumber(ka[1], kb[1]) + }); + } else if (kb[0] != 1 || kb[1] != 1) { + s.push(s.pop() + "scale(" + kb + ")"); + } + n = q.length; + return function(t) { + var i = -1, o; + while (++i < n) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }; + } + function d3_uninterpolateNumber(a, b) { + b = (b -= a = +a) || 1 / b; + return function(x) { + return (x - a) / b; + }; + } + function d3_uninterpolateClamp(a, b) { + b = (b -= a = +a) || 1 / b; + return function(x) { + return Math.max(0, Math.min(1, (x - a) / b)); + }; + } + d3.layout = {}; + d3.layout.bundle = function() { + return function(links) { + var paths = [], i = -1, n = links.length; + while (++i < n) paths.push(d3_layout_bundlePath(links[i])); + return paths; + }; + }; + function d3_layout_bundlePath(link) { + var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ]; + while (start !== lca) { + start = start.parent; + points.push(start); + } + var k = points.length; + while (end !== lca) { + points.splice(k, 0, end); + end = end.parent; + } + return points; + } + function d3_layout_bundleAncestors(node) { + var ancestors = [], parent = node.parent; + while (parent != null) { + ancestors.push(node); + node = parent; + parent = parent.parent; + } + ancestors.push(node); + return ancestors; + } + function d3_layout_bundleLeastCommonAncestor(a, b) { + if (a === b) return a; + var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null; + while (aNode === bNode) { + sharedNode = aNode; + aNode = aNodes.pop(); + bNode = bNodes.pop(); + } + return sharedNode; + } + d3.layout.chord = function() { + var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; + function relayout() { + var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; + chords = []; + groups = []; + k = 0, i = -1; + while (++i < n) { + x = 0, j = -1; + while (++j < n) { + x += matrix[i][j]; + } + groupSums.push(x); + subgroupIndex.push(d3.range(n)); + k += x; + } + if (sortGroups) { + groupIndex.sort(function(a, b) { + return sortGroups(groupSums[a], groupSums[b]); + }); + } + if (sortSubgroups) { + subgroupIndex.forEach(function(d, i) { + d.sort(function(a, b) { + return sortSubgroups(matrix[i][a], matrix[i][b]); + }); + }); + } + k = (τ - padding * n) / k; + x = 0, i = -1; + while (++i < n) { + x0 = x, j = -1; + while (++j < n) { + var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; + subgroups[di + "-" + dj] = { + index: di, + subindex: dj, + startAngle: a0, + endAngle: a1, + value: v + }; + } + groups[di] = { + index: di, + startAngle: x0, + endAngle: x, + value: (x - x0) / k + }; + x += padding; + } + i = -1; + while (++i < n) { + j = i - 1; + while (++j < n) { + var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; + if (source.value || target.value) { + chords.push(source.value < target.value ? { + source: target, + target: source + } : { + source: source, + target: target + }); + } + } + } + if (sortChords) resort(); + } + function resort() { + chords.sort(function(a, b) { + return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); + }); + } + chord.matrix = function(x) { + if (!arguments.length) return matrix; + n = (matrix = x) && matrix.length; + chords = groups = null; + return chord; + }; + chord.padding = function(x) { + if (!arguments.length) return padding; + padding = x; + chords = groups = null; + return chord; + }; + chord.sortGroups = function(x) { + if (!arguments.length) return sortGroups; + sortGroups = x; + chords = groups = null; + return chord; + }; + chord.sortSubgroups = function(x) { + if (!arguments.length) return sortSubgroups; + sortSubgroups = x; + chords = null; + return chord; + }; + chord.sortChords = function(x) { + if (!arguments.length) return sortChords; + sortChords = x; + if (chords) resort(); + return chord; + }; + chord.chords = function() { + if (!chords) relayout(); + return chords; + }; + chord.groups = function() { + if (!groups) relayout(); + return groups; + }; + return chord; + }; + d3.layout.force = function() { + var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges; + function repulse(node) { + return function(quad, x1, _, x2) { + if (quad.point !== node) { + var dx = quad.cx - node.x, dy = quad.cy - node.y, dw = x2 - x1, dn = dx * dx + dy * dy; + if (dw * dw / theta2 < dn) { + if (dn < chargeDistance2) { + var k = quad.charge / dn; + node.px -= dx * k; + node.py -= dy * k; + } + return true; + } + if (quad.point && dn && dn < chargeDistance2) { + var k = quad.pointCharge / dn; + node.px -= dx * k; + node.py -= dy * k; + } + } + return !quad.charge; + }; + } + force.tick = function() { + if ((alpha *= .99) < .005) { + event.end({ + type: "end", + alpha: alpha = 0 + }); + return true; + } + var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y; + for (i = 0; i < m; ++i) { + o = links[i]; + s = o.source; + t = o.target; + x = t.x - s.x; + y = t.y - s.y; + if (l = x * x + y * y) { + l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; + x *= l; + y *= l; + t.x -= x * (k = s.weight / (t.weight + s.weight)); + t.y -= y * k; + s.x += x * (k = 1 - k); + s.y += y * k; + } + } + if (k = alpha * gravity) { + x = size[0] / 2; + y = size[1] / 2; + i = -1; + if (k) while (++i < n) { + o = nodes[i]; + o.x += (x - o.x) * k; + o.y += (y - o.y) * k; + } + } + if (charge) { + d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); + i = -1; + while (++i < n) { + if (!(o = nodes[i]).fixed) { + q.visit(repulse(o)); + } + } + } + i = -1; + while (++i < n) { + o = nodes[i]; + if (o.fixed) { + o.x = o.px; + o.y = o.py; + } else { + o.x -= (o.px - (o.px = o.x)) * friction; + o.y -= (o.py - (o.py = o.y)) * friction; + } + } + event.tick({ + type: "tick", + alpha: alpha + }); + }; + force.nodes = function(x) { + if (!arguments.length) return nodes; + nodes = x; + return force; + }; + force.links = function(x) { + if (!arguments.length) return links; + links = x; + return force; + }; + force.size = function(x) { + if (!arguments.length) return size; + size = x; + return force; + }; + force.linkDistance = function(x) { + if (!arguments.length) return linkDistance; + linkDistance = typeof x === "function" ? x : +x; + return force; + }; + force.distance = force.linkDistance; + force.linkStrength = function(x) { + if (!arguments.length) return linkStrength; + linkStrength = typeof x === "function" ? x : +x; + return force; + }; + force.friction = function(x) { + if (!arguments.length) return friction; + friction = +x; + return force; + }; + force.charge = function(x) { + if (!arguments.length) return charge; + charge = typeof x === "function" ? x : +x; + return force; + }; + force.chargeDistance = function(x) { + if (!arguments.length) return Math.sqrt(chargeDistance2); + chargeDistance2 = x * x; + return force; + }; + force.gravity = function(x) { + if (!arguments.length) return gravity; + gravity = +x; + return force; + }; + force.theta = function(x) { + if (!arguments.length) return Math.sqrt(theta2); + theta2 = x * x; + return force; + }; + force.alpha = function(x) { + if (!arguments.length) return alpha; + x = +x; + if (alpha) { + if (x > 0) alpha = x; else alpha = 0; + } else if (x > 0) { + event.start({ + type: "start", + alpha: alpha = x + }); + d3.timer(force.tick); + } + return force; + }; + force.start = function() { + var i, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o; + for (i = 0; i < n; ++i) { + (o = nodes[i]).index = i; + o.weight = 0; + } + for (i = 0; i < m; ++i) { + o = links[i]; + if (typeof o.source == "number") o.source = nodes[o.source]; + if (typeof o.target == "number") o.target = nodes[o.target]; + ++o.source.weight; + ++o.target.weight; + } + for (i = 0; i < n; ++i) { + o = nodes[i]; + if (isNaN(o.x)) o.x = position("x", w); + if (isNaN(o.y)) o.y = position("y", h); + if (isNaN(o.px)) o.px = o.x; + if (isNaN(o.py)) o.py = o.y; + } + distances = []; + if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance; + strengths = []; + if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength; + charges = []; + if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge; + function position(dimension, size) { + if (!neighbors) { + neighbors = new Array(n); + for (j = 0; j < n; ++j) { + neighbors[j] = []; + } + for (j = 0; j < m; ++j) { + var o = links[j]; + neighbors[o.source.index].push(o.target); + neighbors[o.target.index].push(o.source); + } + } + var candidates = neighbors[i], j = -1, l = candidates.length, x; + while (++j < l) if (!isNaN(x = candidates[j][dimension])) return x; + return Math.random() * size; + } + return force.resume(); + }; + force.resume = function() { + return force.alpha(.1); + }; + force.stop = function() { + return force.alpha(0); + }; + force.drag = function() { + if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend); + if (!arguments.length) return drag; + this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag); + }; + function dragmove(d) { + d.px = d3.event.x, d.py = d3.event.y; + force.resume(); + } + return d3.rebind(force, event, "on"); + }; + function d3_layout_forceDragstart(d) { + d.fixed |= 2; + } + function d3_layout_forceDragend(d) { + d.fixed &= ~6; + } + function d3_layout_forceMouseover(d) { + d.fixed |= 4; + d.px = d.x, d.py = d.y; + } + function d3_layout_forceMouseout(d) { + d.fixed &= ~4; + } + function d3_layout_forceAccumulate(quad, alpha, charges) { + var cx = 0, cy = 0; + quad.charge = 0; + if (!quad.leaf) { + var nodes = quad.nodes, n = nodes.length, i = -1, c; + while (++i < n) { + c = nodes[i]; + if (c == null) continue; + d3_layout_forceAccumulate(c, alpha, charges); + quad.charge += c.charge; + cx += c.charge * c.cx; + cy += c.charge * c.cy; + } + } + if (quad.point) { + if (!quad.leaf) { + quad.point.x += Math.random() - .5; + quad.point.y += Math.random() - .5; + } + var k = alpha * charges[quad.point.index]; + quad.charge += quad.pointCharge = k; + cx += k * quad.point.x; + cy += k * quad.point.y; + } + quad.cx = cx / quad.charge; + quad.cy = cy / quad.charge; + } + var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1, d3_layout_forceChargeDistance2 = Infinity; + d3.layout.hierarchy = function() { + var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue; + function hierarchy(root) { + var stack = [ root ], nodes = [], node; + root.depth = 0; + while ((node = stack.pop()) != null) { + nodes.push(node); + if ((childs = children.call(hierarchy, node, node.depth)) && (n = childs.length)) { + var n, childs, child; + while (--n >= 0) { + stack.push(child = childs[n]); + child.parent = node; + child.depth = node.depth + 1; + } + if (value) node.value = 0; + node.children = childs; + } else { + if (value) node.value = +value.call(hierarchy, node, node.depth) || 0; + delete node.children; + } + } + d3_layout_hierarchyVisitAfter(root, function(node) { + var childs, parent; + if (sort && (childs = node.children)) childs.sort(sort); + if (value && (parent = node.parent)) parent.value += node.value; + }); + return nodes; + } + hierarchy.sort = function(x) { + if (!arguments.length) return sort; + sort = x; + return hierarchy; + }; + hierarchy.children = function(x) { + if (!arguments.length) return children; + children = x; + return hierarchy; + }; + hierarchy.value = function(x) { + if (!arguments.length) return value; + value = x; + return hierarchy; + }; + hierarchy.revalue = function(root) { + if (value) { + d3_layout_hierarchyVisitBefore(root, function(node) { + if (node.children) node.value = 0; + }); + d3_layout_hierarchyVisitAfter(root, function(node) { + var parent; + if (!node.children) node.value = +value.call(hierarchy, node, node.depth) || 0; + if (parent = node.parent) parent.value += node.value; + }); + } + return root; + }; + return hierarchy; + }; + function d3_layout_hierarchyRebind(object, hierarchy) { + d3.rebind(object, hierarchy, "sort", "children", "value"); + object.nodes = object; + object.links = d3_layout_hierarchyLinks; + return object; + } + function d3_layout_hierarchyVisitBefore(node, callback) { + var nodes = [ node ]; + while ((node = nodes.pop()) != null) { + callback(node); + if ((children = node.children) && (n = children.length)) { + var n, children; + while (--n >= 0) nodes.push(children[n]); + } + } + } + function d3_layout_hierarchyVisitAfter(node, callback) { + var nodes = [ node ], nodes2 = []; + while ((node = nodes.pop()) != null) { + nodes2.push(node); + if ((children = node.children) && (n = children.length)) { + var i = -1, n, children; + while (++i < n) nodes.push(children[i]); + } + } + while ((node = nodes2.pop()) != null) { + callback(node); + } + } + function d3_layout_hierarchyChildren(d) { + return d.children; + } + function d3_layout_hierarchyValue(d) { + return d.value; + } + function d3_layout_hierarchySort(a, b) { + return b.value - a.value; + } + function d3_layout_hierarchyLinks(nodes) { + return d3.merge(nodes.map(function(parent) { + return (parent.children || []).map(function(child) { + return { + source: parent, + target: child + }; + }); + })); + } + d3.layout.partition = function() { + var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ]; + function position(node, x, dx, dy) { + var children = node.children; + node.x = x; + node.y = node.depth * dy; + node.dx = dx; + node.dy = dy; + if (children && (n = children.length)) { + var i = -1, n, c, d; + dx = node.value ? dx / node.value : 0; + while (++i < n) { + position(c = children[i], x, d = c.value * dx, dy); + x += d; + } + } + } + function depth(node) { + var children = node.children, d = 0; + if (children && (n = children.length)) { + var i = -1, n; + while (++i < n) d = Math.max(d, depth(children[i])); + } + return 1 + d; + } + function partition(d, i) { + var nodes = hierarchy.call(this, d, i); + position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); + return nodes; + } + partition.size = function(x) { + if (!arguments.length) return size; + size = x; + return partition; + }; + return d3_layout_hierarchyRebind(partition, hierarchy); + }; + d3.layout.pie = function() { + var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = τ, padAngle = 0; + function pie(data) { + var n = data.length, values = data.map(function(d, i) { + return +value.call(pie, d, i); + }), a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle), da = (typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a, p = Math.min(Math.abs(da) / n, +(typeof padAngle === "function" ? padAngle.apply(this, arguments) : padAngle)), pa = p * (da < 0 ? -1 : 1), k = (da - n * pa) / d3.sum(values), index = d3.range(n), arcs = [], v; + if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) { + return values[j] - values[i]; + } : function(i, j) { + return sort(data[i], data[j]); + }); + index.forEach(function(i) { + arcs[i] = { + data: data[i], + value: v = values[i], + startAngle: a, + endAngle: a += v * k + pa, + padAngle: p + }; + }); + return arcs; + } + pie.value = function(_) { + if (!arguments.length) return value; + value = _; + return pie; + }; + pie.sort = function(_) { + if (!arguments.length) return sort; + sort = _; + return pie; + }; + pie.startAngle = function(_) { + if (!arguments.length) return startAngle; + startAngle = _; + return pie; + }; + pie.endAngle = function(_) { + if (!arguments.length) return endAngle; + endAngle = _; + return pie; + }; + pie.padAngle = function(_) { + if (!arguments.length) return padAngle; + padAngle = _; + return pie; + }; + return pie; + }; + var d3_layout_pieSortByValue = {}; + d3.layout.stack = function() { + var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY; + function stack(data, index) { + if (!(n = data.length)) return data; + var series = data.map(function(d, i) { + return values.call(stack, d, i); + }); + var points = series.map(function(d) { + return d.map(function(v, i) { + return [ x.call(stack, v, i), y.call(stack, v, i) ]; + }); + }); + var orders = order.call(stack, points, index); + series = d3.permute(series, orders); + points = d3.permute(points, orders); + var offsets = offset.call(stack, points, index); + var m = series[0].length, n, i, j, o; + for (j = 0; j < m; ++j) { + out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); + for (i = 1; i < n; ++i) { + out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); + } + } + return data; + } + stack.values = function(x) { + if (!arguments.length) return values; + values = x; + return stack; + }; + stack.order = function(x) { + if (!arguments.length) return order; + order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; + return stack; + }; + stack.offset = function(x) { + if (!arguments.length) return offset; + offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; + return stack; + }; + stack.x = function(z) { + if (!arguments.length) return x; + x = z; + return stack; + }; + stack.y = function(z) { + if (!arguments.length) return y; + y = z; + return stack; + }; + stack.out = function(z) { + if (!arguments.length) return out; + out = z; + return stack; + }; + return stack; + }; + function d3_layout_stackX(d) { + return d.x; + } + function d3_layout_stackY(d) { + return d.y; + } + function d3_layout_stackOut(d, y0, y) { + d.y0 = y0; + d.y = y; + } + var d3_layout_stackOrders = d3.map({ + "inside-out": function(data) { + var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) { + return max[a] - max[b]; + }), top = 0, bottom = 0, tops = [], bottoms = []; + for (i = 0; i < n; ++i) { + j = index[i]; + if (top < bottom) { + top += sums[j]; + tops.push(j); + } else { + bottom += sums[j]; + bottoms.push(j); + } + } + return bottoms.reverse().concat(tops); + }, + reverse: function(data) { + return d3.range(data.length).reverse(); + }, + "default": d3_layout_stackOrderDefault + }); + var d3_layout_stackOffsets = d3.map({ + silhouette: function(data) { + var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = []; + for (j = 0; j < m; ++j) { + for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; + if (o > max) max = o; + sums.push(o); + } + for (j = 0; j < m; ++j) { + y0[j] = (max - sums[j]) / 2; + } + return y0; + }, + wiggle: function(data) { + var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = []; + y0[0] = o = o0 = 0; + for (j = 1; j < m; ++j) { + for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; + for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { + for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { + s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; + } + s2 += s3 * data[i][j][1]; + } + y0[j] = o -= s1 ? s2 / s1 * dx : 0; + if (o < o0) o0 = o; + } + for (j = 0; j < m; ++j) y0[j] -= o0; + return y0; + }, + expand: function(data) { + var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = []; + for (j = 0; j < m; ++j) { + for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; + if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k; + } + for (j = 0; j < m; ++j) y0[j] = 0; + return y0; + }, + zero: d3_layout_stackOffsetZero + }); + function d3_layout_stackOrderDefault(data) { + return d3.range(data.length); + } + function d3_layout_stackOffsetZero(data) { + var j = -1, m = data[0].length, y0 = []; + while (++j < m) y0[j] = 0; + return y0; + } + function d3_layout_stackMaxIndex(array) { + var i = 1, j = 0, v = array[0][1], k, n = array.length; + for (;i < n; ++i) { + if ((k = array[i][1]) > v) { + j = i; + v = k; + } + } + return j; + } + function d3_layout_stackReduceSum(d) { + return d.reduce(d3_layout_stackSum, 0); + } + function d3_layout_stackSum(p, d) { + return p + d[1]; + } + d3.layout.histogram = function() { + var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges; + function histogram(data, i) { + var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x; + while (++i < m) { + bin = bins[i] = []; + bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); + bin.y = 0; + } + if (m > 0) { + i = -1; + while (++i < n) { + x = values[i]; + if (x >= range[0] && x <= range[1]) { + bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; + bin.y += k; + bin.push(data[i]); + } + } + } + return bins; + } + histogram.value = function(x) { + if (!arguments.length) return valuer; + valuer = x; + return histogram; + }; + histogram.range = function(x) { + if (!arguments.length) return ranger; + ranger = d3_functor(x); + return histogram; + }; + histogram.bins = function(x) { + if (!arguments.length) return binner; + binner = typeof x === "number" ? function(range) { + return d3_layout_histogramBinFixed(range, x); + } : d3_functor(x); + return histogram; + }; + histogram.frequency = function(x) { + if (!arguments.length) return frequency; + frequency = !!x; + return histogram; + }; + return histogram; + }; + function d3_layout_histogramBinSturges(range, values) { + return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); + } + function d3_layout_histogramBinFixed(range, n) { + var x = -1, b = +range[0], m = (range[1] - b) / n, f = []; + while (++x <= n) f[x] = m * x + b; + return f; + } + function d3_layout_histogramRange(values) { + return [ d3.min(values), d3.max(values) ]; + } + d3.layout.pack = function() { + var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius; + function pack(d, i) { + var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() { + return radius; + }; + root.x = root.y = 0; + d3_layout_hierarchyVisitAfter(root, function(d) { + d.r = +r(d.value); + }); + d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings); + if (padding) { + var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2; + d3_layout_hierarchyVisitAfter(root, function(d) { + d.r += dr; + }); + d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings); + d3_layout_hierarchyVisitAfter(root, function(d) { + d.r -= dr; + }); + } + d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h)); + return nodes; + } + pack.size = function(_) { + if (!arguments.length) return size; + size = _; + return pack; + }; + pack.radius = function(_) { + if (!arguments.length) return radius; + radius = _ == null || typeof _ === "function" ? _ : +_; + return pack; + }; + pack.padding = function(_) { + if (!arguments.length) return padding; + padding = +_; + return pack; + }; + return d3_layout_hierarchyRebind(pack, hierarchy); + }; + function d3_layout_packSort(a, b) { + return a.value - b.value; + } + function d3_layout_packInsert(a, b) { + var c = a._pack_next; + a._pack_next = b; + b._pack_prev = a; + b._pack_next = c; + c._pack_prev = b; + } + function d3_layout_packSplice(a, b) { + a._pack_next = b; + b._pack_prev = a; + } + function d3_layout_packIntersects(a, b) { + var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; + return .999 * dr * dr > dx * dx + dy * dy; + } + function d3_layout_packSiblings(node) { + if (!(nodes = node.children) || !(n = nodes.length)) return; + var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n; + function bound(node) { + xMin = Math.min(node.x - node.r, xMin); + xMax = Math.max(node.x + node.r, xMax); + yMin = Math.min(node.y - node.r, yMin); + yMax = Math.max(node.y + node.r, yMax); + } + nodes.forEach(d3_layout_packLink); + a = nodes[0]; + a.x = -a.r; + a.y = 0; + bound(a); + if (n > 1) { + b = nodes[1]; + b.x = b.r; + b.y = 0; + bound(b); + if (n > 2) { + c = nodes[2]; + d3_layout_packPlace(a, b, c); + bound(c); + d3_layout_packInsert(a, c); + a._pack_prev = c; + d3_layout_packInsert(c, b); + b = a._pack_next; + for (i = 3; i < n; i++) { + d3_layout_packPlace(a, b, c = nodes[i]); + var isect = 0, s1 = 1, s2 = 1; + for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { + if (d3_layout_packIntersects(j, c)) { + isect = 1; + break; + } + } + if (isect == 1) { + for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { + if (d3_layout_packIntersects(k, c)) { + break; + } + } + } + if (isect) { + if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b); + i--; + } else { + d3_layout_packInsert(a, c); + b = c; + bound(c); + } + } + } + } + var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0; + for (i = 0; i < n; i++) { + c = nodes[i]; + c.x -= cx; + c.y -= cy; + cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); + } + node.r = cr; + nodes.forEach(d3_layout_packUnlink); + } + function d3_layout_packLink(node) { + node._pack_next = node._pack_prev = node; + } + function d3_layout_packUnlink(node) { + delete node._pack_next; + delete node._pack_prev; + } + function d3_layout_packTransform(node, x, y, k) { + var children = node.children; + node.x = x += k * node.x; + node.y = y += k * node.y; + node.r *= k; + if (children) { + var i = -1, n = children.length; + while (++i < n) d3_layout_packTransform(children[i], x, y, k); + } + } + function d3_layout_packPlace(a, b, c) { + var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y; + if (db && (dx || dy)) { + var da = b.r + c.r, dc = dx * dx + dy * dy; + da *= da; + db *= db; + var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); + c.x = a.x + x * dx + y * dy; + c.y = a.y + x * dy - y * dx; + } else { + c.x = a.x + db; + c.y = a.y; + } + } + d3.layout.tree = function() { + var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = null; + function tree(d, i) { + var nodes = hierarchy.call(this, d, i), root0 = nodes[0], root1 = wrapTree(root0); + d3_layout_hierarchyVisitAfter(root1, firstWalk), root1.parent.m = -root1.z; + d3_layout_hierarchyVisitBefore(root1, secondWalk); + if (nodeSize) d3_layout_hierarchyVisitBefore(root0, sizeNode); else { + var left = root0, right = root0, bottom = root0; + d3_layout_hierarchyVisitBefore(root0, function(node) { + if (node.x < left.x) left = node; + if (node.x > right.x) right = node; + if (node.depth > bottom.depth) bottom = node; + }); + var tx = separation(left, right) / 2 - left.x, kx = size[0] / (right.x + separation(right, left) / 2 + tx), ky = size[1] / (bottom.depth || 1); + d3_layout_hierarchyVisitBefore(root0, function(node) { + node.x = (node.x + tx) * kx; + node.y = node.depth * ky; + }); + } + return nodes; + } + function wrapTree(root0) { + var root1 = { + A: null, + children: [ root0 ] + }, queue = [ root1 ], node1; + while ((node1 = queue.pop()) != null) { + for (var children = node1.children, child, i = 0, n = children.length; i < n; ++i) { + queue.push((children[i] = child = { + _: children[i], + parent: node1, + children: (child = children[i].children) && child.slice() || [], + A: null, + a: null, + z: 0, + m: 0, + c: 0, + s: 0, + t: null, + i: i + }).a = child); + } + } + return root1.children[0]; + } + function firstWalk(v) { + var children = v.children, siblings = v.parent.children, w = v.i ? siblings[v.i - 1] : null; + if (children.length) { + d3_layout_treeShift(v); + var midpoint = (children[0].z + children[children.length - 1].z) / 2; + if (w) { + v.z = w.z + separation(v._, w._); + v.m = v.z - midpoint; + } else { + v.z = midpoint; + } + } else if (w) { + v.z = w.z + separation(v._, w._); + } + v.parent.A = apportion(v, w, v.parent.A || siblings[0]); + } + function secondWalk(v) { + v._.x = v.z + v.parent.m; + v.m += v.parent.m; + } + function apportion(v, w, ancestor) { + if (w) { + var vip = v, vop = v, vim = w, vom = vip.parent.children[0], sip = vip.m, sop = vop.m, sim = vim.m, som = vom.m, shift; + while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { + vom = d3_layout_treeLeft(vom); + vop = d3_layout_treeRight(vop); + vop.a = v; + shift = vim.z + sim - vip.z - sip + separation(vim._, vip._); + if (shift > 0) { + d3_layout_treeMove(d3_layout_treeAncestor(vim, v, ancestor), v, shift); + sip += shift; + sop += shift; + } + sim += vim.m; + sip += vip.m; + som += vom.m; + sop += vop.m; + } + if (vim && !d3_layout_treeRight(vop)) { + vop.t = vim; + vop.m += sim - sop; + } + if (vip && !d3_layout_treeLeft(vom)) { + vom.t = vip; + vom.m += sip - som; + ancestor = v; + } + } + return ancestor; + } + function sizeNode(node) { + node.x *= size[0]; + node.y = node.depth * size[1]; + } + tree.separation = function(x) { + if (!arguments.length) return separation; + separation = x; + return tree; + }; + tree.size = function(x) { + if (!arguments.length) return nodeSize ? null : size; + nodeSize = (size = x) == null ? sizeNode : null; + return tree; + }; + tree.nodeSize = function(x) { + if (!arguments.length) return nodeSize ? size : null; + nodeSize = (size = x) == null ? null : sizeNode; + return tree; + }; + return d3_layout_hierarchyRebind(tree, hierarchy); + }; + function d3_layout_treeSeparation(a, b) { + return a.parent == b.parent ? 1 : 2; + } + function d3_layout_treeLeft(v) { + var children = v.children; + return children.length ? children[0] : v.t; + } + function d3_layout_treeRight(v) { + var children = v.children, n; + return (n = children.length) ? children[n - 1] : v.t; + } + function d3_layout_treeMove(wm, wp, shift) { + var change = shift / (wp.i - wm.i); + wp.c -= change; + wp.s += shift; + wm.c += change; + wp.z += shift; + wp.m += shift; + } + function d3_layout_treeShift(v) { + var shift = 0, change = 0, children = v.children, i = children.length, w; + while (--i >= 0) { + w = children[i]; + w.z += shift; + w.m += shift; + shift += w.s + (change += w.c); + } + } + function d3_layout_treeAncestor(vim, v, ancestor) { + return vim.a.parent === v.parent ? vim.a : ancestor; + } + d3.layout.cluster = function() { + var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; + function cluster(d, i) { + var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0; + d3_layout_hierarchyVisitAfter(root, function(node) { + var children = node.children; + if (children && children.length) { + node.x = d3_layout_clusterX(children); + node.y = d3_layout_clusterY(children); + } else { + node.x = previousNode ? x += separation(node, previousNode) : 0; + node.y = 0; + previousNode = node; + } + }); + var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; + d3_layout_hierarchyVisitAfter(root, nodeSize ? function(node) { + node.x = (node.x - root.x) * size[0]; + node.y = (root.y - node.y) * size[1]; + } : function(node) { + node.x = (node.x - x0) / (x1 - x0) * size[0]; + node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; + }); + return nodes; + } + cluster.separation = function(x) { + if (!arguments.length) return separation; + separation = x; + return cluster; + }; + cluster.size = function(x) { + if (!arguments.length) return nodeSize ? null : size; + nodeSize = (size = x) == null; + return cluster; + }; + cluster.nodeSize = function(x) { + if (!arguments.length) return nodeSize ? size : null; + nodeSize = (size = x) != null; + return cluster; + }; + return d3_layout_hierarchyRebind(cluster, hierarchy); + }; + function d3_layout_clusterY(children) { + return 1 + d3.max(children, function(child) { + return child.y; + }); + } + function d3_layout_clusterX(children) { + return children.reduce(function(x, child) { + return x + child.x; + }, 0) / children.length; + } + function d3_layout_clusterLeft(node) { + var children = node.children; + return children && children.length ? d3_layout_clusterLeft(children[0]) : node; + } + function d3_layout_clusterRight(node) { + var children = node.children, n; + return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; + } + d3.layout.treemap = function() { + var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5)); + function scale(children, k) { + var i = -1, n = children.length, child, area; + while (++i < n) { + area = (child = children[i]).value * (k < 0 ? 0 : k); + child.area = isNaN(area) || area <= 0 ? 0 : area; + } + } + function squarify(node) { + var children = node.children; + if (children && children.length) { + var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n; + scale(remaining, rect.dx * rect.dy / node.value); + row.area = 0; + while ((n = remaining.length) > 0) { + row.push(child = remaining[n - 1]); + row.area += child.area; + if (mode !== "squarify" || (score = worst(row, u)) <= best) { + remaining.pop(); + best = score; + } else { + row.area -= row.pop().area; + position(row, u, rect, false); + u = Math.min(rect.dx, rect.dy); + row.length = row.area = 0; + best = Infinity; + } + } + if (row.length) { + position(row, u, rect, true); + row.length = row.area = 0; + } + children.forEach(squarify); + } + } + function stickify(node) { + var children = node.children; + if (children && children.length) { + var rect = pad(node), remaining = children.slice(), child, row = []; + scale(remaining, rect.dx * rect.dy / node.value); + row.area = 0; + while (child = remaining.pop()) { + row.push(child); + row.area += child.area; + if (child.z != null) { + position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); + row.length = row.area = 0; + } + } + children.forEach(stickify); + } + } + function worst(row, u) { + var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length; + while (++i < n) { + if (!(r = row[i].area)) continue; + if (r < rmin) rmin = r; + if (r > rmax) rmax = r; + } + s *= s; + u *= u; + return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity; + } + function position(row, u, rect, flush) { + var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o; + if (u == rect.dx) { + if (flush || v > rect.dy) v = rect.dy; + while (++i < n) { + o = row[i]; + o.x = x; + o.y = y; + o.dy = v; + x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); + } + o.z = true; + o.dx += rect.x + rect.dx - x; + rect.y += v; + rect.dy -= v; + } else { + if (flush || v > rect.dx) v = rect.dx; + while (++i < n) { + o = row[i]; + o.x = x; + o.y = y; + o.dx = v; + y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); + } + o.z = false; + o.dy += rect.y + rect.dy - y; + rect.x += v; + rect.dx -= v; + } + } + function treemap(d) { + var nodes = stickies || hierarchy(d), root = nodes[0]; + root.x = 0; + root.y = 0; + root.dx = size[0]; + root.dy = size[1]; + if (stickies) hierarchy.revalue(root); + scale([ root ], root.dx * root.dy / root.value); + (stickies ? stickify : squarify)(root); + if (sticky) stickies = nodes; + return nodes; + } + treemap.size = function(x) { + if (!arguments.length) return size; + size = x; + return treemap; + }; + treemap.padding = function(x) { + if (!arguments.length) return padding; + function padFunction(node) { + var p = x.call(treemap, node, node.depth); + return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p); + } + function padConstant(node) { + return d3_layout_treemapPad(node, x); + } + var type; + pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], + padConstant) : padConstant; + return treemap; + }; + treemap.round = function(x) { + if (!arguments.length) return round != Number; + round = x ? Math.round : Number; + return treemap; + }; + treemap.sticky = function(x) { + if (!arguments.length) return sticky; + sticky = x; + stickies = null; + return treemap; + }; + treemap.ratio = function(x) { + if (!arguments.length) return ratio; + ratio = x; + return treemap; + }; + treemap.mode = function(x) { + if (!arguments.length) return mode; + mode = x + ""; + return treemap; + }; + return d3_layout_hierarchyRebind(treemap, hierarchy); + }; + function d3_layout_treemapPadNull(node) { + return { + x: node.x, + y: node.y, + dx: node.dx, + dy: node.dy + }; + } + function d3_layout_treemapPad(node, padding) { + var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2]; + if (dx < 0) { + x += dx / 2; + dx = 0; + } + if (dy < 0) { + y += dy / 2; + dy = 0; + } + return { + x: x, + y: y, + dx: dx, + dy: dy + }; + } + d3.random = { + normal: function(µ, σ) { + var n = arguments.length; + if (n < 2) σ = 1; + if (n < 1) µ = 0; + return function() { + var x, y, r; + do { + x = Math.random() * 2 - 1; + y = Math.random() * 2 - 1; + r = x * x + y * y; + } while (!r || r > 1); + return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r); + }; + }, + logNormal: function() { + var random = d3.random.normal.apply(d3, arguments); + return function() { + return Math.exp(random()); + }; + }, + bates: function(m) { + var random = d3.random.irwinHall(m); + return function() { + return random() / m; + }; + }, + irwinHall: function(m) { + return function() { + for (var s = 0, j = 0; j < m; j++) s += Math.random(); + return s; + }; + } + }; + d3.scale = {}; + function d3_scaleExtent(domain) { + var start = domain[0], stop = domain[domain.length - 1]; + return start < stop ? [ start, stop ] : [ stop, start ]; + } + function d3_scaleRange(scale) { + return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); + } + function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { + var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]); + return function(x) { + return i(u(x)); + }; + } + function d3_scale_nice(domain, nice) { + var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx; + if (x1 < x0) { + dx = i0, i0 = i1, i1 = dx; + dx = x0, x0 = x1, x1 = dx; + } + domain[i0] = nice.floor(x0); + domain[i1] = nice.ceil(x1); + return domain; + } + function d3_scale_niceStep(step) { + return step ? { + floor: function(x) { + return Math.floor(x / step) * step; + }, + ceil: function(x) { + return Math.ceil(x / step) * step; + } + } : d3_scale_niceIdentity; + } + var d3_scale_niceIdentity = { + floor: d3_identity, + ceil: d3_identity + }; + function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { + var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1; + if (domain[k] < domain[0]) { + domain = domain.slice().reverse(); + range = range.slice().reverse(); + } + while (++j <= k) { + u.push(uninterpolate(domain[j - 1], domain[j])); + i.push(interpolate(range[j - 1], range[j])); + } + return function(x) { + var j = d3.bisect(domain, x, 1, k) - 1; + return i[j](u[j](x)); + }; + } + d3.scale.linear = function() { + return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false); + }; + function d3_scale_linear(domain, range, interpolate, clamp) { + var output, input; + function rescale() { + var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; + output = linear(domain, range, uninterpolate, interpolate); + input = linear(range, domain, uninterpolate, d3_interpolate); + return scale; + } + function scale(x) { + return output(x); + } + scale.invert = function(y) { + return input(y); + }; + scale.domain = function(x) { + if (!arguments.length) return domain; + domain = x.map(Number); + return rescale(); + }; + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + return rescale(); + }; + scale.rangeRound = function(x) { + return scale.range(x).interpolate(d3_interpolateRound); + }; + scale.clamp = function(x) { + if (!arguments.length) return clamp; + clamp = x; + return rescale(); + }; + scale.interpolate = function(x) { + if (!arguments.length) return interpolate; + interpolate = x; + return rescale(); + }; + scale.ticks = function(m) { + return d3_scale_linearTicks(domain, m); + }; + scale.tickFormat = function(m, format) { + return d3_scale_linearTickFormat(domain, m, format); + }; + scale.nice = function(m) { + d3_scale_linearNice(domain, m); + return rescale(); + }; + scale.copy = function() { + return d3_scale_linear(domain, range, interpolate, clamp); + }; + return rescale(); + } + function d3_scale_linearRebind(scale, linear) { + return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); + } + function d3_scale_linearNice(domain, m) { + return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2])); + } + function d3_scale_linearTickRange(domain, m) { + if (m == null) m = 10; + var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; + if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; + extent[0] = Math.ceil(extent[0] / step) * step; + extent[1] = Math.floor(extent[1] / step) * step + step * .5; + extent[2] = step; + return extent; + } + function d3_scale_linearTicks(domain, m) { + return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); + } + function d3_scale_linearTickFormat(domain, m, format) { + var range = d3_scale_linearTickRange(domain, m); + if (format) { + var match = d3_format_re.exec(format); + match.shift(); + if (match[8] === "s") { + var prefix = d3.formatPrefix(Math.max(abs(range[0]), abs(range[1]))); + if (!match[7]) match[7] = "." + d3_scale_linearPrecision(prefix.scale(range[2])); + match[8] = "f"; + format = d3.format(match.join("")); + return function(d) { + return format(prefix.scale(d)) + prefix.symbol; + }; + } + if (!match[7]) match[7] = "." + d3_scale_linearFormatPrecision(match[8], range); + format = match.join(""); + } else { + format = ",." + d3_scale_linearPrecision(range[2]) + "f"; + } + return d3.format(format); + } + var d3_scale_linearFormatSignificant = { + s: 1, + g: 1, + p: 1, + r: 1, + e: 1 + }; + function d3_scale_linearPrecision(value) { + return -Math.floor(Math.log(value) / Math.LN10 + .01); + } + function d3_scale_linearFormatPrecision(type, range) { + var p = d3_scale_linearPrecision(range[2]); + return type in d3_scale_linearFormatSignificant ? Math.abs(p - d3_scale_linearPrecision(Math.max(abs(range[0]), abs(range[1])))) + +(type !== "e") : p - (type === "%") * 2; + } + d3.scale.log = function() { + return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]); + }; + function d3_scale_log(linear, base, positive, domain) { + function log(x) { + return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base); + } + function pow(x) { + return positive ? Math.pow(base, x) : -Math.pow(base, -x); + } + function scale(x) { + return linear(log(x)); + } + scale.invert = function(x) { + return pow(linear.invert(x)); + }; + scale.domain = function(x) { + if (!arguments.length) return domain; + positive = x[0] >= 0; + linear.domain((domain = x.map(Number)).map(log)); + return scale; + }; + scale.base = function(_) { + if (!arguments.length) return base; + base = +_; + linear.domain(domain.map(log)); + return scale; + }; + scale.nice = function() { + var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative); + linear.domain(niced); + domain = niced.map(pow); + return scale; + }; + scale.ticks = function() { + var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base; + if (isFinite(j - i)) { + if (positive) { + for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k); + ticks.push(pow(i)); + } else { + ticks.push(pow(i)); + for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k); + } + for (i = 0; ticks[i] < u; i++) {} + for (j = ticks.length; ticks[j - 1] > v; j--) {} + ticks = ticks.slice(i, j); + } + return ticks; + }; + scale.tickFormat = function(n, format) { + if (!arguments.length) return d3_scale_logFormat; + if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format); + var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12, + Math.floor), e; + return function(d) { + return d / pow(f(log(d) + e)) <= k ? format(d) : ""; + }; + }; + scale.copy = function() { + return d3_scale_log(linear.copy(), base, positive, domain); + }; + return d3_scale_linearRebind(scale, linear); + } + var d3_scale_logFormat = d3.format(".0e"), d3_scale_logNiceNegative = { + floor: function(x) { + return -Math.ceil(-x); + }, + ceil: function(x) { + return -Math.floor(-x); + } + }; + d3.scale.pow = function() { + return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]); + }; + function d3_scale_pow(linear, exponent, domain) { + var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent); + function scale(x) { + return linear(powp(x)); + } + scale.invert = function(x) { + return powb(linear.invert(x)); + }; + scale.domain = function(x) { + if (!arguments.length) return domain; + linear.domain((domain = x.map(Number)).map(powp)); + return scale; + }; + scale.ticks = function(m) { + return d3_scale_linearTicks(domain, m); + }; + scale.tickFormat = function(m, format) { + return d3_scale_linearTickFormat(domain, m, format); + }; + scale.nice = function(m) { + return scale.domain(d3_scale_linearNice(domain, m)); + }; + scale.exponent = function(x) { + if (!arguments.length) return exponent; + powp = d3_scale_powPow(exponent = x); + powb = d3_scale_powPow(1 / exponent); + linear.domain(domain.map(powp)); + return scale; + }; + scale.copy = function() { + return d3_scale_pow(linear.copy(), exponent, domain); + }; + return d3_scale_linearRebind(scale, linear); + } + function d3_scale_powPow(e) { + return function(x) { + return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); + }; + } + d3.scale.sqrt = function() { + return d3.scale.pow().exponent(.5); + }; + d3.scale.ordinal = function() { + return d3_scale_ordinal([], { + t: "range", + a: [ [] ] + }); + }; + function d3_scale_ordinal(domain, ranger) { + var index, range, rangeBand; + function scale(x) { + return range[((index.get(x) || (ranger.t === "range" ? index.set(x, domain.push(x)) : NaN)) - 1) % range.length]; + } + function steps(start, step) { + return d3.range(domain.length).map(function(i) { + return start + step * i; + }); + } + scale.domain = function(x) { + if (!arguments.length) return domain; + domain = []; + index = new d3_Map(); + var i = -1, n = x.length, xi; + while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); + return scale[ranger.t].apply(scale, ranger.a); + }; + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + rangeBand = 0; + ranger = { + t: "range", + a: arguments + }; + return scale; + }; + scale.rangePoints = function(x, padding) { + if (arguments.length < 2) padding = 0; + var start = x[0], stop = x[1], step = domain.length < 2 ? (start = (start + stop) / 2, + 0) : (stop - start) / (domain.length - 1 + padding); + range = steps(start + step * padding / 2, step); + rangeBand = 0; + ranger = { + t: "rangePoints", + a: arguments + }; + return scale; + }; + scale.rangeRoundPoints = function(x, padding) { + if (arguments.length < 2) padding = 0; + var start = x[0], stop = x[1], step = domain.length < 2 ? (start = stop = Math.round((start + stop) / 2), + 0) : (stop - start) / (domain.length - 1 + padding) | 0; + range = steps(start + Math.round(step * padding / 2 + (stop - start - (domain.length - 1 + padding) * step) / 2), step); + rangeBand = 0; + ranger = { + t: "rangeRoundPoints", + a: arguments + }; + return scale; + }; + scale.rangeBands = function(x, padding, outerPadding) { + if (arguments.length < 2) padding = 0; + if (arguments.length < 3) outerPadding = padding; + var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding); + range = steps(start + step * outerPadding, step); + if (reverse) range.reverse(); + rangeBand = step * (1 - padding); + ranger = { + t: "rangeBands", + a: arguments + }; + return scale; + }; + scale.rangeRoundBands = function(x, padding, outerPadding) { + if (arguments.length < 2) padding = 0; + if (arguments.length < 3) outerPadding = padding; + var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)); + range = steps(start + Math.round((stop - start - (domain.length - padding) * step) / 2), step); + if (reverse) range.reverse(); + rangeBand = Math.round(step * (1 - padding)); + ranger = { + t: "rangeRoundBands", + a: arguments + }; + return scale; + }; + scale.rangeBand = function() { + return rangeBand; + }; + scale.rangeExtent = function() { + return d3_scaleExtent(ranger.a[0]); + }; + scale.copy = function() { + return d3_scale_ordinal(domain, ranger); + }; + return scale.domain(domain); + } + d3.scale.category10 = function() { + return d3.scale.ordinal().range(d3_category10); + }; + d3.scale.category20 = function() { + return d3.scale.ordinal().range(d3_category20); + }; + d3.scale.category20b = function() { + return d3.scale.ordinal().range(d3_category20b); + }; + d3.scale.category20c = function() { + return d3.scale.ordinal().range(d3_category20c); + }; + var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString); + var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString); + var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString); + var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString); + d3.scale.quantile = function() { + return d3_scale_quantile([], []); + }; + function d3_scale_quantile(domain, range) { + var thresholds; + function rescale() { + var k = 0, q = range.length; + thresholds = []; + while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); + return scale; + } + function scale(x) { + if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)]; + } + scale.domain = function(x) { + if (!arguments.length) return domain; + domain = x.map(d3_number).filter(d3_numeric).sort(d3_ascending); + return rescale(); + }; + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + return rescale(); + }; + scale.quantiles = function() { + return thresholds; + }; + scale.invertExtent = function(y) { + y = range.indexOf(y); + return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ]; + }; + scale.copy = function() { + return d3_scale_quantile(domain, range); + }; + return rescale(); + } + d3.scale.quantize = function() { + return d3_scale_quantize(0, 1, [ 0, 1 ]); + }; + function d3_scale_quantize(x0, x1, range) { + var kx, i; + function scale(x) { + return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; + } + function rescale() { + kx = range.length / (x1 - x0); + i = range.length - 1; + return scale; + } + scale.domain = function(x) { + if (!arguments.length) return [ x0, x1 ]; + x0 = +x[0]; + x1 = +x[x.length - 1]; + return rescale(); + }; + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + return rescale(); + }; + scale.invertExtent = function(y) { + y = range.indexOf(y); + y = y < 0 ? NaN : y / kx + x0; + return [ y, y + 1 / kx ]; + }; + scale.copy = function() { + return d3_scale_quantize(x0, x1, range); + }; + return rescale(); + } + d3.scale.threshold = function() { + return d3_scale_threshold([ .5 ], [ 0, 1 ]); + }; + function d3_scale_threshold(domain, range) { + function scale(x) { + if (x <= x) return range[d3.bisect(domain, x)]; + } + scale.domain = function(_) { + if (!arguments.length) return domain; + domain = _; + return scale; + }; + scale.range = function(_) { + if (!arguments.length) return range; + range = _; + return scale; + }; + scale.invertExtent = function(y) { + y = range.indexOf(y); + return [ domain[y - 1], domain[y] ]; + }; + scale.copy = function() { + return d3_scale_threshold(domain, range); + }; + return scale; + } + d3.scale.identity = function() { + return d3_scale_identity([ 0, 1 ]); + }; + function d3_scale_identity(domain) { + function identity(x) { + return +x; + } + identity.invert = identity; + identity.domain = identity.range = function(x) { + if (!arguments.length) return domain; + domain = x.map(identity); + return identity; + }; + identity.ticks = function(m) { + return d3_scale_linearTicks(domain, m); + }; + identity.tickFormat = function(m, format) { + return d3_scale_linearTickFormat(domain, m, format); + }; + identity.copy = function() { + return d3_scale_identity(domain); + }; + return identity; + } + d3.svg = {}; + function d3_zero() { + return 0; + } + d3.svg.arc = function() { + var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, cornerRadius = d3_zero, padRadius = d3_svg_arcAuto, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle, padAngle = d3_svg_arcPadAngle; + function arc() { + var r0 = Math.max(0, +innerRadius.apply(this, arguments)), r1 = Math.max(0, +outerRadius.apply(this, arguments)), a0 = startAngle.apply(this, arguments) - halfπ, a1 = endAngle.apply(this, arguments) - halfπ, da = Math.abs(a1 - a0), cw = a0 > a1 ? 0 : 1; + if (r1 < r0) rc = r1, r1 = r0, r0 = rc; + if (da >= τε) return circleSegment(r1, cw) + (r0 ? circleSegment(r0, 1 - cw) : "") + "Z"; + var rc, cr, rp, ap, p0 = 0, p1 = 0, x0, y0, x1, y1, x2, y2, x3, y3, path = []; + if (ap = (+padAngle.apply(this, arguments) || 0) / 2) { + rp = padRadius === d3_svg_arcAuto ? Math.sqrt(r0 * r0 + r1 * r1) : +padRadius.apply(this, arguments); + if (!cw) p1 *= -1; + if (r1) p1 = d3_asin(rp / r1 * Math.sin(ap)); + if (r0) p0 = d3_asin(rp / r0 * Math.sin(ap)); + } + if (r1) { + x0 = r1 * Math.cos(a0 + p1); + y0 = r1 * Math.sin(a0 + p1); + x1 = r1 * Math.cos(a1 - p1); + y1 = r1 * Math.sin(a1 - p1); + var l1 = Math.abs(a1 - a0 - 2 * p1) <= π ? 0 : 1; + if (p1 && d3_svg_arcSweep(x0, y0, x1, y1) === cw ^ l1) { + var h1 = (a0 + a1) / 2; + x0 = r1 * Math.cos(h1); + y0 = r1 * Math.sin(h1); + x1 = y1 = null; + } + } else { + x0 = y0 = 0; + } + if (r0) { + x2 = r0 * Math.cos(a1 - p0); + y2 = r0 * Math.sin(a1 - p0); + x3 = r0 * Math.cos(a0 + p0); + y3 = r0 * Math.sin(a0 + p0); + var l0 = Math.abs(a0 - a1 + 2 * p0) <= π ? 0 : 1; + if (p0 && d3_svg_arcSweep(x2, y2, x3, y3) === 1 - cw ^ l0) { + var h0 = (a0 + a1) / 2; + x2 = r0 * Math.cos(h0); + y2 = r0 * Math.sin(h0); + x3 = y3 = null; + } + } else { + x2 = y2 = 0; + } + if ((rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments))) > .001) { + cr = r0 < r1 ^ cw ? 0 : 1; + var oc = x3 == null ? [ x2, y2 ] : x1 == null ? [ x0, y0 ] : d3_geom_polygonIntersect([ x0, y0 ], [ x3, y3 ], [ x1, y1 ], [ x2, y2 ]), ax = x0 - oc[0], ay = y0 - oc[1], bx = x1 - oc[0], by = y1 - oc[1], kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2), lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]); + if (x1 != null) { + var rc1 = Math.min(rc, (r1 - lc) / (kc + 1)), t30 = d3_svg_arcCornerTangents(x3 == null ? [ x2, y2 ] : [ x3, y3 ], [ x0, y0 ], r1, rc1, cw), t12 = d3_svg_arcCornerTangents([ x1, y1 ], [ x2, y2 ], r1, rc1, cw); + if (rc === rc1) { + path.push("M", t30[0], "A", rc1, ",", rc1, " 0 0,", cr, " ", t30[1], "A", r1, ",", r1, " 0 ", 1 - cw ^ d3_svg_arcSweep(t30[1][0], t30[1][1], t12[1][0], t12[1][1]), ",", cw, " ", t12[1], "A", rc1, ",", rc1, " 0 0,", cr, " ", t12[0]); + } else { + path.push("M", t30[0], "A", rc1, ",", rc1, " 0 1,", cr, " ", t12[0]); + } + } else { + path.push("M", x0, ",", y0); + } + if (x3 != null) { + var rc0 = Math.min(rc, (r0 - lc) / (kc - 1)), t03 = d3_svg_arcCornerTangents([ x0, y0 ], [ x3, y3 ], r0, -rc0, cw), t21 = d3_svg_arcCornerTangents([ x2, y2 ], x1 == null ? [ x0, y0 ] : [ x1, y1 ], r0, -rc0, cw); + if (rc === rc0) { + path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t21[1], "A", r0, ",", r0, " 0 ", cw ^ d3_svg_arcSweep(t21[1][0], t21[1][1], t03[1][0], t03[1][1]), ",", 1 - cw, " ", t03[1], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]); + } else { + path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]); + } + } else { + path.push("L", x2, ",", y2); + } + } else { + path.push("M", x0, ",", y0); + if (x1 != null) path.push("A", r1, ",", r1, " 0 ", l1, ",", cw, " ", x1, ",", y1); + path.push("L", x2, ",", y2); + if (x3 != null) path.push("A", r0, ",", r0, " 0 ", l0, ",", 1 - cw, " ", x3, ",", y3); + } + path.push("Z"); + return path.join(""); + } + function circleSegment(r1, cw) { + return "M0," + r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + -r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + r1; + } + arc.innerRadius = function(v) { + if (!arguments.length) return innerRadius; + innerRadius = d3_functor(v); + return arc; + }; + arc.outerRadius = function(v) { + if (!arguments.length) return outerRadius; + outerRadius = d3_functor(v); + return arc; + }; + arc.cornerRadius = function(v) { + if (!arguments.length) return cornerRadius; + cornerRadius = d3_functor(v); + return arc; + }; + arc.padRadius = function(v) { + if (!arguments.length) return padRadius; + padRadius = v == d3_svg_arcAuto ? d3_svg_arcAuto : d3_functor(v); + return arc; + }; + arc.startAngle = function(v) { + if (!arguments.length) return startAngle; + startAngle = d3_functor(v); + return arc; + }; + arc.endAngle = function(v) { + if (!arguments.length) return endAngle; + endAngle = d3_functor(v); + return arc; + }; + arc.padAngle = function(v) { + if (!arguments.length) return padAngle; + padAngle = d3_functor(v); + return arc; + }; + arc.centroid = function() { + var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - halfπ; + return [ Math.cos(a) * r, Math.sin(a) * r ]; + }; + return arc; + }; + var d3_svg_arcAuto = "auto"; + function d3_svg_arcInnerRadius(d) { + return d.innerRadius; + } + function d3_svg_arcOuterRadius(d) { + return d.outerRadius; + } + function d3_svg_arcStartAngle(d) { + return d.startAngle; + } + function d3_svg_arcEndAngle(d) { + return d.endAngle; + } + function d3_svg_arcPadAngle(d) { + return d && d.padAngle; + } + function d3_svg_arcSweep(x0, y0, x1, y1) { + return (x0 - x1) * y0 - (y0 - y1) * x0 > 0 ? 0 : 1; + } + function d3_svg_arcCornerTangents(p0, p1, r1, rc, cw) { + var x01 = p0[0] - p1[0], y01 = p0[1] - p1[1], lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x1 = p0[0] + ox, y1 = p0[1] + oy, x2 = p1[0] + ox, y2 = p1[1] + oy, x3 = (x1 + x2) / 2, y3 = (y1 + y2) / 2, dx = x2 - x1, dy = y2 - y1, d2 = dx * dx + dy * dy, r = r1 - rc, D = x1 * y2 - x2 * y1, d = (dy < 0 ? -1 : 1) * Math.sqrt(r * r * d2 - D * D), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x3, dy0 = cy0 - y3, dx1 = cx1 - x3, dy1 = cy1 - y3; + if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; + return [ [ cx0 - ox, cy0 - oy ], [ cx0 * r1 / r, cy0 * r1 / r ] ]; + } + function d3_svg_line(projection) { + var x = d3_geom_pointX, y = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7; + function line(data) { + var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y); + function segment() { + segments.push("M", interpolate(projection(points), tension)); + } + while (++i < n) { + if (defined.call(this, d = data[i], i)) { + points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]); + } else if (points.length) { + segment(); + points = []; + } + } + if (points.length) segment(); + return segments.length ? segments.join("") : null; + } + line.x = function(_) { + if (!arguments.length) return x; + x = _; + return line; + }; + line.y = function(_) { + if (!arguments.length) return y; + y = _; + return line; + }; + line.defined = function(_) { + if (!arguments.length) return defined; + defined = _; + return line; + }; + line.interpolate = function(_) { + if (!arguments.length) return interpolateKey; + if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; + return line; + }; + line.tension = function(_) { + if (!arguments.length) return tension; + tension = _; + return line; + }; + return line; + } + d3.svg.line = function() { + return d3_svg_line(d3_identity); + }; + var d3_svg_lineInterpolators = d3.map({ + linear: d3_svg_lineLinear, + "linear-closed": d3_svg_lineLinearClosed, + step: d3_svg_lineStep, + "step-before": d3_svg_lineStepBefore, + "step-after": d3_svg_lineStepAfter, + basis: d3_svg_lineBasis, + "basis-open": d3_svg_lineBasisOpen, + "basis-closed": d3_svg_lineBasisClosed, + bundle: d3_svg_lineBundle, + cardinal: d3_svg_lineCardinal, + "cardinal-open": d3_svg_lineCardinalOpen, + "cardinal-closed": d3_svg_lineCardinalClosed, + monotone: d3_svg_lineMonotone + }); + d3_svg_lineInterpolators.forEach(function(key, value) { + value.key = key; + value.closed = /-closed$/.test(key); + }); + function d3_svg_lineLinear(points) { + return points.join("L"); + } + function d3_svg_lineLinearClosed(points) { + return d3_svg_lineLinear(points) + "Z"; + } + function d3_svg_lineStep(points) { + var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; + while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]); + if (n > 1) path.push("H", p[0]); + return path.join(""); + } + function d3_svg_lineStepBefore(points) { + var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; + while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); + return path.join(""); + } + function d3_svg_lineStepAfter(points) { + var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; + while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); + return path.join(""); + } + function d3_svg_lineCardinalOpen(points, tension) { + return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, -1), d3_svg_lineCardinalTangents(points, tension)); + } + function d3_svg_lineCardinalClosed(points, tension) { + return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), + points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension)); + } + function d3_svg_lineCardinal(points, tension) { + return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension)); + } + function d3_svg_lineHermite(points, tangents) { + if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) { + return d3_svg_lineLinear(points); + } + var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1; + if (quad) { + path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1]; + p0 = points[1]; + pi = 2; + } + if (tangents.length > 1) { + t = tangents[1]; + p = points[pi]; + pi++; + path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; + for (var i = 2; i < tangents.length; i++, pi++) { + p = points[pi]; + t = tangents[i]; + path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; + } + } + if (quad) { + var lp = points[pi]; + path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1]; + } + return path; + } + function d3_svg_lineCardinalTangents(points, tension) { + var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length; + while (++i < n) { + p0 = p1; + p1 = p2; + p2 = points[i]; + tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]); + } + return tangents; + } + function d3_svg_lineBasis(points) { + if (points.length < 3) return d3_svg_lineLinear(points); + var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; + points.push(points[n - 1]); + while (++i <= n) { + pi = points[i]; + px.shift(); + px.push(pi[0]); + py.shift(); + py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + points.pop(); + path.push("L", pi); + return path.join(""); + } + function d3_svg_lineBasisOpen(points) { + if (points.length < 4) return d3_svg_lineLinear(points); + var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ]; + while (++i < 3) { + pi = points[i]; + px.push(pi[0]); + py.push(pi[1]); + } + path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); + --i; + while (++i < n) { + pi = points[i]; + px.shift(); + px.push(pi[0]); + py.shift(); + py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + return path.join(""); + } + function d3_svg_lineBasisClosed(points) { + var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = []; + while (++i < 4) { + pi = points[i % n]; + px.push(pi[0]); + py.push(pi[1]); + } + path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; + --i; + while (++i < m) { + pi = points[i % n]; + px.shift(); + px.push(pi[0]); + py.shift(); + py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + return path.join(""); + } + function d3_svg_lineBundle(points, tension) { + var n = points.length - 1; + if (n) { + var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t; + while (++i <= n) { + p = points[i]; + t = i / n; + p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); + p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); + } + } + return d3_svg_lineBasis(points); + } + function d3_svg_lineDot4(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; + } + var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ]; + function d3_svg_lineBasisBezier(path, x, y) { + path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); + } + function d3_svg_lineSlope(p0, p1) { + return (p1[1] - p0[1]) / (p1[0] - p0[0]); + } + function d3_svg_lineFiniteDifferences(points) { + var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1); + while (++i < j) { + m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; + } + m[i] = d; + return m; + } + function d3_svg_lineMonotoneTangents(points) { + var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1; + while (++i < j) { + d = d3_svg_lineSlope(points[i], points[i + 1]); + if (abs(d) < ε) { + m[i] = m[i + 1] = 0; + } else { + a = m[i] / d; + b = m[i + 1] / d; + s = a * a + b * b; + if (s > 9) { + s = d * 3 / Math.sqrt(s); + m[i] = s * a; + m[i + 1] = s * b; + } + } + } + i = -1; + while (++i <= j) { + s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); + tangents.push([ s || 0, m[i] * s || 0 ]); + } + return tangents; + } + function d3_svg_lineMonotone(points) { + return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); + } + d3.svg.line.radial = function() { + var line = d3_svg_line(d3_svg_lineRadial); + line.radius = line.x, delete line.x; + line.angle = line.y, delete line.y; + return line; + }; + function d3_svg_lineRadial(points) { + var point, i = -1, n = points.length, r, a; + while (++i < n) { + point = points[i]; + r = point[0]; + a = point[1] - halfπ; + point[0] = r * Math.cos(a); + point[1] = r * Math.sin(a); + } + return points; + } + function d3_svg_area(projection) { + var x0 = d3_geom_pointX, x1 = d3_geom_pointX, y0 = 0, y1 = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7; + function area(data) { + var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() { + return x; + } : d3_functor(x1), fy1 = y0 === y1 ? function() { + return y; + } : d3_functor(y1), x, y; + function segment() { + segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z"); + } + while (++i < n) { + if (defined.call(this, d = data[i], i)) { + points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]); + points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]); + } else if (points0.length) { + segment(); + points0 = []; + points1 = []; + } + } + if (points0.length) segment(); + return segments.length ? segments.join("") : null; + } + area.x = function(_) { + if (!arguments.length) return x1; + x0 = x1 = _; + return area; + }; + area.x0 = function(_) { + if (!arguments.length) return x0; + x0 = _; + return area; + }; + area.x1 = function(_) { + if (!arguments.length) return x1; + x1 = _; + return area; + }; + area.y = function(_) { + if (!arguments.length) return y1; + y0 = y1 = _; + return area; + }; + area.y0 = function(_) { + if (!arguments.length) return y0; + y0 = _; + return area; + }; + area.y1 = function(_) { + if (!arguments.length) return y1; + y1 = _; + return area; + }; + area.defined = function(_) { + if (!arguments.length) return defined; + defined = _; + return area; + }; + area.interpolate = function(_) { + if (!arguments.length) return interpolateKey; + if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; + interpolateReverse = interpolate.reverse || interpolate; + L = interpolate.closed ? "M" : "L"; + return area; + }; + area.tension = function(_) { + if (!arguments.length) return tension; + tension = _; + return area; + }; + return area; + } + d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; + d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; + d3.svg.area = function() { + return d3_svg_area(d3_identity); + }; + d3.svg.area.radial = function() { + var area = d3_svg_area(d3_svg_lineRadial); + area.radius = area.x, delete area.x; + area.innerRadius = area.x0, delete area.x0; + area.outerRadius = area.x1, delete area.x1; + area.angle = area.y, delete area.y; + area.startAngle = area.y0, delete area.y0; + area.endAngle = area.y1, delete area.y1; + return area; + }; + d3.svg.chord = function() { + var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; + function chord(d, i) { + var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i); + return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z"; + } + function subgroup(self, f, d, i) { + var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) - halfπ, a1 = endAngle.call(self, subgroup, i) - halfπ; + return { + r: r, + a0: a0, + a1: a1, + p0: [ r * Math.cos(a0), r * Math.sin(a0) ], + p1: [ r * Math.cos(a1), r * Math.sin(a1) ] + }; + } + function equals(a, b) { + return a.a0 == b.a0 && a.a1 == b.a1; + } + function arc(r, p, a) { + return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p; + } + function curve(r0, p0, r1, p1) { + return "Q 0,0 " + p1; + } + chord.radius = function(v) { + if (!arguments.length) return radius; + radius = d3_functor(v); + return chord; + }; + chord.source = function(v) { + if (!arguments.length) return source; + source = d3_functor(v); + return chord; + }; + chord.target = function(v) { + if (!arguments.length) return target; + target = d3_functor(v); + return chord; + }; + chord.startAngle = function(v) { + if (!arguments.length) return startAngle; + startAngle = d3_functor(v); + return chord; + }; + chord.endAngle = function(v) { + if (!arguments.length) return endAngle; + endAngle = d3_functor(v); + return chord; + }; + return chord; + }; + function d3_svg_chordRadius(d) { + return d.radius; + } + d3.svg.diagonal = function() { + var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection; + function diagonal(d, i) { + var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { + x: p0.x, + y: m + }, { + x: p3.x, + y: m + }, p3 ]; + p = p.map(projection); + return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; + } + diagonal.source = function(x) { + if (!arguments.length) return source; + source = d3_functor(x); + return diagonal; + }; + diagonal.target = function(x) { + if (!arguments.length) return target; + target = d3_functor(x); + return diagonal; + }; + diagonal.projection = function(x) { + if (!arguments.length) return projection; + projection = x; + return diagonal; + }; + return diagonal; + }; + function d3_svg_diagonalProjection(d) { + return [ d.x, d.y ]; + } + d3.svg.diagonal.radial = function() { + var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection; + diagonal.projection = function(x) { + return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection; + }; + return diagonal; + }; + function d3_svg_diagonalRadialProjection(projection) { + return function() { + var d = projection.apply(this, arguments), r = d[0], a = d[1] - halfπ; + return [ r * Math.cos(a), r * Math.sin(a) ]; + }; + } + d3.svg.symbol = function() { + var type = d3_svg_symbolType, size = d3_svg_symbolSize; + function symbol(d, i) { + return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i)); + } + symbol.type = function(x) { + if (!arguments.length) return type; + type = d3_functor(x); + return symbol; + }; + symbol.size = function(x) { + if (!arguments.length) return size; + size = d3_functor(x); + return symbol; + }; + return symbol; + }; + function d3_svg_symbolSize() { + return 64; + } + function d3_svg_symbolType() { + return "circle"; + } + function d3_svg_symbolCircle(size) { + var r = Math.sqrt(size / π); + return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z"; + } + var d3_svg_symbols = d3.map({ + circle: d3_svg_symbolCircle, + cross: function(size) { + var r = Math.sqrt(size / 5) / 2; + return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z"; + }, + diamond: function(size) { + var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30; + return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z"; + }, + square: function(size) { + var r = Math.sqrt(size) / 2; + return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z"; + }, + "triangle-down": function(size) { + var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; + return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z"; + }, + "triangle-up": function(size) { + var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; + return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z"; + } + }); + d3.svg.symbolTypes = d3_svg_symbols.keys(); + var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians); + d3_selectionPrototype.transition = function(name) { + var id = d3_transitionInheritId || ++d3_transitionId, ns = d3_transitionNamespace(name), subgroups = [], subgroup, node, transition = d3_transitionInherit || { + time: Date.now(), + ease: d3_ease_cubicInOut, + delay: 0, + duration: 250 + }; + for (var j = -1, m = this.length; ++j < m; ) { + subgroups.push(subgroup = []); + for (var group = this[j], i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) d3_transitionNode(node, i, ns, id, transition); + subgroup.push(node); + } + } + return d3_transition(subgroups, ns, id); + }; + d3_selectionPrototype.interrupt = function(name) { + return this.each(name == null ? d3_selection_interrupt : d3_selection_interruptNS(d3_transitionNamespace(name))); + }; + var d3_selection_interrupt = d3_selection_interruptNS(d3_transitionNamespace()); + function d3_selection_interruptNS(ns) { + return function() { + var lock, active; + if ((lock = this[ns]) && (active = lock[lock.active])) { + if (--lock.count) delete lock[lock.active]; else delete this[ns]; + lock.active += .5; + active.event && active.event.interrupt.call(this, this.__data__, active.index); + } + }; + } + function d3_transition(groups, ns, id) { + d3_subclass(groups, d3_transitionPrototype); + groups.namespace = ns; + groups.id = id; + return groups; + } + var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit; + d3_transitionPrototype.call = d3_selectionPrototype.call; + d3_transitionPrototype.empty = d3_selectionPrototype.empty; + d3_transitionPrototype.node = d3_selectionPrototype.node; + d3_transitionPrototype.size = d3_selectionPrototype.size; + d3.transition = function(selection, name) { + return selection && selection.transition ? d3_transitionInheritId ? selection.transition(name) : selection : d3.selection().transition(selection); + }; + d3.transition.prototype = d3_transitionPrototype; + d3_transitionPrototype.select = function(selector) { + var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnode, node; + selector = d3_selection_selector(selector); + for (var j = -1, m = this.length; ++j < m; ) { + subgroups.push(subgroup = []); + for (var group = this[j], i = -1, n = group.length; ++i < n; ) { + if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) { + if ("__data__" in node) subnode.__data__ = node.__data__; + d3_transitionNode(subnode, i, ns, id, node[ns][id]); + subgroup.push(subnode); + } else { + subgroup.push(null); + } + } + } + return d3_transition(subgroups, ns, id); + }; + d3_transitionPrototype.selectAll = function(selector) { + var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnodes, node, subnode, transition; + selector = d3_selection_selectorAll(selector); + for (var j = -1, m = this.length; ++j < m; ) { + for (var group = this[j], i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) { + transition = node[ns][id]; + subnodes = selector.call(node, node.__data__, i, j); + subgroups.push(subgroup = []); + for (var k = -1, o = subnodes.length; ++k < o; ) { + if (subnode = subnodes[k]) d3_transitionNode(subnode, k, ns, id, transition); + subgroup.push(subnode); + } + } + } + } + return d3_transition(subgroups, ns, id); + }; + d3_transitionPrototype.filter = function(filter) { + var subgroups = [], subgroup, group, node; + if (typeof filter !== "function") filter = d3_selection_filter(filter); + for (var j = 0, m = this.length; j < m; j++) { + subgroups.push(subgroup = []); + for (var group = this[j], i = 0, n = group.length; i < n; i++) { + if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { + subgroup.push(node); + } + } + } + return d3_transition(subgroups, this.namespace, this.id); + }; + d3_transitionPrototype.tween = function(name, tween) { + var id = this.id, ns = this.namespace; + if (arguments.length < 2) return this.node()[ns][id].tween.get(name); + return d3_selection_each(this, tween == null ? function(node) { + node[ns][id].tween.remove(name); + } : function(node) { + node[ns][id].tween.set(name, tween); + }); + }; + function d3_transition_tween(groups, name, value, tween) { + var id = groups.id, ns = groups.namespace; + return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) { + node[ns][id].tween.set(name, tween(value.call(node, node.__data__, i, j))); + } : (value = tween(value), function(node) { + node[ns][id].tween.set(name, value); + })); + } + d3_transitionPrototype.attr = function(nameNS, value) { + if (arguments.length < 2) { + for (value in nameNS) this.attr(value, nameNS[value]); + return this; + } + var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS); + function attrNull() { + this.removeAttribute(name); + } + function attrNullNS() { + this.removeAttributeNS(name.space, name.local); + } + function attrTween(b) { + return b == null ? attrNull : (b += "", function() { + var a = this.getAttribute(name), i; + return a !== b && (i = interpolate(a, b), function(t) { + this.setAttribute(name, i(t)); + }); + }); + } + function attrTweenNS(b) { + return b == null ? attrNullNS : (b += "", function() { + var a = this.getAttributeNS(name.space, name.local), i; + return a !== b && (i = interpolate(a, b), function(t) { + this.setAttributeNS(name.space, name.local, i(t)); + }); + }); + } + return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween); + }; + d3_transitionPrototype.attrTween = function(nameNS, tween) { + var name = d3.ns.qualify(nameNS); + function attrTween(d, i) { + var f = tween.call(this, d, i, this.getAttribute(name)); + return f && function(t) { + this.setAttribute(name, f(t)); + }; + } + function attrTweenNS(d, i) { + var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); + return f && function(t) { + this.setAttributeNS(name.space, name.local, f(t)); + }; + } + return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); + }; + d3_transitionPrototype.style = function(name, value, priority) { + var n = arguments.length; + if (n < 3) { + if (typeof name !== "string") { + if (n < 2) value = ""; + for (priority in name) this.style(priority, name[priority], value); + return this; + } + priority = ""; + } + function styleNull() { + this.style.removeProperty(name); + } + function styleString(b) { + return b == null ? styleNull : (b += "", function() { + var a = d3_window(this).getComputedStyle(this, null).getPropertyValue(name), i; + return a !== b && (i = d3_interpolate(a, b), function(t) { + this.style.setProperty(name, i(t), priority); + }); + }); + } + return d3_transition_tween(this, "style." + name, value, styleString); + }; + d3_transitionPrototype.styleTween = function(name, tween, priority) { + if (arguments.length < 3) priority = ""; + function styleTween(d, i) { + var f = tween.call(this, d, i, d3_window(this).getComputedStyle(this, null).getPropertyValue(name)); + return f && function(t) { + this.style.setProperty(name, f(t), priority); + }; + } + return this.tween("style." + name, styleTween); + }; + d3_transitionPrototype.text = function(value) { + return d3_transition_tween(this, "text", value, d3_transition_text); + }; + function d3_transition_text(b) { + if (b == null) b = ""; + return function() { + this.textContent = b; + }; + } + d3_transitionPrototype.remove = function() { + var ns = this.namespace; + return this.each("end.transition", function() { + var p; + if (this[ns].count < 2 && (p = this.parentNode)) p.removeChild(this); + }); + }; + d3_transitionPrototype.ease = function(value) { + var id = this.id, ns = this.namespace; + if (arguments.length < 1) return this.node()[ns][id].ease; + if (typeof value !== "function") value = d3.ease.apply(d3, arguments); + return d3_selection_each(this, function(node) { + node[ns][id].ease = value; + }); + }; + d3_transitionPrototype.delay = function(value) { + var id = this.id, ns = this.namespace; + if (arguments.length < 1) return this.node()[ns][id].delay; + return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { + node[ns][id].delay = +value.call(node, node.__data__, i, j); + } : (value = +value, function(node) { + node[ns][id].delay = value; + })); + }; + d3_transitionPrototype.duration = function(value) { + var id = this.id, ns = this.namespace; + if (arguments.length < 1) return this.node()[ns][id].duration; + return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { + node[ns][id].duration = Math.max(1, value.call(node, node.__data__, i, j)); + } : (value = Math.max(1, value), function(node) { + node[ns][id].duration = value; + })); + }; + d3_transitionPrototype.each = function(type, listener) { + var id = this.id, ns = this.namespace; + if (arguments.length < 2) { + var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId; + try { + d3_transitionInheritId = id; + d3_selection_each(this, function(node, i, j) { + d3_transitionInherit = node[ns][id]; + type.call(node, node.__data__, i, j); + }); + } finally { + d3_transitionInherit = inherit; + d3_transitionInheritId = inheritId; + } + } else { + d3_selection_each(this, function(node) { + var transition = node[ns][id]; + (transition.event || (transition.event = d3.dispatch("start", "end", "interrupt"))).on(type, listener); + }); + } + return this; + }; + d3_transitionPrototype.transition = function() { + var id0 = this.id, id1 = ++d3_transitionId, ns = this.namespace, subgroups = [], subgroup, group, node, transition; + for (var j = 0, m = this.length; j < m; j++) { + subgroups.push(subgroup = []); + for (var group = this[j], i = 0, n = group.length; i < n; i++) { + if (node = group[i]) { + transition = node[ns][id0]; + d3_transitionNode(node, i, ns, id1, { + time: transition.time, + ease: transition.ease, + delay: transition.delay + transition.duration, + duration: transition.duration + }); + } + subgroup.push(node); + } + } + return d3_transition(subgroups, ns, id1); + }; + function d3_transitionNamespace(name) { + return name == null ? "__transition__" : "__transition_" + name + "__"; + } + function d3_transitionNode(node, i, ns, id, inherit) { + var lock = node[ns] || (node[ns] = { + active: 0, + count: 0 + }), transition = lock[id]; + if (!transition) { + var time = inherit.time; + transition = lock[id] = { + tween: new d3_Map(), + time: time, + delay: inherit.delay, + duration: inherit.duration, + ease: inherit.ease, + index: i + }; + inherit = null; + ++lock.count; + d3.timer(function(elapsed) { + var delay = transition.delay, duration, ease, timer = d3_timer_active, tweened = []; + timer.t = delay + time; + if (delay <= elapsed) return start(elapsed - delay); + timer.c = start; + function start(elapsed) { + if (lock.active > id) return stop(); + var active = lock[lock.active]; + if (active) { + --lock.count; + delete lock[lock.active]; + active.event && active.event.interrupt.call(node, node.__data__, active.index); + } + lock.active = id; + transition.event && transition.event.start.call(node, node.__data__, i); + transition.tween.forEach(function(key, value) { + if (value = value.call(node, node.__data__, i)) { + tweened.push(value); + } + }); + ease = transition.ease; + duration = transition.duration; + d3.timer(function() { + timer.c = tick(elapsed || 1) ? d3_true : tick; + return 1; + }, 0, time); + } + function tick(elapsed) { + if (lock.active !== id) return 1; + var t = elapsed / duration, e = ease(t), n = tweened.length; + while (n > 0) { + tweened[--n].call(node, e); + } + if (t >= 1) { + transition.event && transition.event.end.call(node, node.__data__, i); + return stop(); + } + } + function stop() { + if (--lock.count) delete lock[id]; else delete node[ns]; + return 1; + } + }, 0, time); + } + } + d3.svg.axis = function() { + var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_; + function axis(g) { + g.each(function() { + var g = d3.select(this); + var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = scale.copy(); + var ticks = tickValues == null ? scale1.ticks ? scale1.ticks.apply(scale1, tickArguments_) : scale1.domain() : tickValues, tickFormat = tickFormat_ == null ? scale1.tickFormat ? scale1.tickFormat.apply(scale1, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(".tick").data(ticks, scale1), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", ε), tickExit = d3.transition(tick.exit()).style("opacity", ε).remove(), tickUpdate = d3.transition(tick.order()).style("opacity", 1), tickSpacing = Math.max(innerTickSize, 0) + tickPadding, tickTransform; + var range = d3_scaleRange(scale1), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), + d3.transition(path)); + tickEnter.append("line"); + tickEnter.append("text"); + var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"), sign = orient === "top" || orient === "left" ? -1 : 1, x1, x2, y1, y2; + if (orient === "bottom" || orient === "top") { + tickTransform = d3_svg_axisX, x1 = "x", y1 = "y", x2 = "x2", y2 = "y2"; + text.attr("dy", sign < 0 ? "0em" : ".71em").style("text-anchor", "middle"); + pathUpdate.attr("d", "M" + range[0] + "," + sign * outerTickSize + "V0H" + range[1] + "V" + sign * outerTickSize); + } else { + tickTransform = d3_svg_axisY, x1 = "y", y1 = "x", x2 = "y2", y2 = "x2"; + text.attr("dy", ".32em").style("text-anchor", sign < 0 ? "end" : "start"); + pathUpdate.attr("d", "M" + sign * outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + sign * outerTickSize); + } + lineEnter.attr(y2, sign * innerTickSize); + textEnter.attr(y1, sign * tickSpacing); + lineUpdate.attr(x2, 0).attr(y2, sign * innerTickSize); + textUpdate.attr(x1, 0).attr(y1, sign * tickSpacing); + if (scale1.rangeBand) { + var x = scale1, dx = x.rangeBand() / 2; + scale0 = scale1 = function(d) { + return x(d) + dx; + }; + } else if (scale0.rangeBand) { + scale0 = scale1; + } else { + tickExit.call(tickTransform, scale1, scale0); + } + tickEnter.call(tickTransform, scale0, scale1); + tickUpdate.call(tickTransform, scale1, scale1); + }); + } + axis.scale = function(x) { + if (!arguments.length) return scale; + scale = x; + return axis; + }; + axis.orient = function(x) { + if (!arguments.length) return orient; + orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient; + return axis; + }; + axis.ticks = function() { + if (!arguments.length) return tickArguments_; + tickArguments_ = arguments; + return axis; + }; + axis.tickValues = function(x) { + if (!arguments.length) return tickValues; + tickValues = x; + return axis; + }; + axis.tickFormat = function(x) { + if (!arguments.length) return tickFormat_; + tickFormat_ = x; + return axis; + }; + axis.tickSize = function(x) { + var n = arguments.length; + if (!n) return innerTickSize; + innerTickSize = +x; + outerTickSize = +arguments[n - 1]; + return axis; + }; + axis.innerTickSize = function(x) { + if (!arguments.length) return innerTickSize; + innerTickSize = +x; + return axis; + }; + axis.outerTickSize = function(x) { + if (!arguments.length) return outerTickSize; + outerTickSize = +x; + return axis; + }; + axis.tickPadding = function(x) { + if (!arguments.length) return tickPadding; + tickPadding = +x; + return axis; + }; + axis.tickSubdivide = function() { + return arguments.length && axis; + }; + return axis; + }; + var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = { + top: 1, + right: 1, + bottom: 1, + left: 1 + }; + function d3_svg_axisX(selection, x0, x1) { + selection.attr("transform", function(d) { + var v0 = x0(d); + return "translate(" + (isFinite(v0) ? v0 : x1(d)) + ",0)"; + }); + } + function d3_svg_axisY(selection, y0, y1) { + selection.attr("transform", function(d) { + var v0 = y0(d); + return "translate(0," + (isFinite(v0) ? v0 : y1(d)) + ")"; + }); + } + d3.svg.brush = function() { + var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0]; + function brush(g) { + g.each(function() { + var g = d3.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart); + var background = g.selectAll(".background").data([ 0 ]); + background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"); + g.selectAll(".extent").data([ 0 ]).enter().append("rect").attr("class", "extent").style("cursor", "move"); + var resize = g.selectAll(".resize").data(resizes, d3_identity); + resize.exit().remove(); + resize.enter().append("g").attr("class", function(d) { + return "resize " + d; + }).style("cursor", function(d) { + return d3_svg_brushCursor[d]; + }).append("rect").attr("x", function(d) { + return /[ew]$/.test(d) ? -3 : null; + }).attr("y", function(d) { + return /^[ns]/.test(d) ? -3 : null; + }).attr("width", 6).attr("height", 6).style("visibility", "hidden"); + resize.style("display", brush.empty() ? "none" : null); + var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range; + if (x) { + range = d3_scaleRange(x); + backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]); + redrawX(gUpdate); + } + if (y) { + range = d3_scaleRange(y); + backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]); + redrawY(gUpdate); + } + redraw(gUpdate); + }); + } + brush.event = function(g) { + g.each(function() { + var event_ = event.of(this, arguments), extent1 = { + x: xExtent, + y: yExtent, + i: xExtentDomain, + j: yExtentDomain + }, extent0 = this.__chart__ || extent1; + this.__chart__ = extent1; + if (d3_transitionInheritId) { + d3.select(this).transition().each("start.brush", function() { + xExtentDomain = extent0.i; + yExtentDomain = extent0.j; + xExtent = extent0.x; + yExtent = extent0.y; + event_({ + type: "brushstart" + }); + }).tween("brush:brush", function() { + var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y); + xExtentDomain = yExtentDomain = null; + return function(t) { + xExtent = extent1.x = xi(t); + yExtent = extent1.y = yi(t); + event_({ + type: "brush", + mode: "resize" + }); + }; + }).each("end.brush", function() { + xExtentDomain = extent1.i; + yExtentDomain = extent1.j; + event_({ + type: "brush", + mode: "resize" + }); + event_({ + type: "brushend" + }); + }); + } else { + event_({ + type: "brushstart" + }); + event_({ + type: "brush", + mode: "resize" + }); + event_({ + type: "brushend" + }); + } + }); + }; + function redraw(g) { + g.selectAll(".resize").attr("transform", function(d) { + return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")"; + }); + } + function redrawX(g) { + g.select(".extent").attr("x", xExtent[0]); + g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]); + } + function redrawY(g) { + g.select(".extent").attr("y", yExtent[0]); + g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]); + } + function brushstart() { + var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(target), center, origin = d3.mouse(target), offset; + var w = d3.select(d3_window(target)).on("keydown.brush", keydown).on("keyup.brush", keyup); + if (d3.event.changedTouches) { + w.on("touchmove.brush", brushmove).on("touchend.brush", brushend); + } else { + w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend); + } + g.interrupt().selectAll("*").interrupt(); + if (dragging) { + origin[0] = xExtent[0] - origin[0]; + origin[1] = yExtent[0] - origin[1]; + } else if (resizing) { + var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing); + offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ]; + origin[0] = xExtent[ex]; + origin[1] = yExtent[ey]; + } else if (d3.event.altKey) center = origin.slice(); + g.style("pointer-events", "none").selectAll(".resize").style("display", null); + d3.select("body").style("cursor", eventTarget.style("cursor")); + event_({ + type: "brushstart" + }); + brushmove(); + function keydown() { + if (d3.event.keyCode == 32) { + if (!dragging) { + center = null; + origin[0] -= xExtent[1]; + origin[1] -= yExtent[1]; + dragging = 2; + } + d3_eventPreventDefault(); + } + } + function keyup() { + if (d3.event.keyCode == 32 && dragging == 2) { + origin[0] += xExtent[1]; + origin[1] += yExtent[1]; + dragging = 0; + d3_eventPreventDefault(); + } + } + function brushmove() { + var point = d3.mouse(target), moved = false; + if (offset) { + point[0] += offset[0]; + point[1] += offset[1]; + } + if (!dragging) { + if (d3.event.altKey) { + if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ]; + origin[0] = xExtent[+(point[0] < center[0])]; + origin[1] = yExtent[+(point[1] < center[1])]; + } else center = null; + } + if (resizingX && move1(point, x, 0)) { + redrawX(g); + moved = true; + } + if (resizingY && move1(point, y, 1)) { + redrawY(g); + moved = true; + } + if (moved) { + redraw(g); + event_({ + type: "brush", + mode: dragging ? "move" : "resize" + }); + } + } + function move1(point, scale, i) { + var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max; + if (dragging) { + r0 -= position; + r1 -= size + position; + } + min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i]; + if (dragging) { + max = (min += position) + size; + } else { + if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); + if (position < min) { + max = min; + min = position; + } else { + max = position; + } + } + if (extent[0] != min || extent[1] != max) { + if (i) yExtentDomain = null; else xExtentDomain = null; + extent[0] = min; + extent[1] = max; + return true; + } + } + function brushend() { + brushmove(); + g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); + d3.select("body").style("cursor", null); + w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null); + dragRestore(); + event_({ + type: "brushend" + }); + } + } + brush.x = function(z) { + if (!arguments.length) return x; + x = z; + resizes = d3_svg_brushResizes[!x << 1 | !y]; + return brush; + }; + brush.y = function(z) { + if (!arguments.length) return y; + y = z; + resizes = d3_svg_brushResizes[!x << 1 | !y]; + return brush; + }; + brush.clamp = function(z) { + if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null; + if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z; + return brush; + }; + brush.extent = function(z) { + var x0, x1, y0, y1, t; + if (!arguments.length) { + if (x) { + if (xExtentDomain) { + x0 = xExtentDomain[0], x1 = xExtentDomain[1]; + } else { + x0 = xExtent[0], x1 = xExtent[1]; + if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); + if (x1 < x0) t = x0, x0 = x1, x1 = t; + } + } + if (y) { + if (yExtentDomain) { + y0 = yExtentDomain[0], y1 = yExtentDomain[1]; + } else { + y0 = yExtent[0], y1 = yExtent[1]; + if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); + if (y1 < y0) t = y0, y0 = y1, y1 = t; + } + } + return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ]; + } + if (x) { + x0 = z[0], x1 = z[1]; + if (y) x0 = x0[0], x1 = x1[0]; + xExtentDomain = [ x0, x1 ]; + if (x.invert) x0 = x(x0), x1 = x(x1); + if (x1 < x0) t = x0, x0 = x1, x1 = t; + if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ]; + } + if (y) { + y0 = z[0], y1 = z[1]; + if (x) y0 = y0[1], y1 = y1[1]; + yExtentDomain = [ y0, y1 ]; + if (y.invert) y0 = y(y0), y1 = y(y1); + if (y1 < y0) t = y0, y0 = y1, y1 = t; + if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ]; + } + return brush; + }; + brush.clear = function() { + if (!brush.empty()) { + xExtent = [ 0, 0 ], yExtent = [ 0, 0 ]; + xExtentDomain = yExtentDomain = null; + } + return brush; + }; + brush.empty = function() { + return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1]; + }; + return d3.rebind(brush, event, "on"); + }; + var d3_svg_brushCursor = { + n: "ns-resize", + e: "ew-resize", + s: "ns-resize", + w: "ew-resize", + nw: "nwse-resize", + ne: "nesw-resize", + se: "nwse-resize", + sw: "nesw-resize" + }; + var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ]; + var d3_time_format = d3_time.format = d3_locale_enUS.timeFormat; + var d3_time_formatUtc = d3_time_format.utc; + var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ"); + d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso; + function d3_time_formatIsoNative(date) { + return date.toISOString(); + } + d3_time_formatIsoNative.parse = function(string) { + var date = new Date(string); + return isNaN(date) ? null : date; + }; + d3_time_formatIsoNative.toString = d3_time_formatIso.toString; + d3_time.second = d3_time_interval(function(date) { + return new d3_date(Math.floor(date / 1e3) * 1e3); + }, function(date, offset) { + date.setTime(date.getTime() + Math.floor(offset) * 1e3); + }, function(date) { + return date.getSeconds(); + }); + d3_time.seconds = d3_time.second.range; + d3_time.seconds.utc = d3_time.second.utc.range; + d3_time.minute = d3_time_interval(function(date) { + return new d3_date(Math.floor(date / 6e4) * 6e4); + }, function(date, offset) { + date.setTime(date.getTime() + Math.floor(offset) * 6e4); + }, function(date) { + return date.getMinutes(); + }); + d3_time.minutes = d3_time.minute.range; + d3_time.minutes.utc = d3_time.minute.utc.range; + d3_time.hour = d3_time_interval(function(date) { + var timezone = date.getTimezoneOffset() / 60; + return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); + }, function(date, offset) { + date.setTime(date.getTime() + Math.floor(offset) * 36e5); + }, function(date) { + return date.getHours(); + }); + d3_time.hours = d3_time.hour.range; + d3_time.hours.utc = d3_time.hour.utc.range; + d3_time.month = d3_time_interval(function(date) { + date = d3_time.day(date); + date.setDate(1); + return date; + }, function(date, offset) { + date.setMonth(date.getMonth() + offset); + }, function(date) { + return date.getMonth(); + }); + d3_time.months = d3_time.month.range; + d3_time.months.utc = d3_time.month.utc.range; + function d3_time_scale(linear, methods, format) { + function scale(x) { + return linear(x); + } + scale.invert = function(x) { + return d3_time_scaleDate(linear.invert(x)); + }; + scale.domain = function(x) { + if (!arguments.length) return linear.domain().map(d3_time_scaleDate); + linear.domain(x); + return scale; + }; + function tickMethod(extent, count) { + var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target); + return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) { + return d / 31536e6; + }), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i]; + } + scale.nice = function(interval, skip) { + var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" && tickMethod(extent, interval); + if (method) interval = method[0], skip = method[1]; + function skipped(date) { + return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length; + } + return scale.domain(d3_scale_nice(domain, skip > 1 ? { + floor: function(date) { + while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1); + return date; + }, + ceil: function(date) { + while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1); + return date; + } + } : interval)); + }; + scale.ticks = function(interval, skip) { + var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" ? tickMethod(extent, interval) : !interval.range && [ { + range: interval + }, skip ]; + if (method) interval = method[0], skip = method[1]; + return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip); + }; + scale.tickFormat = function() { + return format; + }; + scale.copy = function() { + return d3_time_scale(linear.copy(), methods, format); + }; + return d3_scale_linearRebind(scale, linear); + } + function d3_time_scaleDate(t) { + return new Date(t); + } + var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ]; + var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ]; + var d3_time_scaleLocalFormat = d3_time_format.multi([ [ ".%L", function(d) { + return d.getMilliseconds(); + } ], [ ":%S", function(d) { + return d.getSeconds(); + } ], [ "%I:%M", function(d) { + return d.getMinutes(); + } ], [ "%I %p", function(d) { + return d.getHours(); + } ], [ "%a %d", function(d) { + return d.getDay() && d.getDate() != 1; + } ], [ "%b %d", function(d) { + return d.getDate() != 1; + } ], [ "%B", function(d) { + return d.getMonth(); + } ], [ "%Y", d3_true ] ]); + var d3_time_scaleMilliseconds = { + range: function(start, stop, step) { + return d3.range(Math.ceil(start / step) * step, +stop, step).map(d3_time_scaleDate); + }, + floor: d3_identity, + ceil: d3_identity + }; + d3_time_scaleLocalMethods.year = d3_time.year; + d3_time.scale = function() { + return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); + }; + var d3_time_scaleUtcMethods = d3_time_scaleLocalMethods.map(function(m) { + return [ m[0].utc, m[1] ]; + }); + var d3_time_scaleUtcFormat = d3_time_formatUtc.multi([ [ ".%L", function(d) { + return d.getUTCMilliseconds(); + } ], [ ":%S", function(d) { + return d.getUTCSeconds(); + } ], [ "%I:%M", function(d) { + return d.getUTCMinutes(); + } ], [ "%I %p", function(d) { + return d.getUTCHours(); + } ], [ "%a %d", function(d) { + return d.getUTCDay() && d.getUTCDate() != 1; + } ], [ "%b %d", function(d) { + return d.getUTCDate() != 1; + } ], [ "%B", function(d) { + return d.getUTCMonth(); + } ], [ "%Y", d3_true ] ]); + d3_time_scaleUtcMethods.year = d3_time.year.utc; + d3_time.scale.utc = function() { + return d3_time_scale(d3.scale.linear(), d3_time_scaleUtcMethods, d3_time_scaleUtcFormat); + }; + d3.text = d3_xhrType(function(request) { + return request.responseText; + }); + d3.json = function(url, callback) { + return d3_xhr(url, "application/json", d3_json, callback); + }; + function d3_json(request) { + return JSON.parse(request.responseText); + } + d3.html = function(url, callback) { + return d3_xhr(url, "text/html", d3_html, callback); + }; + function d3_html(request) { + var range = d3_document.createRange(); + range.selectNode(d3_document.body); + return range.createContextualFragment(request.responseText); + } + d3.xml = d3_xhrType(function(request) { + return request.responseXML; + }); + if (typeof define === "function" && define.amd) define(d3); else if (typeof module === "object" && module.exports) module.exports = d3; + this.d3 = d3; +}(); \ No newline at end of file diff --git a/docs/site_libs/d3-3.5.3/d3.min.js b/docs/site_libs/d3-3.5.3/d3.min.js new file mode 100644 index 0000000..1984d17 --- /dev/null +++ b/docs/site_libs/d3-3.5.3/d3.min.js @@ -0,0 +1,5 @@ +!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function r(n){return null===n?0/0:+n}function u(n){return!isNaN(n)}function i(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function c(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function l(){this._=Object.create(null)}function s(n){return(n+="")===pa||n[0]===va?va+n:n}function f(n){return(n+="")[0]===va?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=da.length;r>e;++e){var u=da[e]+t;if(u in n)return u}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,u=-1,i=r.length;++ue;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function Z(n){return ya(n,Sa),n}function V(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var l=ka.get(n);return l&&(n=l,c=B),a?t?u:r:t?b:i}function $(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Aa,u="click"+r,i=ta.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ea&&(Ea="onselectstart"in e?!1:x(e.style,"userSelect")),Ea){var o=n(e).style,a=o[Ea];o[Ea]="none"}return function(n){if(i.on(r,null),Ea&&(o[Ea]=a),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Na){var i=t(n);if(i.scrollX||i.scrollY){r=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Na=!(o.f||o.e),r.remove()}}return Na?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ta.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nt(n){return n>1?0:-1>n?qa:Math.acos(n)}function tt(n){return n>1?Ra:-1>n?-Ra:Math.asin(n)}function et(n){return((n=Math.exp(n))-1/n)/2}function rt(n){return((n=Math.exp(n))+1/n)/2}function ut(n){return((n=Math.exp(2*n))-1)/(n+1)}function it(n){return(n=Math.sin(n/2))*n}function ot(){}function at(n,t,e){return this instanceof at?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof at?new at(n.h,n.s,n.l):bt(""+n,_t,at):new at(n,t,e)}function ct(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new mt(u(n+120),u(n),u(n-120))}function lt(n,t,e){return this instanceof lt?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof lt?new lt(n.h,n.c,n.l):n instanceof ft?gt(n.l,n.a,n.b):gt((n=wt((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new lt(n,t,e)}function st(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new ft(e,Math.cos(n*=Da)*t,Math.sin(n)*t)}function ft(n,t,e){return this instanceof ft?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof ft?new ft(n.l,n.a,n.b):n instanceof lt?st(n.h,n.c,n.l):wt((n=mt(n)).r,n.g,n.b):new ft(n,t,e)}function ht(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=pt(u)*Xa,r=pt(r)*$a,i=pt(i)*Ba,new mt(dt(3.2404542*u-1.5371385*r-.4985314*i),dt(-.969266*u+1.8760108*r+.041556*i),dt(.0556434*u-.2040259*r+1.0572252*i))}function gt(n,t,e){return n>0?new lt(Math.atan2(e,t)*Pa,Math.sqrt(t*t+e*e),n):new lt(0/0,0/0,n)}function pt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function vt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function dt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mt(n,t,e){return this instanceof mt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mt?new mt(n.r,n.g,n.b):bt(""+n,mt,ct):new mt(n,t,e)}function yt(n){return new mt(n>>16,n>>8&255,255&n)}function Mt(n){return yt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function bt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(kt(u[0]),kt(u[1]),kt(u[2]))}return(i=Ga.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new at(r,u,c)}function wt(n,t,e){n=St(n),t=St(t),e=St(e);var r=vt((.4124564*n+.3575761*t+.1804375*e)/Xa),u=vt((.2126729*n+.7151522*t+.072175*e)/$a),i=vt((.0193339*n+.119192*t+.9503041*e)/Ba);return ft(116*u-16,500*(r-u),200*(u-i))}function St(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function kt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function Et(n){return"function"==typeof n?n:function(){return n}}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return void o.error.call(i,r)}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!this.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(tc),tc=setTimeout(qt,t)),nc=0):(nc=1,rc(qt))}function Lt(){var n=Date.now();for(ec=Ka;ec;)n>=ec.t&&(ec.f=ec.c(n-ec.t)),ec=ec.n;return n}function Tt(){for(var n,t=Ka,e=1/0;t;)t.f?t=n?n.n=t.n:Ka=t.n:(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:y;return function(n){var e=ic.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=oc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new cc(e-1)),1),e}function i(n,e){return t(n=new cc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{cc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{cc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{cc=jt;var r=new jt;return r._=t,n(r,e)._}finally{cc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++aa;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in sc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{cc=jt;var t=new cc;return t._=n,r(t)}finally{cc=Date}}var r=t(n);return e.parse=function(n){try{cc=jt;var t=r.parse(n);return t&&t._}finally{cc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=Yt(v),b=Zt(v),_=Yt(d),w=Zt(d),S=Yt(m),k=Zt(m),E=Yt(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return It(n.getDate(),t,2)},e:function(n,t){return It(n.getDate(),t,2)},H:function(n,t){return It(n.getHours(),t,2)},I:function(n,t){return It(n.getHours()%12||12,t,2)},j:function(n,t){return It(1+ac.dayOfYear(n),t,3)},L:function(n,t){return It(n.getMilliseconds(),t,3)},m:function(n,t){return It(n.getMonth()+1,t,2)},M:function(n,t){return It(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return It(n.getSeconds(),t,2)},U:function(n,t){return It(ac.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return It(ac.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return It(n.getFullYear()%100,t,2)},Y:function(n,t){return It(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function It(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Yt(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new l,e=-1,r=n.length;++e68?1900:2e3)}function Kt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=ga(t)/60|0,u=ga(t)%60;return e+It(r,"0",2)+It(u,"0",2)}function oe(n,t,e){hc.lastIndex=0;var r=hc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);yc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;Mc.point=function(o,a){Mc.point=n,r=(t=o)*Da,u=Math.cos(a=(e=a)*Da/2+qa/4),i=Math.sin(a)},Mc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),tt(n[2])]}function be(n,t){return ga(n[0]-t[0])a;++a)u.point((e=n[a])[0],e[1]);return void u.lineEnd()}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-Ra-Ca:Ra-n[1])-((t=t.x)[0]<0?t[1]-Ra-Ca:Ra-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?qa:-qa,c=ga(i-e);ga(c-qa)0?Ra:-Ra),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=qa&&(ga(e-u)Ca?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*Ra,r.point(-qa,u),r.point(0,u),r.point(qa,u),r.point(qa,0),r.point(qa,-u),r.point(0,-u),r.point(-qa,-u),r.point(-qa,0),r.point(-qa,u);else if(ga(n[0]-t[0])>Ca){var i=n[0]a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+qa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+qa/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>qa,k=p*M;if(yc.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*La:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*tt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ca>i||Ca>i&&0>yc)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?qa:-qa),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ca,p[1]+=Ca,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=ga(A-qa)A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(ga(b[0]-w)qa^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:qa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ga(i)>Ca,c=gr(n,6*Da);return Le(t,e,c,o?[0,-n]:[-qa,n-qa])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ie(n,t,e,r){function u(r,u){return ga(r[0]-n)0?0:3:ga(r[0]-e)0?2:1:ga(r[1]-t)0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&Q(l,i,n)>0&&++t:i[1]<=r&&Q(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Tc,Math.min(Tc,n)),t=Math.max(-Tc,Math.min(Tc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ye(n){var t=0,e=qa/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*qa/180,e=n[1]*qa/180):[t/qa*180,e/qa*180]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,tt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Dc+=u*n-r*t,r=n,u=t}var t,e,r,u;Hc.point=function(i,o){Hc.point=n,t=r=i,e=u=o},Hc.lineEnd=function(){n(t,e)}}function Xe(n,t){Pc>n&&(Pc=n),n>jc&&(jc=n),Uc>t&&(Uc=t),t>Fc&&(Fc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){_c+=n,wc+=t,++Sc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);kc+=o*(t+n)/2,Ec+=o*(e+r)/2,Ac+=o,We(t=n,e=r)}var t,e;Ic.point=function(r,u){Ic.point=n,We(t=r,e=u)}}function Ge(){Ic.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);kc+=o*(r+n)/2,Ec+=o*(u+t)/2,Ac+=o,o=u*n-r*t,Nc+=o*(r+n),Cc+=o*(u+t),zc+=3*o,We(r=n,u=t)}var t,e,r,u;Ic.point=function(i,o){Ic.point=n,We(t=r=i,e=u=o)},Ic.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,La)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c +},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=ga(ga(w)-1)i||ga((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Da),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Pa,e*Pa])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Da,n[1]*Da),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Pa,n[1]*Pa]}function r(){a=Ae(o=lr(m,M,x),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,M=0,x=0,b=Lc,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(b(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Lc):He((w=+n)*Da),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Ie(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Da,d=n[1]%360*Da,r()):[v*Pa,d*Pa]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Da,M=n[1]%360*Da,x=n.length>2?n[2]%360*Da:0,r()):[m*Pa,M*Pa,x*Pa]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Da,e*Da)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>qa?n-La:-qa>n?n+La:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>qa?t-La:-qa>t?t+La:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),tt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),tt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*La)):(u=n+o*La,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=nt(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ca)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(it(r-t)+u*o*it(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Pa,Math.atan2(o,Math.sqrt(r*r+u*u))*Pa]}:function(){return[n*Pa,t*Pa]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Da),o=Math.cos(u),a=ga((n*=Da)-t),c=Math.cos(a);Yc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Zc.point=function(u,i){t=u*Da,e=Math.sin(i*=Da),r=Math.cos(i),Zc.point=n},Zc.lineEnd=function(){Zc.point=Zc.lineEnd=b}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-Ra+Ca>t&&(t=-Ra+Ca):t>Ra-Ca&&(t=Ra-Ca);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(qa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ra]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ga(u)u;u++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=el.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Qc.remove(n),el.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&ga(e-c.circle.x)s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Qc._;a;)if(r=Fr(a,o)-i,r>Ca)a=a.L;else{if(u=i-Hr(a,o),!(u>Ca)){r>-Ca?(t=a.P,e=a):u>-Ca?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Qc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Qc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),void Vr(e);if(!e)return void(c.edge=Jr(t.site,c.site));Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Ir(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Kc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(ga(r-t)>Ca||ga(u-e)>Ca)&&(a.splice(o,0,new Qr(Gr(i.site,s,ga(r-f)Ca?{x:f,y:ga(t-f)Ca?{x:ga(e-p)Ca?{x:h,y:ga(t-h)Ca?{x:ga(e-g)=-za)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=rl.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=tl._;M;)if(m.yd||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.yr||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.yg){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.xi||f>o||r>h||u>g)){if(p=n.point){var p,v=t-n.x,d=e-n.y,m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+xt(Math.round(e+i*n))+xt(Math.round(r+o*n))+xt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=il.lastIndex=ol.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=il.exec(n))&&(r=ol.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=ol.lastIndex;return ir;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*Ra)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/La*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*La/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return st(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ht(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++oe;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.ro;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ml}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Oi:ji,c=r?Iu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Ii(n,t,e,r)},u()}function Yi(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=ic.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(ga(r[0]),ga(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in yl?Math.abs(e-Bi(Math.max(ga(t[0]),ga(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:xl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++0;h--)o.push(i(l)*h);for(l=0;o[l]c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return Ml;arguments.length<2?t=Ml:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Yi(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Yi(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new l;for(var i,o=-1,a=r.length;++oe?[0/0,0/0]:[e>0?a[e-1]:n[0],et?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=Et(e),p=Et(r);++f1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++ur)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,a)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=ec,v=[];return p.t=g+a,u>=g?c(u-g):void(p.c=c)},0,a)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Vl,u);return i==Vl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Vl[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Yi(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.6"},ea=[].slice,ra=function(n){return ea.call(n)},ua=this.document;if(ua)try{ra(ua.documentElement.childNodes)[0].nodeType}catch(ia){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),ua)try{ua.createElement("DIV").style.setProperty("opacity",0,"")}catch(oa){var aa=this.Element.prototype,ca=aa.setAttribute,la=aa.setAttributeNS,sa=this.CSSStyleDeclaration.prototype,fa=sa.setProperty;aa.setAttribute=function(n,t){ca.call(this,n,t+"")},aa.setAttributeNS=function(n,t,e){la.call(this,n,t,e+"")},sa.setProperty=function(n,t,e){fa.call(this,n,t+"",e)}}ta.ascending=e,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ur&&(e=r)}else{for(;++u=r){e=r;break}for(;++ur&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ue&&(e=r)}else{for(;++u=r){e=r;break}for(;++ue&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var e,r=0,i=n.length,o=-1;if(1===arguments.length)for(;++o1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var ha=i(e);ta.bisectLeft=ha.left,ta.bisect=ta.bisectRight=ha.right,ta.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=Math.random()*i--|0,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,o),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ga=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=a(ga(e)),o=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++o)>t;)u.push(r/i);else for(;(r=n+e*++o)=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var c,s,f,h,g=-1,p=o.length,v=i[a++],d=new l;++g=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},c(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(ma,"\\$&")};var ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ya={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ma=function(n,t){return t.querySelector(n)},xa=function(n,t){return t.querySelectorAll(n)},ba=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(ba=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(Ma=function(n,t){return Sizzle(n,t)[0]||null},xa=Sizzle,ba=Sizzle.matchesSelector),ta.selection=function(){return ta.select(ua.documentElement)};var _a=ta.selection.prototype=[];_a.select=function(n){var t,e,r,u,i=[];n=N(n);for(var o=-1,a=this.length;++o=0&&(e=n.slice(0,t),n=n.slice(t+1)),wa.hasOwnProperty(e)?{space:wa[e],local:n}:n}},_a.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},_a.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++uu){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},_a.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},_a.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},_a.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},_a.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},_a.insert=function(n,t){return n=j(n),t=N(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},_a.remove=function(){return this.each(F)},_a.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new l,y=new Array(o);for(r=-1;++rr;++r)p[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,a.push(p),c.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++ii;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return A(u)},_a.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},_a.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},_a.size=function(){var n=0;return Y(this,function(){++n}),n};var Sa=[];ta.selection.enter=Z,ta.selection.enter.prototype=Sa,Sa.append=_a.append,Sa.empty=_a.empty,Sa.node=_a.node,Sa.call=_a.call,Sa.size=_a.size,Sa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var ka=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});ua&&ka.forEach(function(n){"on"+n in ua&&ka.remove(n)});var Ea,Aa=0;ta.mouse=function(n){return J(n,k())};var Na=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",o)}function e(n,t,e,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(e(f)).on(i+d,a).on(o+d,c),y=W(f),M=t(h,v);u?(l=u.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var r=E(n,"drag","dragstart","dragend"),u=null,i=e(b,ta.mouse,t,"mousemove","mouseup"),o=e(G,ta.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},ta.rebind(n,r,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ra(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Ca=1e-6,za=Ca*Ca,qa=Math.PI,La=2*qa,Ta=La-Ca,Ra=qa/2,Da=qa/180,Pa=180/qa,Ua=Math.SQRT2,ja=2,Fa=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=rt(v),o=i/(ja*h)*(e*ut(Ua*t+v)-et(v));return[r+o*l,u+o*s,i*e/rt(Ua*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Ua*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Fa*f)/(2*i*ja*h),p=(c*c-i*i-Fa*f)/(2*c*ja*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ua;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(q,f).on(Oa+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(N[0],Math.min(N[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,o)),i(d=e,r),t=ta.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function c(n){z++||n({type:"zoomstart"})}function l(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||(n({type:"zoomend"}),d=null)}function f(){function n(){f=1,i(ta.mouse(u),g),l(a)}function r(){h.on(L,null).on(T,null),p(f&&ta.event.target===o),s(a)}var u=this,o=ta.event.target,a=D.of(u,arguments),f=0,h=ta.select(t(u)).on(L,n).on(T,r),g=e(ta.mouse(u)),p=W(u);Dl.call(u),c(a)}function h(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ta.event.target;ta.select(t).on(x,r).on(b,a),_.push(t);for(var e=ta.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var c=n(),l=Date.now();if(1===c.length){if(500>l-M){var s=c[0];o(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=l}else if(c.length>1){var s=c[0],f=c[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,o=ta.touches(p);Dl.call(p);for(var a=0,c=o.length;c>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),l(v)}function a(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(_).on(y,null),w.on(q,f).on(R,h),E(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=ta.select(p),E=W(p);t(),c(v),w.on(q,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(Dl.call(this),v=e(d=m||ta.mouse(this)),c(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Ha())*k.k),i(d,v),l(n)}function p(){var n=ta.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ta.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},A=[960,500],N=Ia,C=250,z=0,q="mousedown.zoom",L="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=E(n,"zoomstart","zoom","zoomend");return Oa||(Oa="onwheel"in ua?(Ha=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Ha=function(){return ta.event.wheelDelta},"mousewheel"):(Ha=function(){return-ta.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Tl?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},c(n)}).tween("zoom:zoom",function(){var e=A[0],r=A[1],u=d?d[0]:e/2,i=d?d[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},l(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,c(n),l(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(N=null==t?Ia:[+t[0],+t[1]],n):N},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(A=t&&[+t[0],+t[1]],n):A},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ta.rebind(n,D,"on")};var Ha,Oa,Ia=[0,1/0];ta.color=ot,ot.prototype.toString=function(){return this.rgb()+""},ta.hsl=at;var Ya=at.prototype=new ot;Ya.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,this.l/n)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,n*this.l)},Ya.rgb=function(){return ct(this.h,this.s,this.l)},ta.hcl=lt;var Za=lt.prototype=new ot;Za.brighter=function(n){return new lt(this.h,this.c,Math.min(100,this.l+Va*(arguments.length?n:1)))},Za.darker=function(n){return new lt(this.h,this.c,Math.max(0,this.l-Va*(arguments.length?n:1)))},Za.rgb=function(){return st(this.h,this.c,this.l).rgb()},ta.lab=ft;var Va=18,Xa=.95047,$a=1,Ba=1.08883,Wa=ft.prototype=new ot;Wa.brighter=function(n){return new ft(Math.min(100,this.l+Va*(arguments.length?n:1)),this.a,this.b)},Wa.darker=function(n){return new ft(Math.max(0,this.l-Va*(arguments.length?n:1)),this.a,this.b)},Wa.rgb=function(){return ht(this.l,this.a,this.b)},ta.rgb=mt;var Ja=mt.prototype=new ot;Ja.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new mt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mt(u,u,u)},Ja.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mt(n*this.r,n*this.g,n*this.b)},Ja.hsl=function(){return _t(this.r,this.g,this.b)},Ja.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var Ga=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ga.forEach(function(n,t){Ga.set(n,yt(t))}),ta.functor=Et,ta.xhr=At(y),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new m,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var Ka,Qa,nc,tc,ec,rc=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Qa?Qa.n=i:Ka=i,Qa=i,nc||(tc=clearTimeout(tc),nc=1,rc(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var uc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),uc[8+e/3]};var ic=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),ac=ta.time={},cc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){lc.setUTCDate.apply(this._,arguments)},setDay:function(){lc.setUTCDay.apply(this._,arguments)},setFullYear:function(){lc.setUTCFullYear.apply(this._,arguments)},setHours:function(){lc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){lc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){lc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){lc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){lc.setUTCSeconds.apply(this._,arguments)},setTime:function(){lc.setTime.apply(this._,arguments)}};var lc=Date.prototype;ac.year=Ft(function(n){return n=ac.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ac.years=ac.year.range,ac.years.utc=ac.year.utc.range,ac.day=Ft(function(n){var t=new cc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ac.days=ac.day.range,ac.days.utc=ac.day.utc.range,ac.dayOfYear=function(n){var t=ac.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ac[n]=Ft(function(n){return(n=ac.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ac[n+"s"]=e.range,ac[n+"s"].utc=e.utc.range,ac[n+"OfYear"]=function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)}}),ac.week=ac.sunday,ac.weeks=ac.sunday.range,ac.weeks.utc=ac.sunday.utc.range,ac.weekOfYear=ac.sundayOfYear;var sc={"-":"",_:" ",0:"0"},fc=/^\s*\d+/,hc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var gc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=gc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,pc),le(pc.s,this.s,this),this.s?this.t+=pc.t:this.s=pc.t +},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var pc=new ce;ta.geo.stream=function(n,t){n&&vc.hasOwnProperty(n.type)?vc[n.type](n,t):se(n,t)};var vc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*qa+n:n,Mc.lineStart=Mc.lineEnd=Mc.point=b}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Da,e*Da]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Pa*l,d=ga(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Pa;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Pa;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ga(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Mc.point(n,e),t(n,e)}function i(){Mc.lineStart()}function o(){u(v,d),Mc.lineEnd(),ga(y)>Ca&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nyc?(s=-(h=180),f=-(g=90)):y>Ca?g=90:-Ca>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){xc=bc=_c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,qc);var t=Nc,e=Cc,r=zc,u=t*t+e*e+r*r;return za>u&&(t=kc,e=Ec,r=Ac,Ca>bc&&(t=_c,e=wc,r=Sc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Pa,tt(r/Math.sqrt(u))*Pa]};var xc,bc,_c,wc,Sc,kc,Ec,Ac,Nc,Cc,zc,qc={sphere:b,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){qc.lineStart=Ee},polygonEnd:function(){qc.lineStart=Se}},Lc=Le(Ne,Pe,je,[-qa,-qa/2]),Tc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ie(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ye(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ca,f+.12*l+Ca],[s-.214*l-Ca,f+.234*l-Ca]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ca,f+.166*l+Ca],[s-.115*l-Ca,f+.234*l-Ca]]).stream(c).point,n},n.scale(1070)};var Rc,Dc,Pc,Uc,jc,Fc,Hc={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Dc=0,Hc.lineStart=Ve},polygonEnd:function(){Hc.lineStart=Hc.lineEnd=Hc.point=b,Rc+=ga(Dc/2)}},Oc={point:Xe,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Ic={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Ic.lineStart=Ke},polygonEnd:function(){Ic.point=We,Ic.lineStart=Je,Ic.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Rc=0,ta.geo.stream(n,u(Hc)),Rc},n.centroid=function(n){return _c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,u(Ic)),zc?[Nc/zc,Cc/zc]:Ac?[kc/Ac,Ec/Ac]:Sc?[_c/Sc,wc/Sc]:[0/0,0/0]},n.bounds=function(n){return jc=Fc=-(Pc=Uc=1/0),ta.geo.stream(n,u(Oc)),[[Pc,Uc],[jc,Fc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):y,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t}return n=lr(n[0]%360*Da,n[1]*Da,n.length>2?n[2]*Da:0),t.invert=function(t){return t=n.invert(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Da,-n[1]*Da,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Pa,n[1]*=Pa}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Da,u*Da),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Da,(u=+r)*Da),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Da,u=n[1]*Da,i=t[1]*Da,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ga(n%d)>Ca}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ga(n%m)>Ca}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ca],[180,90-Ca]]).minorExtent([[-180,-80-Ca],[180,80+Ca]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Da,n[1]*Da,t[0]*Da,t[1]*Da)},ta.geo.length=function(n){return Yc=0,ta.geo.stream(n,Zc),Yc};var Yc,Zc={sphere:b,point:b,lineStart:xr,lineEnd:b,polygonStart:b,polygonEnd:b},Vc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Vc)}).raw=Vc;var Xc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(ta.geo.azimuthalEquidistant=function(){return ur(Xc)}).raw=Xc,(ta.geo.conicConformal=function(){return Ye(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ye(wr)}).raw=wr;var $c=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur($c)}).raw=$c,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ra]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Bc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Bc)}).raw=Bc;var Wc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Wc)}).raw=Wc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ra]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=Et(e),i=Et(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ca)*Ca,y:Math.round(o(n,t)/Ca)*Ca,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=ul;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Yr),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=Et(a),x=Et(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.xm&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=cl.get(e)||al,r=ll.get(r)||y,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:sl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var sl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=fl,h=hl,g=-30,p=gl,v=.1,d=.64,m=[],M=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,y,x,b=m.length,_=M.length;for(e=0;_>e;++e)a=M[e],f=a.source,h=a.target,y=h.x-f.x,x=h.y-f.y,(p=y*y+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,y*=p,x*=p,h.x-=y*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=y*(d=1-d),f.y+=x*d);if((d=r*v)&&(y=l[0]/2,x=l[1]/2,e=-1,d))for(;++e0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=M[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++at;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=M[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,M[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,M[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(y).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?void this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e):e},ta.rebind(a,c,"on")};var fl=20,hl=1,gl=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++lf?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===pl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=pl,r=0,u=La,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var pl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=y,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:vl.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:dl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var vl=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),dl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:Et(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.xp.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++oe&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++ie.dx)&&(s=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var ml={floor:y,ceil:y};ta.scale.linear=function(){return Ii([0,1],[0,1],mu,!1)};var yl={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var Ml=ta.format(".0e"),xl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(bl)},ta.scale.category20=function(){return ta.scale.ordinal().range(_l)},ta.scale.category20b=function(){return ta.scale.ordinal().range(wl)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Sl)};var bl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(Mt),_l=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(Mt),wl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(Mt),Sl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(Mt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-Ra,f=a.apply(this,arguments)-Ra,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ta)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===kl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=tt(d/l*Math.sin(m))),n&&(E=tt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=qa?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=qa?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),I=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],I[1][0],I[1][1]),",",g," ",I[1],"A",H,",",H," 0 0,",v," ",I[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",I[0])}else N.push("M",y,",",M);if(null!=S){var Y=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-Y,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-Y,g);p===Y?N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",Y,",",Y," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=kl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.outerRadius=function(t){return arguments.length?(r=Et(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=Et(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==kl?kl:Et(t),n):i},n.startAngle=function(t){return arguments.length?(o=Et(t),n):o},n.endAngle=function(t){return arguments.length?(a=Et(t),n):a},n.padAngle=function(t){return arguments.length?(c=Et(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Ra;return[Math.cos(t)*n,Math.sin(t)*n]},n};var kl="auto";ta.svg.line=function(){return ho(y)};var El=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});El.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Al=[0,2/3,1/3,0],Nl=[0,1/3,2/3,0],Cl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(y)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-Ra,s=l.call(n,u,r)-Ra;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>qa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(l=Et(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(zl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var zl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=zl.keys();var ql=Math.sqrt(3),Ll=Math.tan(30*Da);_a.transition=function(n){for(var t,e,r=Tl||++Ul,u=Xo(n),i=[],o=Rl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++ai;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Yo(u,this.namespace,this.id)},Pl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Pl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Pl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Pl.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=mu(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Zo(this,"style."+n,e,i)},Pl.styleTween=function(n,e,r){function u(u,i){var o=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Pl.text=function(n){return Zo(this,"text",n,Vo)},Pl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Pl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),Y(this,function(r){r[e][t].ease=n}))},Pl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Pl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Pl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Rl,i=Tl;try{Tl=e,Y(this,function(t,u,i){Rl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Rl=u,Tl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Pl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ul,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Yo(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):y:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ca),d=ta.transition(p.exit()).style("opacity",Ca).remove(),m=ta.transition(p.order()).style("opacity",1),M=Math.max(u,0)+o,x=Ui(f),b=l.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ta.transition(b));v.append("line"),v.append("text");var w,S,k,E,A=v.select("line"),N=m.select("line"),C=p.select("text").text(g),z=v.select("text"),q=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,w="x",k="y",S="x2",E="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Wo,w="y",k="x",S="y2",E="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),A.attr(E,L*u),z.attr(k,L*M),N.attr(S,0).attr(E,L*u),q.attr(w,0).attr(k,L*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=jl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Fl?t+"":jl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var jl="bottom",Fl={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(t){t.each(function(){var t=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,y);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Hl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var c,f=ta.transition(t),h=ta.transition(o);l&&(c=Ui(l),h.attr("x",c[0]).attr("width",c[1]-c[0]),r(f)),s&&(c=Ui(s),h.attr("y",c[0]).attr("height",c[1]-c[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==ta.event.keyCode&&(C||(M=null,q[0]-=f[1],q[1]-=h[1],C=2),S())}function v(){32==ta.event.keyCode&&2==C&&(q[0]+=f[1],q[1]+=h[1],C=0,S())}function d(){var n=ta.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ta.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),q[0]=f[+(n[0]s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?a=null:o=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ta.select(ta.event.target),w=c.of(b,arguments),k=ta.select(b),E=_.datum(),A=!/^(n|s)$/.test(E)&&l,N=!/^(e|w)$/.test(E)&&s,C=_.classed("extent"),z=W(b),q=ta.mouse(b),L=ta.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(ta.event.changedTouches?L.on("touchmove.brush",d).on("touchend.brush",y):L.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)q[0]=f[0]-q[0],q[1]=h[0]-q[1];else if(E){var T=+/w$/.test(E),R=+/^n/.test(E);x=[f[1-T]-q[0],h[1-R]-q[1]],q[0]=f[T],q[1]=h[R]}else ta.event.altKey&&(M=q.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,c=E(n,"brushstart","brush","brushend"),l=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=Ol[0];return n.event=function(n){n.each(function(){var n=c.of(this,arguments),t={x:f,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Tl?ta.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(f,t.x),r=yu(h,t.y);return o=a=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(l=t,v=Ol[!l<<1|!s],n):l},n.y=function(t){return arguments.length?(s=t,v=Ol[!l<<1|!s],n):s},n.clamp=function(t){return arguments.length?(l&&s?(g=!!t[0],p=!!t[1]):l?g=!!t:s&&(p=!!t),n):l&&s?[g,p]:l?g:s?p:null},n.extent=function(t){var e,r,u,i,c;return arguments.length?(l&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),o=[e,r],l.invert&&(e=l(e),r=l(r)),e>r&&(c=e,e=r,r=c),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],l&&(u=u[1],i=i[1]),a=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(c=u,u=i,i=c),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(l&&(o?(e=o[0],r=o[1]):(e=f[0],r=f[1],l.invert&&(e=l.invert(e),r=l.invert(r)),e>r&&(c=e,e=r,r=c))),s&&(a?(u=a[0],i=a[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(c=u,u=i,i=c))),l&&s?[[e,u],[r,i]]:l?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!l&&f[0]==f[1]||!!s&&h[0]==h[1]},ta.rebind(n,c,"on")};var Hl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ol=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Il=ac.format=gc.timeFormat,Yl=Il.utc,Zl=Yl("%Y-%m-%dT%H:%M:%S.%LZ");Il.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Zl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Zl.toString,ac.second=Ft(function(n){return new cc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ac.seconds=ac.second.range,ac.seconds.utc=ac.second.utc.range,ac.minute=Ft(function(n){return new cc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ac.minutes=ac.minute.range,ac.minutes.utc=ac.minute.utc.range,ac.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new cc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ac.hours=ac.hour.range,ac.hours.utc=ac.hour.utc.range,ac.month=Ft(function(n){return n=ac.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ac.months=ac.month.range,ac.months.utc=ac.month.utc.range;var Vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Xl=[[ac.second,1],[ac.second,5],[ac.second,15],[ac.second,30],[ac.minute,1],[ac.minute,5],[ac.minute,15],[ac.minute,30],[ac.hour,1],[ac.hour,3],[ac.hour,6],[ac.hour,12],[ac.day,1],[ac.day,2],[ac.week,1],[ac.month,1],[ac.month,3],[ac.year,1]],$l=Il.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Bl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:y,ceil:y};Xl.year=ac.year,ac.scale=function(){return Go(ta.scale.linear(),Xl,$l)};var Wl=Xl.map(function(n){return[n[0].utc,n[1]]}),Jl=Yl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Wl.year=ac.year.utc,ac.scale.utc=function(){return Go(ta.scale.linear(),Wl,Jl)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}(); \ No newline at end of file diff --git a/docs/site_libs/htmlwidgets-1.5.4/htmlwidgets.js b/docs/site_libs/htmlwidgets-1.5.4/htmlwidgets.js new file mode 100644 index 0000000..da8b236 --- /dev/null +++ b/docs/site_libs/htmlwidgets-1.5.4/htmlwidgets.js @@ -0,0 +1,903 @@ +(function() { + // If window.HTMLWidgets is already defined, then use it; otherwise create a + // new object. This allows preceding code to set options that affect the + // initialization process (though none currently exist). + window.HTMLWidgets = window.HTMLWidgets || {}; + + // See if we're running in a viewer pane. If not, we're in a web browser. + var viewerMode = window.HTMLWidgets.viewerMode = + /\bviewer_pane=1\b/.test(window.location); + + // See if we're running in Shiny mode. If not, it's a static document. + // Note that static widgets can appear in both Shiny and static modes, but + // obviously, Shiny widgets can only appear in Shiny apps/documents. + var shinyMode = window.HTMLWidgets.shinyMode = + typeof(window.Shiny) !== "undefined" && !!window.Shiny.outputBindings; + + // We can't count on jQuery being available, so we implement our own + // version if necessary. + function querySelectorAll(scope, selector) { + if (typeof(jQuery) !== "undefined" && scope instanceof jQuery) { + return scope.find(selector); + } + if (scope.querySelectorAll) { + return scope.querySelectorAll(selector); + } + } + + function asArray(value) { + if (value === null) + return []; + if ($.isArray(value)) + return value; + return [value]; + } + + // Implement jQuery's extend + function extend(target /*, ... */) { + if (arguments.length == 1) { + return target; + } + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var prop in source) { + if (source.hasOwnProperty(prop)) { + target[prop] = source[prop]; + } + } + } + return target; + } + + // IE8 doesn't support Array.forEach. + function forEach(values, callback, thisArg) { + if (values.forEach) { + values.forEach(callback, thisArg); + } else { + for (var i = 0; i < values.length; i++) { + callback.call(thisArg, values[i], i, values); + } + } + } + + // Replaces the specified method with the return value of funcSource. + // + // Note that funcSource should not BE the new method, it should be a function + // that RETURNS the new method. funcSource receives a single argument that is + // the overridden method, it can be called from the new method. The overridden + // method can be called like a regular function, it has the target permanently + // bound to it so "this" will work correctly. + function overrideMethod(target, methodName, funcSource) { + var superFunc = target[methodName] || function() {}; + var superFuncBound = function() { + return superFunc.apply(target, arguments); + }; + target[methodName] = funcSource(superFuncBound); + } + + // Add a method to delegator that, when invoked, calls + // delegatee.methodName. If there is no such method on + // the delegatee, but there was one on delegator before + // delegateMethod was called, then the original version + // is invoked instead. + // For example: + // + // var a = { + // method1: function() { console.log('a1'); } + // method2: function() { console.log('a2'); } + // }; + // var b = { + // method1: function() { console.log('b1'); } + // }; + // delegateMethod(a, b, "method1"); + // delegateMethod(a, b, "method2"); + // a.method1(); + // a.method2(); + // + // The output would be "b1", "a2". + function delegateMethod(delegator, delegatee, methodName) { + var inherited = delegator[methodName]; + delegator[methodName] = function() { + var target = delegatee; + var method = delegatee[methodName]; + + // The method doesn't exist on the delegatee. Instead, + // call the method on the delegator, if it exists. + if (!method) { + target = delegator; + method = inherited; + } + + if (method) { + return method.apply(target, arguments); + } + }; + } + + // Implement a vague facsimilie of jQuery's data method + function elementData(el, name, value) { + if (arguments.length == 2) { + return el["htmlwidget_data_" + name]; + } else if (arguments.length == 3) { + el["htmlwidget_data_" + name] = value; + return el; + } else { + throw new Error("Wrong number of arguments for elementData: " + + arguments.length); + } + } + + // http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex + function escapeRegExp(str) { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + } + + function hasClass(el, className) { + var re = new RegExp("\\b" + escapeRegExp(className) + "\\b"); + return re.test(el.className); + } + + // elements - array (or array-like object) of HTML elements + // className - class name to test for + // include - if true, only return elements with given className; + // if false, only return elements *without* given className + function filterByClass(elements, className, include) { + var results = []; + for (var i = 0; i < elements.length; i++) { + if (hasClass(elements[i], className) == include) + results.push(elements[i]); + } + return results; + } + + function on(obj, eventName, func) { + if (obj.addEventListener) { + obj.addEventListener(eventName, func, false); + } else if (obj.attachEvent) { + obj.attachEvent(eventName, func); + } + } + + function off(obj, eventName, func) { + if (obj.removeEventListener) + obj.removeEventListener(eventName, func, false); + else if (obj.detachEvent) { + obj.detachEvent(eventName, func); + } + } + + // Translate array of values to top/right/bottom/left, as usual with + // the "padding" CSS property + // https://developer.mozilla.org/en-US/docs/Web/CSS/padding + function unpackPadding(value) { + if (typeof(value) === "number") + value = [value]; + if (value.length === 1) { + return {top: value[0], right: value[0], bottom: value[0], left: value[0]}; + } + if (value.length === 2) { + return {top: value[0], right: value[1], bottom: value[0], left: value[1]}; + } + if (value.length === 3) { + return {top: value[0], right: value[1], bottom: value[2], left: value[1]}; + } + if (value.length === 4) { + return {top: value[0], right: value[1], bottom: value[2], left: value[3]}; + } + } + + // Convert an unpacked padding object to a CSS value + function paddingToCss(paddingObj) { + return paddingObj.top + "px " + paddingObj.right + "px " + paddingObj.bottom + "px " + paddingObj.left + "px"; + } + + // Makes a number suitable for CSS + function px(x) { + if (typeof(x) === "number") + return x + "px"; + else + return x; + } + + // Retrieves runtime widget sizing information for an element. + // The return value is either null, or an object with fill, padding, + // defaultWidth, defaultHeight fields. + function sizingPolicy(el) { + var sizingEl = document.querySelector("script[data-for='" + el.id + "'][type='application/htmlwidget-sizing']"); + if (!sizingEl) + return null; + var sp = JSON.parse(sizingEl.textContent || sizingEl.text || "{}"); + if (viewerMode) { + return sp.viewer; + } else { + return sp.browser; + } + } + + // @param tasks Array of strings (or falsy value, in which case no-op). + // Each element must be a valid JavaScript expression that yields a + // function. Or, can be an array of objects with "code" and "data" + // properties; in this case, the "code" property should be a string + // of JS that's an expr that yields a function, and "data" should be + // an object that will be added as an additional argument when that + // function is called. + // @param target The object that will be "this" for each function + // execution. + // @param args Array of arguments to be passed to the functions. (The + // same arguments will be passed to all functions.) + function evalAndRun(tasks, target, args) { + if (tasks) { + forEach(tasks, function(task) { + var theseArgs = args; + if (typeof(task) === "object") { + theseArgs = theseArgs.concat([task.data]); + task = task.code; + } + var taskFunc = tryEval(task); + if (typeof(taskFunc) !== "function") { + throw new Error("Task must be a function! Source:\n" + task); + } + taskFunc.apply(target, theseArgs); + }); + } + } + + // Attempt eval() both with and without enclosing in parentheses. + // Note that enclosing coerces a function declaration into + // an expression that eval() can parse + // (otherwise, a SyntaxError is thrown) + function tryEval(code) { + var result = null; + try { + result = eval("(" + code + ")"); + } catch(error) { + if (!(error instanceof SyntaxError)) { + throw error; + } + try { + result = eval(code); + } catch(e) { + if (e instanceof SyntaxError) { + throw error; + } else { + throw e; + } + } + } + return result; + } + + function initSizing(el) { + var sizing = sizingPolicy(el); + if (!sizing) + return; + + var cel = document.getElementById("htmlwidget_container"); + if (!cel) + return; + + if (typeof(sizing.padding) !== "undefined") { + document.body.style.margin = "0"; + document.body.style.padding = paddingToCss(unpackPadding(sizing.padding)); + } + + if (sizing.fill) { + document.body.style.overflow = "hidden"; + document.body.style.width = "100%"; + document.body.style.height = "100%"; + document.documentElement.style.width = "100%"; + document.documentElement.style.height = "100%"; + if (cel) { + cel.style.position = "absolute"; + var pad = unpackPadding(sizing.padding); + cel.style.top = pad.top + "px"; + cel.style.right = pad.right + "px"; + cel.style.bottom = pad.bottom + "px"; + cel.style.left = pad.left + "px"; + el.style.width = "100%"; + el.style.height = "100%"; + } + + return { + getWidth: function() { return cel.offsetWidth; }, + getHeight: function() { return cel.offsetHeight; } + }; + + } else { + el.style.width = px(sizing.width); + el.style.height = px(sizing.height); + + return { + getWidth: function() { return el.offsetWidth; }, + getHeight: function() { return el.offsetHeight; } + }; + } + } + + // Default implementations for methods + var defaults = { + find: function(scope) { + return querySelectorAll(scope, "." + this.name); + }, + renderError: function(el, err) { + var $el = $(el); + + this.clearError(el); + + // Add all these error classes, as Shiny does + var errClass = "shiny-output-error"; + if (err.type !== null) { + // use the classes of the error condition as CSS class names + errClass = errClass + " " + $.map(asArray(err.type), function(type) { + return errClass + "-" + type; + }).join(" "); + } + errClass = errClass + " htmlwidgets-error"; + + // Is el inline or block? If inline or inline-block, just display:none it + // and add an inline error. + var display = $el.css("display"); + $el.data("restore-display-mode", display); + + if (display === "inline" || display === "inline-block") { + $el.hide(); + if (err.message !== "") { + var errorSpan = $("").addClass(errClass); + errorSpan.text(err.message); + $el.after(errorSpan); + } + } else if (display === "block") { + // If block, add an error just after the el, set visibility:none on the + // el, and position the error to be on top of the el. + // Mark it with a unique ID and CSS class so we can remove it later. + $el.css("visibility", "hidden"); + if (err.message !== "") { + var errorDiv = $("
").addClass(errClass).css("position", "absolute") + .css("top", el.offsetTop) + .css("left", el.offsetLeft) + // setting width can push out the page size, forcing otherwise + // unnecessary scrollbars to appear and making it impossible for + // the element to shrink; so use max-width instead + .css("maxWidth", el.offsetWidth) + .css("height", el.offsetHeight); + errorDiv.text(err.message); + $el.after(errorDiv); + + // Really dumb way to keep the size/position of the error in sync with + // the parent element as the window is resized or whatever. + var intId = setInterval(function() { + if (!errorDiv[0].parentElement) { + clearInterval(intId); + return; + } + errorDiv + .css("top", el.offsetTop) + .css("left", el.offsetLeft) + .css("maxWidth", el.offsetWidth) + .css("height", el.offsetHeight); + }, 500); + } + } + }, + clearError: function(el) { + var $el = $(el); + var display = $el.data("restore-display-mode"); + $el.data("restore-display-mode", null); + + if (display === "inline" || display === "inline-block") { + if (display) + $el.css("display", display); + $(el.nextSibling).filter(".htmlwidgets-error").remove(); + } else if (display === "block"){ + $el.css("visibility", "inherit"); + $(el.nextSibling).filter(".htmlwidgets-error").remove(); + } + }, + sizing: {} + }; + + // Called by widget bindings to register a new type of widget. The definition + // object can contain the following properties: + // - name (required) - A string indicating the binding name, which will be + // used by default as the CSS classname to look for. + // - initialize (optional) - A function(el) that will be called once per + // widget element; if a value is returned, it will be passed as the third + // value to renderValue. + // - renderValue (required) - A function(el, data, initValue) that will be + // called with data. Static contexts will cause this to be called once per + // element; Shiny apps will cause this to be called multiple times per + // element, as the data changes. + window.HTMLWidgets.widget = function(definition) { + if (!definition.name) { + throw new Error("Widget must have a name"); + } + if (!definition.type) { + throw new Error("Widget must have a type"); + } + // Currently we only support output widgets + if (definition.type !== "output") { + throw new Error("Unrecognized widget type '" + definition.type + "'"); + } + // TODO: Verify that .name is a valid CSS classname + + // Support new-style instance-bound definitions. Old-style class-bound + // definitions have one widget "object" per widget per type/class of + // widget; the renderValue and resize methods on such widget objects + // take el and instance arguments, because the widget object can't + // store them. New-style instance-bound definitions have one widget + // object per widget instance; the definition that's passed in doesn't + // provide renderValue or resize methods at all, just the single method + // factory(el, width, height) + // which returns an object that has renderValue(x) and resize(w, h). + // This enables a far more natural programming style for the widget + // author, who can store per-instance state using either OO-style + // instance fields or functional-style closure variables (I guess this + // is in contrast to what can only be called C-style pseudo-OO which is + // what we required before). + if (definition.factory) { + definition = createLegacyDefinitionAdapter(definition); + } + + if (!definition.renderValue) { + throw new Error("Widget must have a renderValue function"); + } + + // For static rendering (non-Shiny), use a simple widget registration + // scheme. We also use this scheme for Shiny apps/documents that also + // contain static widgets. + window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || []; + // Merge defaults into the definition; don't mutate the original definition. + var staticBinding = extend({}, defaults, definition); + overrideMethod(staticBinding, "find", function(superfunc) { + return function(scope) { + var results = superfunc(scope); + // Filter out Shiny outputs, we only want the static kind + return filterByClass(results, "html-widget-output", false); + }; + }); + window.HTMLWidgets.widgets.push(staticBinding); + + if (shinyMode) { + // Shiny is running. Register the definition with an output binding. + // The definition itself will not be the output binding, instead + // we will make an output binding object that delegates to the + // definition. This is because we foolishly used the same method + // name (renderValue) for htmlwidgets definition and Shiny bindings + // but they actually have quite different semantics (the Shiny + // bindings receive data that includes lots of metadata that it + // strips off before calling htmlwidgets renderValue). We can't + // just ignore the difference because in some widgets it's helpful + // to call this.renderValue() from inside of resize(), and if + // we're not delegating, then that call will go to the Shiny + // version instead of the htmlwidgets version. + + // Merge defaults with definition, without mutating either. + var bindingDef = extend({}, defaults, definition); + + // This object will be our actual Shiny binding. + var shinyBinding = new Shiny.OutputBinding(); + + // With a few exceptions, we'll want to simply use the bindingDef's + // version of methods if they are available, otherwise fall back to + // Shiny's defaults. NOTE: If Shiny's output bindings gain additional + // methods in the future, and we want them to be overrideable by + // HTMLWidget binding definitions, then we'll need to add them to this + // list. + delegateMethod(shinyBinding, bindingDef, "getId"); + delegateMethod(shinyBinding, bindingDef, "onValueChange"); + delegateMethod(shinyBinding, bindingDef, "onValueError"); + delegateMethod(shinyBinding, bindingDef, "renderError"); + delegateMethod(shinyBinding, bindingDef, "clearError"); + delegateMethod(shinyBinding, bindingDef, "showProgress"); + + // The find, renderValue, and resize are handled differently, because we + // want to actually decorate the behavior of the bindingDef methods. + + shinyBinding.find = function(scope) { + var results = bindingDef.find(scope); + + // Only return elements that are Shiny outputs, not static ones + var dynamicResults = results.filter(".html-widget-output"); + + // It's possible that whatever caused Shiny to think there might be + // new dynamic outputs, also caused there to be new static outputs. + // Since there might be lots of different htmlwidgets bindings, we + // schedule execution for later--no need to staticRender multiple + // times. + if (results.length !== dynamicResults.length) + scheduleStaticRender(); + + return dynamicResults; + }; + + // Wrap renderValue to handle initialization, which unfortunately isn't + // supported natively by Shiny at the time of this writing. + + shinyBinding.renderValue = function(el, data) { + Shiny.renderDependencies(data.deps); + // Resolve strings marked as javascript literals to objects + if (!(data.evals instanceof Array)) data.evals = [data.evals]; + for (var i = 0; data.evals && i < data.evals.length; i++) { + window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]); + } + if (!bindingDef.renderOnNullValue) { + if (data.x === null) { + el.style.visibility = "hidden"; + return; + } else { + el.style.visibility = "inherit"; + } + } + if (!elementData(el, "initialized")) { + initSizing(el); + + elementData(el, "initialized", true); + if (bindingDef.initialize) { + var result = bindingDef.initialize(el, el.offsetWidth, + el.offsetHeight); + elementData(el, "init_result", result); + } + } + bindingDef.renderValue(el, data.x, elementData(el, "init_result")); + evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]); + }; + + // Only override resize if bindingDef implements it + if (bindingDef.resize) { + shinyBinding.resize = function(el, width, height) { + // Shiny can call resize before initialize/renderValue have been + // called, which doesn't make sense for widgets. + if (elementData(el, "initialized")) { + bindingDef.resize(el, width, height, elementData(el, "init_result")); + } + }; + } + + Shiny.outputBindings.register(shinyBinding, bindingDef.name); + } + }; + + var scheduleStaticRenderTimerId = null; + function scheduleStaticRender() { + if (!scheduleStaticRenderTimerId) { + scheduleStaticRenderTimerId = setTimeout(function() { + scheduleStaticRenderTimerId = null; + window.HTMLWidgets.staticRender(); + }, 1); + } + } + + // Render static widgets after the document finishes loading + // Statically render all elements that are of this widget's class + window.HTMLWidgets.staticRender = function() { + var bindings = window.HTMLWidgets.widgets || []; + forEach(bindings, function(binding) { + var matches = binding.find(document.documentElement); + forEach(matches, function(el) { + var sizeObj = initSizing(el, binding); + + if (hasClass(el, "html-widget-static-bound")) + return; + el.className = el.className + " html-widget-static-bound"; + + var initResult; + if (binding.initialize) { + initResult = binding.initialize(el, + sizeObj ? sizeObj.getWidth() : el.offsetWidth, + sizeObj ? sizeObj.getHeight() : el.offsetHeight + ); + elementData(el, "init_result", initResult); + } + + if (binding.resize) { + var lastSize = { + w: sizeObj ? sizeObj.getWidth() : el.offsetWidth, + h: sizeObj ? sizeObj.getHeight() : el.offsetHeight + }; + var resizeHandler = function(e) { + var size = { + w: sizeObj ? sizeObj.getWidth() : el.offsetWidth, + h: sizeObj ? sizeObj.getHeight() : el.offsetHeight + }; + if (size.w === 0 && size.h === 0) + return; + if (size.w === lastSize.w && size.h === lastSize.h) + return; + lastSize = size; + binding.resize(el, size.w, size.h, initResult); + }; + + on(window, "resize", resizeHandler); + + // This is needed for cases where we're running in a Shiny + // app, but the widget itself is not a Shiny output, but + // rather a simple static widget. One example of this is + // an rmarkdown document that has runtime:shiny and widget + // that isn't in a render function. Shiny only knows to + // call resize handlers for Shiny outputs, not for static + // widgets, so we do it ourselves. + if (window.jQuery) { + window.jQuery(document).on( + "shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets", + resizeHandler + ); + window.jQuery(document).on( + "hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets", + resizeHandler + ); + } + + // This is needed for the specific case of ioslides, which + // flips slides between display:none and display:block. + // Ideally we would not have to have ioslide-specific code + // here, but rather have ioslides raise a generic event, + // but the rmarkdown package just went to CRAN so the + // window to getting that fixed may be long. + if (window.addEventListener) { + // It's OK to limit this to window.addEventListener + // browsers because ioslides itself only supports + // such browsers. + on(document, "slideenter", resizeHandler); + on(document, "slideleave", resizeHandler); + } + } + + var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']"); + if (scriptData) { + var data = JSON.parse(scriptData.textContent || scriptData.text); + // Resolve strings marked as javascript literals to objects + if (!(data.evals instanceof Array)) data.evals = [data.evals]; + for (var k = 0; data.evals && k < data.evals.length; k++) { + window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]); + } + binding.renderValue(el, data.x, initResult); + evalAndRun(data.jsHooks.render, initResult, [el, data.x]); + } + }); + }); + + invokePostRenderHandlers(); + } + + + function has_jQuery3() { + if (!window.jQuery) { + return false; + } + var $version = window.jQuery.fn.jquery; + var $major_version = parseInt($version.split(".")[0]); + return $major_version >= 3; + } + + /* + / Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's + / on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now + / really means $(setTimeout(fn)). + / https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous + / + / Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny + / one tick later than it did before, which means staticRender() is + / called renderValue() earlier than (advanced) widget authors might be expecting. + / https://github.com/rstudio/shiny/issues/2630 + / + / For a concrete example, leaflet has some methods (e.g., updateBounds) + / which reference Shiny methods registered in initShiny (e.g., setInputValue). + / Since leaflet is privy to this life-cycle, it knows to use setTimeout() to + / delay execution of those methods (until Shiny methods are ready) + / https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268 + / + / Ideally widget authors wouldn't need to use this setTimeout() hack that + / leaflet uses to call Shiny methods on a staticRender(). In the long run, + / the logic initShiny should be broken up so that method registration happens + / right away, but binding happens later. + */ + function maybeStaticRenderLater() { + if (shinyMode && has_jQuery3()) { + window.jQuery(window.HTMLWidgets.staticRender); + } else { + window.HTMLWidgets.staticRender(); + } + } + + if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", function() { + document.removeEventListener("DOMContentLoaded", arguments.callee, false); + maybeStaticRenderLater(); + }, false); + } else if (document.attachEvent) { + document.attachEvent("onreadystatechange", function() { + if (document.readyState === "complete") { + document.detachEvent("onreadystatechange", arguments.callee); + maybeStaticRenderLater(); + } + }); + } + + + window.HTMLWidgets.getAttachmentUrl = function(depname, key) { + // If no key, default to the first item + if (typeof(key) === "undefined") + key = 1; + + var link = document.getElementById(depname + "-" + key + "-attachment"); + if (!link) { + throw new Error("Attachment " + depname + "/" + key + " not found in document"); + } + return link.getAttribute("href"); + }; + + window.HTMLWidgets.dataframeToD3 = function(df) { + var names = []; + var length; + for (var name in df) { + if (df.hasOwnProperty(name)) + names.push(name); + if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") { + throw new Error("All fields must be arrays"); + } else if (typeof(length) !== "undefined" && length !== df[name].length) { + throw new Error("All fields must be arrays of the same length"); + } + length = df[name].length; + } + var results = []; + var item; + for (var row = 0; row < length; row++) { + item = {}; + for (var col = 0; col < names.length; col++) { + item[names[col]] = df[names[col]][row]; + } + results.push(item); + } + return results; + }; + + window.HTMLWidgets.transposeArray2D = function(array) { + if (array.length === 0) return array; + var newArray = array[0].map(function(col, i) { + return array.map(function(row) { + return row[i] + }) + }); + return newArray; + }; + // Split value at splitChar, but allow splitChar to be escaped + // using escapeChar. Any other characters escaped by escapeChar + // will be included as usual (including escapeChar itself). + function splitWithEscape(value, splitChar, escapeChar) { + var results = []; + var escapeMode = false; + var currentResult = ""; + for (var pos = 0; pos < value.length; pos++) { + if (!escapeMode) { + if (value[pos] === splitChar) { + results.push(currentResult); + currentResult = ""; + } else if (value[pos] === escapeChar) { + escapeMode = true; + } else { + currentResult += value[pos]; + } + } else { + currentResult += value[pos]; + escapeMode = false; + } + } + if (currentResult !== "") { + results.push(currentResult); + } + return results; + } + // Function authored by Yihui/JJ Allaire + window.HTMLWidgets.evaluateStringMember = function(o, member) { + var parts = splitWithEscape(member, '.', '\\'); + for (var i = 0, l = parts.length; i < l; i++) { + var part = parts[i]; + // part may be a character or 'numeric' member name + if (o !== null && typeof o === "object" && part in o) { + if (i == (l - 1)) { // if we are at the end of the line then evalulate + if (typeof o[part] === "string") + o[part] = tryEval(o[part]); + } else { // otherwise continue to next embedded object + o = o[part]; + } + } + } + }; + + // Retrieve the HTMLWidget instance (i.e. the return value of an + // HTMLWidget binding's initialize() or factory() function) + // associated with an element, or null if none. + window.HTMLWidgets.getInstance = function(el) { + return elementData(el, "init_result"); + }; + + // Finds the first element in the scope that matches the selector, + // and returns the HTMLWidget instance (i.e. the return value of + // an HTMLWidget binding's initialize() or factory() function) + // associated with that element, if any. If no element matches the + // selector, or the first matching element has no HTMLWidget + // instance associated with it, then null is returned. + // + // The scope argument is optional, and defaults to window.document. + window.HTMLWidgets.find = function(scope, selector) { + if (arguments.length == 1) { + selector = scope; + scope = document; + } + + var el = scope.querySelector(selector); + if (el === null) { + return null; + } else { + return window.HTMLWidgets.getInstance(el); + } + }; + + // Finds all elements in the scope that match the selector, and + // returns the HTMLWidget instances (i.e. the return values of + // an HTMLWidget binding's initialize() or factory() function) + // associated with the elements, in an array. If elements that + // match the selector don't have an associated HTMLWidget + // instance, the returned array will contain nulls. + // + // The scope argument is optional, and defaults to window.document. + window.HTMLWidgets.findAll = function(scope, selector) { + if (arguments.length == 1) { + selector = scope; + scope = document; + } + + var nodes = scope.querySelectorAll(selector); + var results = []; + for (var i = 0; i < nodes.length; i++) { + results.push(window.HTMLWidgets.getInstance(nodes[i])); + } + return results; + }; + + var postRenderHandlers = []; + function invokePostRenderHandlers() { + while (postRenderHandlers.length) { + var handler = postRenderHandlers.shift(); + if (handler) { + handler(); + } + } + } + + // Register the given callback function to be invoked after the + // next time static widgets are rendered. + window.HTMLWidgets.addPostRenderHandler = function(callback) { + postRenderHandlers.push(callback); + }; + + // Takes a new-style instance-bound definition, and returns an + // old-style class-bound definition. This saves us from having + // to rewrite all the logic in this file to accomodate both + // types of definitions. + function createLegacyDefinitionAdapter(defn) { + var result = { + name: defn.name, + type: defn.type, + initialize: function(el, width, height) { + return defn.factory(el, width, height); + }, + renderValue: function(el, x, instance) { + return instance.renderValue(x); + }, + resize: function(el, width, height, instance) { + return instance.resize(width, height); + } + }; + + if (defn.find) + result.find = defn.find; + if (defn.renderError) + result.renderError = defn.renderError; + if (defn.clearError) + result.clearError = defn.clearError; + + return result; + } +})(); + diff --git a/docs/site_libs/jquery-3.5.1/jquery-AUTHORS.txt b/docs/site_libs/jquery-3.5.1/jquery-AUTHORS.txt new file mode 100644 index 0000000..06df1a5 --- /dev/null +++ b/docs/site_libs/jquery-3.5.1/jquery-AUTHORS.txt @@ -0,0 +1,357 @@ +Authors ordered by first contribution. + +John Resig +Gilles van den Hoven +Michael Geary +Stefan Petre +Yehuda Katz +Corey Jewett +Klaus Hartl +Franck Marcia +Jörn Zaefferer +Paul Bakaus +Brandon Aaron +Mike Alsup +Dave Methvin +Ed Engelhardt +Sean Catchpole +Paul Mclanahan +David Serduke +Richard D. Worth +Scott González +Ariel Flesler +Cheah Chu Yeow +Andrew Chalkley +Fabio Buffoni +Stefan Bauckmeier  +Jon Evans +TJ Holowaychuk +Riccardo De Agostini +Michael Bensoussan +Louis-Rémi Babé +Robert Katić +Damian Janowski +Anton Kovalyov +Dušan B. Jovanovic +Earle Castledine +Rich Dougherty +Kim Dalsgaard +Andrea Giammarchi +Fabian Jakobs +Mark Gibson +Karl Swedberg +Justin Meyer +Ben Alman +James Padolsey +David Petersen +Batiste Bieler +Jake Archibald +Alexander Farkas +Filipe Fortes +Rick Waldron +Neeraj Singh +Paul Irish +Iraê Carvalho +Matt Curry +Michael Monteleone +Noah Sloan +Tom Viner +J. Ryan Stinnett +Douglas Neiner +Adam J. Sontag +Heungsub Lee +Dave Reed +Carl Fürstenberg +Jacob Wright +Ralph Whitbeck +unknown +temp01 +Colin Snover +Jared Grippe +Ryan W Tenney +Alex Sexton +Pinhook +Ron Otten +Jephte Clain +Anton Matzneller +Dan Heberden +Henri Wiechers +Russell Holbrook +Julian Aubourg +Gianni Alessandro Chiappetta +Scott Jehl +James Burke +Jonas Pfenniger +Xavi Ramirez +Sylvester Keil +Brandon Sterne +Mathias Bynens +Lee Carpenter +Timmy Willison <4timmywil@gmail.com> +Corey Frang +Digitalxero +David Murdoch +Josh Varner +Charles McNulty +Jordan Boesch +Jess Thrysoee +Michael Murray +Alexis Abril +Rob Morgan +John Firebaugh +Sam Bisbee +Gilmore Davidson +Brian Brennan +Xavier Montillet +Daniel Pihlstrom +Sahab Yazdani +avaly +Scott Hughes +Mike Sherov +Greg Hazel +Schalk Neethling +Denis Knauf +Timo Tijhof +Steen Nielsen +Anton Ryzhov +Shi Chuan +Matt Mueller +Berker Peksag +Toby Brain +Justin +Daniel Herman +Oleg Gaidarenko +Rock Hymas +Richard Gibson +Rafaël Blais Masson +cmc3cn <59194618@qq.com> +Joe Presbrey +Sindre Sorhus +Arne de Bree +Vladislav Zarakovsky +Andrew E Monat +Oskari +Joao Henrique de Andrade Bruni +tsinha +Dominik D. Geyer +Matt Farmer +Trey Hunner +Jason Moon +Jeffery To +Kris Borchers +Vladimir Zhuravlev +Jacob Thornton +Chad Killingsworth +Vitya Muhachev +Nowres Rafid +David Benjamin +Alan Plum +Uri Gilad +Chris Faulkner +Marcel Greter +Elijah Manor +Daniel Chatfield +Daniel Gálvez +Nikita Govorov +Wesley Walser +Mike Pennisi +Matthias Jäggli +Devin Cooper +Markus Staab +Dave Riddle +Callum Macrae +Jonathan Sampson +Benjamin Truyman +Jay Merrifield +James Huston +Sai Lung Wong +Erick Ruiz de Chávez +David Bonner +Allen J Schmidt Jr +Akintayo Akinwunmi +MORGAN +Ismail Khair +Carl Danley +Mike Petrovich +Greg Lavallee +Tom H Fuertes +Roland Eckl +Yiming He +David Fox +Bennett Sorbo +Paul Ramos +Rod Vagg +Sebastian Burkhard +Zachary Adam Kaplan +Adam Coulombe +nanto_vi +nanto +Danil Somsikov +Ryunosuke SATO +Diego Tres +Jean Boussier +Andrew Plummer +Mark Raddatz +Pascal Borreli +Isaac Z. Schlueter +Karl Sieburg +Nguyen Phuc Lam +Dmitry Gusev +Steven Benner +Li Xudong +Michał Gołębiowski-Owczarek +Renato Oliveira dos Santos +Frederic Junod +Tom H Fuertes +Mitch Foley +ros3cin +Kyle Robinson Young +John Paul +Jason Bedard +Chris Talkington +Eddie Monge +Terry Jones +Jason Merino +Dan Burzo +Jeremy Dunck +Chris Price +Guy Bedford +njhamann +Goare Mao +Amey Sakhadeo +Mike Sidorov +Anthony Ryan +Lihan Li +George Kats +Dongseok Paeng +Ronny Springer +Ilya Kantor +Marian Sollmann +Chris Antaki +David Hong +Jakob Stoeck +Christopher Jones +Forbes Lindesay +S. Andrew Sheppard +Leonardo Balter +Rodrigo Rosenfeld Rosas +Daniel Husar +Philip Jägenstedt +John Hoven +Roman Reiß +Benjy Cui +Christian Kosmowski +David Corbacho +Liang Peng +TJ VanToll +Aurelio De Rosa +Senya Pugach +Dan Hart +Nazar Mokrynskyi +Benjamin Tan +Amit Merchant +Jason Bedard +Veaceslav Grimalschi +Richard McDaniel +Arthur Verschaeve +Shivaji Varma +Ben Toews +Bin Xin +Neftaly Hernandez +T.J. Crowder +Nicolas HENRY +Frederic Hemberger +Victor Homyakov +Aditya Raghavan +Anne-Gaelle Colom +Leonardo Braga +George Mauer +Stephen Edgar +Thomas Tortorini +Jörn Wagner +Jon Hester +Colin Frick +Winston Howes +Alexander O'Mara +Chris Rebert +Bastian Buchholz +Mu Haibao +Calvin Metcalf +Arthur Stolyar +Gabriel Schulhof +Gilad Peleg +Julian Alexander Murillo +Kevin Kirsche +Martin Naumann +Yongwoo Jeon +John-David Dalton +Marek Lewandowski +Bruno Pérel +Daniel Nill +Reed Loden +Sean Henderson +Gary Ye +Richard Kraaijenhagen +Connor Atherton +Christian Grete +Tom von Clef +Liza Ramo +Joelle Fleurantin +Steve Mao +Jon Dufresne +Jae Sung Park +Josh Soref +Saptak Sengupta +Henry Wong +Jun Sun +Martijn W. van der Lee +Devin Wilson +Damian Senn +Zack Hall +Vitaliy Terziev +Todor Prikumov +Bernhard M. Wiedemann +Jha Naman +Alexander Lisianoi +William Robinet +Joe Trumbull +Alexander K +Ralin Chimev +Felipe Sateler +Christophe Tafani-Dereeper +Manoj Kumar +David Broder-Rodgers +Alex Louden +Alex Padilla +karan-96 +南漂一卒 +Erik Lax +Boom Lee +Andreas Solleder +Pierre Spring +Shashanka Nataraj +CDAGaming +Matan Kotler-Berkowitz <205matan@gmail.com> +Jordan Beland +Henry Zhu +Nilton Cesar +basil.belokon +Andrey Meshkov +tmybr11 +Luis Emilio Velasco Sanchez +Ed S +Bert Zhang +Sébastien Règne +wartmanm <3869625+wartmanm@users.noreply.github.com> +Siddharth Dungarwal +abnud1 +Andrei Fangli +Marja Hölttä +buddh4 +Hoang +Wonseop Kim +Pat O'Callaghan +JuanMa Ruiz +Ahmed.S.ElAfifi +Sean Robinson +Christian Oliff diff --git a/docs/site_libs/jquery-3.5.1/jquery.js b/docs/site_libs/jquery-3.5.1/jquery.js new file mode 100644 index 0000000..5093733 --- /dev/null +++ b/docs/site_libs/jquery-3.5.1/jquery.js @@ -0,0 +1,10872 @@ +/*! + * jQuery JavaScript Library v3.5.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2020-05-04T22:49Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.5.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.5 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2020-03-14 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem.namespaceURI, + docElem = ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px"; + tr.style.height = "1px"; + trChild.style.height = "9px"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( + dataPriv.get( cur, "events" ) || Object.create( null ) + )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script + if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+ + + + +
+ +
+
+

Biodiversity Modelling 2022

+
+ + + +
+ +
+
Author
+
+

Dominique Gravel, Vincent Beauregard

+
+
+ + + +
+ + +
+ +

Diapositives des présentations données lors de la modélisation de la biodiversité en 2022

+

Slides from presentations given in Biodiversity modelling in 2022.

+
+

Day 1

+ + +
+
+

Day 3

+ +
+
+

Day 4

+

https://bit.ly/dataviz_uds

+ + +
+ +
+ +
+ + + + \ No newline at end of file