diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..ae2ea45 --- /dev/null +++ b/404.html @@ -0,0 +1,3307 @@ + + + + + + + + + + + + + + + + + + + + + + + BIMS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/about/citations/index.html b/about/citations/index.html new file mode 100644 index 0000000..a3ef096 --- /dev/null +++ b/about/citations/index.html @@ -0,0 +1,1541 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+79. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

79. Citations

+

79.1 Citation guidelines

+

Data accessed through the FBIS are free for all—but not free of obligations. Under the terms of the FBIS data users agreement, users who download individual datasets or search results and use them in research or policy agree to cite them using the referencing information provided in the metadata for each data record.

+

Good citation practices ensure scientific transparency and reproducibility by guiding other researchers to the original sources of information. They also reward data-publishing institutions and individuals by reinforcing the value of sharing open data and demonstrating its impact to their stakeholders and funders.

+

Users are strongly encouraged to cite data retrieved from the FBIS network according to the recommended citation:

+

Freshwater Biodiversity Information System (FBIS). 2022. Downloaded from https://freshwaterbiodiversity.org on [current date]

+
+

Note: Users also need to cite the individual source references that they have used, which are available in the metadata table provided on the detailed dashboards.

+
+

To cite the scientific article published in the African Journal of Aquatic Science.

+

Dallas HF, Shelton JM, Sutton T, Tri Ciputra D, Kajee M and Job N. 2021. Development of a freshwater biodiversity information system for evaluating long-term change in rivers in South Africa. African Journal of Aquatic Science. doi.org/10.2989/16085914.2021.1982672

+

To cite the User Manual:

+

Freshwater Biodiversity Information System (FBIS). 2022. FBIS User Manual. Prepared by the Freshwater Research Centre and Kartoza.

+

Website:

+

freshwaterbiodiversity.org

+

Logos

+

79.2 Citation examples

+

Kajee Mohammed, Henry Dominic A. W., Dallas Helen F., Griffiths Charles L., Pegg Josephine, Van der Colff Dewidine, Impson Dean, Chakona Albert, Raimondo Domitilla C., Job Nancy M., Paxton Bruce R., Jordaan Martine S., Bills Roger, Roux Francois, Zengeya Tsungai A., Hoffman Andre, Rivers-Moore Nick, Shelton Jeremy M. (2023) How the Freshwater Biodiversity Information System (FBIS) is supporting national freshwater fish conservation decisions in South Africa, Frontiers in Environmental Science, Vol 11, DOI: DOI=10.3389/fenvs.2023.1122223

+

https://www.frontiersin.org/articles/10.3389/fenvs.2023.1122223

+
+

Helen Dallas, Jeremy Shelton, Tim Sutton, Dimas Tri Cuptura, Mohammed Kajee & Nancy Job (2022) The Freshwater Biodiversity Information System (FBIS) – mobilising data for evaluating long-term change in South African rivers, African Journal of Aquatic Science, 47:3, 291-306, DOI: 10.2989/16085914.2021.1982672

+

https://www.tandfonline.com/doi/abs/10.2989/16085914.2021.1982672

+
+

Kajee, Mohammed, Helen F. Dallas, Aneri Swanepoel, Charles L. Griffiths, and Jeremy M. Shelton. 2023. “The Freshwater Biodiversity Information System (FBIS) Fish Data: A Georeferenced Dataset of Freshwater Fishes Occurring in South Africa”. Journal of Limnology 82 (s1).

+

https://doi.org/10.4081/jlimnol.2023.2133.

+
+

The past and current distribution of native and non-native fish in the Kowie River catchment, Makhanda, Eastern Cape +Dumisani Khosa, Josie South, Ncumisa Y. Matam, Lubabalo Mofu, Ryan J. Wasserman and Olaf L.F. Weyl +Knowl. Manag. Aquat. Ecosyst., 424 (2023) 3

+

https://doi.org/10.1051/kmae/2022026

+
+

79.2.1 About the FBIS

+

Helen Dallas, Jeremy Shelton, Tim Sutton, Dimas Tri Ciptura, Mohammed Kajee & Nancy Job (2022) The Freshwater Biodiversity Information System (FBIS) – mobilising data for evaluating long-term change in South African rivers. African Journal of Aquatic Science, 47:3, 291-306, DOI: 10.2989/16085914.2021.1982672 +https://www.tandfonline.com/

+
+

79.2.2 Papers using FBIS data

+

Kajee Mohammed, Henry Dominic A. W., Dallas Helen F., Griffiths Charles L., Pegg Josephine, Van der Colff Dewidine, Impson Dean, Chakona Albert, Raimondo Domitilla C., Job Nancy M., Paxton Bruce R., Jordaan Martine S., Bills Roger, Roux Francois, Zengeya Tsungai A., Hoffman Andre, Rivers-Moore Nick, Shelton Jeremy M. (2023) How the Freshwater Biodiversity Information System (FBIS) is supporting national freshwater fish conservation decisions in South Africa. Frontiers in Environmental Science, Vol 11, DOI: DOI=10.3389/fenvs.2023.1122223 +https://www.frontiersin.org/

+
+

Kajee, Mohammed, Helen F. Dallas, Aneri Swanepoel, Charles L. Griffiths, and Jeremy M. Shelton. 2023. The Freshwater Biodiversity Information System (FBIS) Fish Data: A Georeferenced Dataset of Freshwater Fishes Occurring in South Africa. Journal of Limnology 82 (s1). +https://doi.org/10.4081/

+
+

Dumisani Khosa, Josie South, Ncumisa Y. Matam, Lubabalo Mofu, Ryan J. Wasserman and Olaf L.F. Weyl. The past and current distribution of native and non-native fish in the Kowie River catchment, Makhanda, Eastern Cape.  Knowl. Manag. Aquat. Ecosyst., 424 (2023) 3 +https://doi.org/10.1051/kmae/

+
+

Céline C. Hanzen, Martyn C. Lucas, Olaf L.F. Weyl, Sean M. Marr, Gordon O’Brien, Colleen T. Downs (2022). Slippery customers for conservation: Distribution and decline of anguillid eels in South Africa. Volume32, Issue 8, Pages 1277-1290. https://doi.org/10.1002/aqc.

+
+

Mahomed Desai, Celine Hanzen, Colleen T. Downs, Gordon C. O’Brien (2021) Environmental drivers of ichthyofauna community composition of the river ecosystems draining the Lake St. Lucia basin, South Africa. Hydrobiologia 848:3539–3554 +https://doi.org/10.1007/

+
+

79.2.3 Environmental Impact Assessments using FBIS data

+

Toni Belcher (2022) Aquatic Biodiversity Impact Assessment: Farm 1441, Jonkershoek, Stellenbosch in the Western Cape.

+
+

79.3 Publications citing FBIS and FBIS data

+
+

79.3.1 Peer-review articles

+

Dallas HF, Shelton JM, Sutton T, Tri Ciputra D, Kajee M and Job N. 2022. The Freshwater Biodiversity Information System (FBIS) – mobilising data for evaluating long-term change in South African rivers, African Journal of Aquatic Science 47(3): 291-306, DOI: 10.2989/16085914.2021.1982672

+
+

Desai M, Hanzen C, Downs CT, O’Brien GC. 2021. Environmental drivers of ichthyofauna community composition of the river ecosystems draining the Lake St. Lucia basin, South Africa. Hydrobiologia 848:3539–3554 +https://doi.org/10.1007/s10750-021-04609-7

+
+

Khosa D, South J, Matam NY, Mofu L, Wasserman RJ and Weyl OLF. 2023. The past and current distribution of native and non-native fish in the Kowie River catchment, Makhanda, Eastern Cape. Knowl. Manag. Aquat. Ecosyst., 424. DOI: https://doi.org/10.1051/kmae/2022026

+
+

Hanzen CC, Lucas MC, Weyl OLF, Marr SM, O’Brien G and Downs CT. 2022. Slippery customers for conservation: Distribution and decline of anguillid eels in South Africa. Aquatic Conservation: Marine and Freshwater Ecosystems, 32: 1277– 1290. https://doi.org/10.1002/aqc.3823

+
+

Kajee M, Henry DAW, Dallas HF, Griffiths CL, Pegg J, Ven der Coll D, Impson D, Chakona A, Raimondo DC, Job NM, Paxton BR, Jordaan MS, Bills R, Roux F, Zengeya TA, Hoffman A, Rivers-Moore N, Shelton JM. 2023. How the Freshwater Biodiversity Information System (FBIS) is supporting national freshwater fish conservation decisions in South Africa. Frontiers in Environmental Science. Vol 11, +https://www.frontiersin.org/articles/10.3389/fenvs.2023.1122223

+
+

Kajee M, Dallas HF, Swanepoel A, Griffiths CL, and Shelton JM. 2023. The Freshwater Biodiversity Information System (FBIS) Fish Data: A Georeferenced Dataset of Freshwater Fishes Occurring in South Africa. Journal of Limnology 82 (s1). https://doi.org/10.4081/jlimnol.2023.2133

+
+

King J and Palmer C. 2022. Perspectives on Protecting African freshwater Ecosystems in the Anthropocene. African Journal of Aquatic Science. 47(3): iii-vi.

+
+

79.3.2 Government products

+

The Department of Forestry Fisheries and Environment (DFFE) National Environmental Screening Tool Aquatic Biodiversity Sensitivity Layers. 2023.

+
+

Shelton J, Jordaan M, Dallas H, van der Colff D, Kajee M, Impson D, Henry D, Khosa D, Raimondo D, Job N, Chakona A. 2023. The Department of Forestry Fisheries and Environment (DFFE) Environmental Assessment Protocols: Freshwater fish fauna.

+
+

79.3.3 Science and policy briefs

+

GEO BON and FWBON, 2022. Inland Waters in the Post-2020 Global Biodiversity Framework. Available from https://geobon.org/science-briefs/.

+
+

79.3.4 Reports, books and book chapters

+

Day JA and BR Davies. 2022. Vanishing Waters (3rd ed.) Water research Commission Special Report SR 160/22, Water Research Commission, Pretoria, South Africa.

+
+

Fry C. 2021. A field guide to freshwater macroinvertebrates of southern Africa. Jacana Press. South Africa.

+
+

Machingura J, Coetzee J, Dallas H, Day B, Day J, Hay D, Skelton P, Thirion C and Uys M. 2021. The evolution of ecosystem research – from biodiversity to biossessments. Chapter 7 In: WRC@50: Celebrating a half century of excellence (Eds. Day JA, Day B and Reizenberg J). Water Research Commission Report no. SP 148/21, Water Research Commission, Pretoria, South Africa.

+
+

Turak E, Van Deventer H, Pienaar M, Walters M, Dallas H, etc. In prep. Collection and management of biological records must support protection and restoration goals for freshwater species and ecosystems.

+
+

79.3.5 Technical and consultancy reports

+
+

Note: Numerous consultants use the data from FBIS is their reports. Not all correctly cite the FBIS yet.

+
+

CapeNature 2022. Field Report 4/2022. Jonkershoek Nature Reserve Eerste River winter monitoring report. Unpublished internal report. Field report. CapeNature 2022. Field Report 10/2022. Jonkershoek Nature Reserve Eerste River autumn monitoring report. Unpublished internal report. Field report.

+
+

Toni Belcher (2022) Aquatic Biodiversity Impact Assessment: Farm 1441, Jonkershoek, Stellenbosch in the Western Cape.

+
+

CapeNature, 30/03/2022, Field Report: River survey of the Outeniqua Nature Reserve Complex, Unpublished internal report, Biodiversity Capabilities: Technical Report.

+
+

CapeNature 2023. Field Report 2/2023. Kogelberg Nature Reserve annual SASS monitoring report. Unpublished internal report. Field report.

+
+

City of Cape Town. In prep. Hout Bay River – State of the Rivers report. Scientific Services. City of Cape Town.

+
+

Erasmus P. 2022. Basic Assessment Report For The Proposed Prospecting Activities On Various Farms, In The Magisterial District Of Blouberg And Mogalakwena, Limpopo Province For Sylvania Northern Mining (Pty) Ltd For the following Minerals: Chrome Ore, Cobalt, Copper Ore, Gold Ore, Nickel Ore, Platinum Group Metals Located on the Farms: Altona 696 LR, Gillemberg 861 LR, Non Plus Ultra 683 LR, Teneriffe 682 LR, Aurora 397 LR and Nonnenwerth 421 LR, in the Magisterial Districts of there Blouberg and Mogalakwena, Limpopo Province DMRE Reference Number: LP30/5/1/1/2/14710PR. Prescali Environmental Consultants (Pty) Ltd. Pretoria

+
+

Erasmus P. 2022. Basic Assessment Report For The Proposed Prospecting Activities On Various Farms, In The Magisterial District Of Blouberg And Mogalakwena, Limpopo Province For Sylvania Northern Mining (Pty) Ltd For the following Minerals: Chrome Ore, Cobalt, Copper Ore, Gold Ore, Nickel Ore, Platinum Group Metals Located on the Farm: Portion 2 of the Farm Schaffhausen 689 LR, in the Magisterial District of Blouberg, Limpopo Province DMRE Reference Number: LP30/5/1/1/2/14728PR. Prescali Environmental Consultants (Pty) Ltd. Pretoria

+
+

Erasmus P. 2023. Desktop Surface Water Assessment Report for Kegakilwe Trading (Pty) Ltd - situated on Portion 0 of the Farm Mooikloof 150 and Portion 5 of the Farm Oatlands 151 within the Waterberg District in the Limpopo Province. Prescali Environmental Consultants (Pty) Ltd. Pretoria.

+
+

Erasmus P. 2022. Desktop Surface Water Assessment Report for Maditse Investments - situated on the Farms Tabana 133 LR, Boekenhoutfontein 108 LR and Prairie 107 LR within the Waterberg District in the Limpopo Province. Prescali Environmental Consultants (Pty) Ltd. Pretoria.

+
+

Erasmus P. 2022. Surface Water Assessment Report for Mofenyi Mining - Modjadji situated on Modjadji No. 1 934-LT within the Mopanie District in the Limpopo Province. Prescali Environmental Consultants (Pty) Ltd. Pretoria.

+
+

Erasmus P. 2022. Desktop Surface Water Assessment Report for Regison Mining (Pty) Ltd - situated on the Farms Greater Giyani 891 LT and Mariyeta 246 LT within the Mopani District in the Limpopo Province. Prescali Environmental Consultants (Pty) Ltd. Pretoria.

+
+

Fry, C. 2022. A field guide to freshwater macroinvertebrates in southern Africa. Jacana Media. South Africa.

+
+

Quale L. 2020. State of Strategic Water Source Areas Monitoring and Reporting Framework, and Information Platform – Southern Drakensberg Pilot. Institute for Natural Resources, South Africa.

+
+

Rivers-Moore NA and Kajee M. 2020. Pilot study on the use of the Freshwater Biodiversity Information System (FBIS) as a tool to extract data for climate change impacts on aquatic species distribution models. Freshwater Research Centre, Cape Town, South Africa.

+
+

79.3.6 Theses

+

Kajee. M. In prep. Trajectories of change is South Africa’s freshwater fish fauna. PhD Thesis. University of Cape Town.

+
+

79.3.7 Conference presentations and talks

+

Dallas HF and Rivers-Moore NA. 2019. Environmental water temperature guidelines for perennial rivers: A protocol and tools for setting water temperature targets in South Africa. Southern African Society for Southern Africa Conference, Limpopo July 2019.

+
+

Dallas HF and Shelton JM. 2017. Building freshwater information systems to last: A freshwater biodiversity information system for evaluating long‐term change in rivers in the Cape Floristic Region, South Africa. JRS Biodiversity Symposium, Johannesburg, South Africa.

+
+

Dallas HF, Shelton J, Olsen T, Sutton T and Ciputra D. 2019. Developing a freshwater biodiversity information system for evaluating long-term change in South African rivers. Southern African Society for Southern Africa Conference, Limpopo July 2019.

+
+

Dallas HF, Shelton J, Sutton T, Tri Cuptura D, Kajee M, Job N. 2021. The Freshwater Biodiversity Information System (FBIS) – a user-driven information system for mobilising, visualising and reporting biodiversity data in South Africa. Southern African Society for Southern Africa Conference, Virtual conference November 2021.

+
+

Dallas HF, Shelton J, Sutton T, Tri Cuptura D, Kajee M, Job N. 2021. Biodiversity data at your fingertips: the Freshwater Biodiversity Information System (FBIS). National Wetlands Indaba, Virtual conference October 2021.

+
+

Dallas HF. 2019. User driven information system design – more carrot less stick. JRS Biodiversity Symposium, Nairobi, Kenya.

+
+

Dallas HF. 2022. Biodiversity data at your fingertips: the Freshwater Biodiversity Information System (FBIS). Keynote Address at the Biodiversity Information Conference. November 2022.

+
+

Kajee M, Dallas HF, Shelton JM and Griffiths CL. 2019. Consolidating data on the status, distribution and abundance of South African freshwater fishes, invertebrates and algae for incorporating into a Freshwater Biodiversity Information System (FBIS) and assessing long-term change. South African National Biodiversity Institute Biodiversity Planning Forum, 4–7 June, Northern Drakensburg.

+
+

Kajee M, Dallas HF, Shelton JM and Griffiths CL. 2019. The status of South African freshwater fishes: A prelude to predicting the impacts of climate change on selected South African freshwater fish. Department of Biological Sciences Careers and Research Day, 21 November, Cape Town.

+
+

Kajee M, Dallas HF, Shelton JM and Griffiths CL. 2019. The status of South African freshwater fishes: A prelude to predicting the impacts of climate change on selected South African freshwater fish. +12th SAEON Graduate Student Network Indibano, 1–6 September, Cape St Francis (Best student presentation).

+
+

Kajee M, Dallas HF, Shelton JM and Griffiths CL. 2019. The status, distribution and abundance of South African freshwater fishes: A prelude to predicting the impacts of climate change on selected South African freshwater fish. 39th Zoological Society of Southern Africa (ZSSA) Congress, 7–10 July, Skukuza, Kruger National Park.

+
+

Kajee M, Dallas HF, Shelton JM and Griffiths CL. 2020. The status of South African freshwater fishes: A prelude to predicting the impacts of climate change on selected South African freshwater fish. W12 Congress: 1st International Meeting of Cities Tackling Water Challenges, 27-28 November, Cape Town.

+
+

Kajee M, Dallas HF, Shelton JM and Griffiths CL. 2021. South African fish data in FBIS: A success story. Southern African Society of Aquatic Scientists Congress, 1-3 November, Virtual Event. +Kajee M, Dallas HF, Shelton JM and Griffiths CL. 2021. South African fish data in FBIS: A success story. National Wetlands Indaba 2021, 20-21 October, Virtual Event (Best student presentation).

+
+

Kajee, M., Dallas, H.F., Shelton JM and Griffiths CL. 2022. South African National Biodiversity Institute 4th Annual Student Research Day, 29-30 March, Cape Town.

+
+

Shelton J and Dallas HF. 2021. Mobilising freshwater biodiversity data for South African rivers – successes, challenges, data providers, future expansion Southern African Society for Southern Africa Conference, Virtual conference November 2021.

+
+

Shelton J and Dallas HF. 2022. How the Freshwater Biodiversity Information System (FBIS) is supporting freshwater fish conservation in South Africa. Biodiversity Information Conference. November 2022.

+
+

Shelton J, Dallas HF, Kajee M. The Freshwater Biodiversity Information System (FBIS): +Unlocking data for improved freshwater decision-making in South Africa. Berg River Improvement Programme. Jonkershoek. June 2023.

+
+

Shelton J and Dallas HF. 2023. The Freshwater Biodiversity Information System (FBIS): +Unlocking data for improved freshwater decision-making in South Africa. City of Cape Town, Athlone Sewage works. August 2023.

+
+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/about/code-of-conduct/index.html b/about/code-of-conduct/index.html new file mode 100644 index 0000000..125f7d5 --- /dev/null +++ b/about/code-of-conduct/index.html @@ -0,0 +1,1320 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+1. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

1. Contributor covenant code of conduct

+

1.1 Our pledge

+

In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +education, socio-economic status, nationality, personal appearance, race, +religion, or sexual identity and orientation.

+

1.2 Our standards

+

Examples of behaviour that contributes to creating a positive environment +include:

+
    +
  • Using welcoming and inclusive language
  • +
  • Being respectful of differing viewpoints and experiences
  • +
  • Gracefully accepting constructive criticism
  • +
  • Focusing on what is best for the community
  • +
  • Showing empathy towards other community members
  • +
+

Examples of unacceptable behaviour by participants include:

+
    +
  • The use of sexualized language or imagery and unwelcome sexual attention or + advances
  • +
  • Trolling, insulting/derogatory comments, and personal or political attacks
  • +
  • Public or private harassment
  • +
  • Publishing others' private information, such as a physical or electronic + address, without explicit permission
  • +
  • Other conduct which could reasonably be considered inappropriate in a + professional setting
  • +
+

1.3 Our responsibilities

+

Project maintainers are responsible for clarifying the standards of acceptable +behaviour and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behaviour.

+

Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful.

+

1.4 Scope

+

This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers.

+

1.5 Enforcement

+

Instances of abusive, harassing, or otherwise unacceptable behaviour may be +reported by contacting the project team. All complaints will be reviewed and +investigated and will result in a response that is deemed necessary and +appropriate to the circumstances. The project team is obligated to maintain +confidentiality with regard to the reporter of an incident. Further details of +specific enforcement policies may be posted separately.

+

Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership.

+

1.6 Attribution

+

This Code of Conduct is adapted from the Contributor Covenant, version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/about/contributing/index.html b/about/contributing/index.html new file mode 100644 index 0000000..33f0321 --- /dev/null +++ b/about/contributing/index.html @@ -0,0 +1,1444 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+78. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

78. Contributing

+

78.1 🔧 Pull Request Steps

+

This project is open source, so you can create a pull request(PR) after you fix issues. Get a local copy of the plugins checked out for development using the following process.

+

78.1.1 Pull Request

+

Before uploading your PR, run test one last time to check if there are any errors. If it has no errors, commit and then push it!

+

For more information on PR's steps, please see links in the Contributing section.

+

78.1.2 Commit messages

+

Please make this project more fun and easy to scan by using emoji prefixes for your +commit messages (see GitMoji).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Commit typeEmoji
Initial commit🎉 :tada:
Version tag🔖 :bookmark:
New feature:sparkles:
Bugfix🐛 :bug:
Metadata📇 :card_index:
Documentation📚 :books:
Documenting source code💡 :bulb:
Performance🐎 :racehorse:
Cosmetic💄 :lipstick:
Tests🚨 :rotating_light:
Adding a test:white_check_mark:
Make a test pass✔️ :heavy_check_mark:
General update⚡️ :zap:
Improve format/structure🎨 :art:
Refactor code🔨 :hammer:
Removing code/files🔥 :fire:
Continuous Integration💚 :green_heart:
Security🔒 :lock:
Upgrading dependencies⬆️ :arrow_up:
Downgrading dependencies⬇️ :arrow_down:
Lint👕 :shirt:
Translation👽 :alien:
Text📝 :pencil:
Critical hotfix🚑 :ambulance:
Deploying stuff🚀 :rocket:
Fixing on MacOS🍎 :apple:
Fixing on Linux🐧 :penguin:
Fixing on Windows🏁 :checkered_flag:
Work in progress🚧 :construction:
Adding CI build system👷 :construction_worker:
Analytics or tracking code📈 :chart_with_upwards_trend:
Removing a dependency:heavy_minus_sign:
Adding a dependency:heavy_plus_sign:
Docker🐳 :whale:
Configuration files🔧 :wrench:
Package.json in JS📦 :package:
Merging branches🔀 :twisted_rightwards_arrows:
Bad code / need improv.💩 :hankey:
Reverting changes:rewind:
Breaking changes💥 :boom:
Code review changes👌 :ok_hand:
Accessibility♿️ :wheelchair:
Move/rename repository🚚 :truck:
OtherBe creative
+

78.2 💬 Contributing

+
+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/about/licence/index.html b/about/licence/index.html new file mode 100644 index 0000000..4f7debd --- /dev/null +++ b/about/licence/index.html @@ -0,0 +1,1276 @@ + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

2. License

+

Creative Commons Legal Code

+

CC0 1.0 Universal

+
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+HEREUNDER.
+
+

Statement of Purpose

+

The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work").

+

Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others.

+

For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights.

+
    +
  1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following:
  2. +
+

i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof.

+
    +
  1. +

    Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose.

    +
  2. +
  3. +

    Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose.

    +
  4. +
  5. +

    Limitations and Disclaimers.

    +
  6. +
+

a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work.

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/about/running-instances/fbis/index.html b/about/running-instances/fbis/index.html new file mode 100644 index 0000000..3d71c7f --- /dev/null +++ b/about/running-instances/fbis/index.html @@ -0,0 +1,1170 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+4. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

4. FBIS

+

FBIS

+

Web Site: https://freshwaterbiodiversity.org/

+

The Freshwater Biodiversity Information System (FBIS), South Africa.

+

FBIS

+

The FBIS serves as a community platform for inventory and maintenance of freshwater biodiversity data with an end goal to assist the evaluation of long-term change in river biodiversity and ecosystem condition in South Africa.

+

This project is funded by the JRS Biodiversity Foundation and SANBI, and implemented by the FRC and Kartoza.

+

By signing up and creating an account you will be able to (1) explore the map, (2) query the data in the system, (3) download maps, data, graphs and reports and (4) create a site and upload data. If you do not sign up, you will still have access to all the above functions except the ability to upload data.

+

The FBIS v3 release includes access to FBIS, a FBIS v3 user manual (accessed via the 'Help' tab on the top bar of the site) and a short ‘how to’ video series available here.

+

These aids should help you to navigate your way around the system and test out the main functions, features and work flows, as well as flag any issues you pick up on while testing.

+

Any questions can be directed to fbis@frcsa.org.za.

+

We look forward to receiving your feedback!

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/about/running-instances/img/FBIS-1.png b/about/running-instances/img/FBIS-1.png new file mode 100644 index 0000000..e6945d3 Binary files /dev/null and b/about/running-instances/img/FBIS-1.png differ diff --git a/about/running-instances/img/FBIS-2.png b/about/running-instances/img/FBIS-2.png new file mode 100644 index 0000000..1106d16 Binary files /dev/null and b/about/running-instances/img/FBIS-2.png differ diff --git a/about/running-instances/img/ORBIS-1.png b/about/running-instances/img/ORBIS-1.png new file mode 100644 index 0000000..49beea7 Binary files /dev/null and b/about/running-instances/img/ORBIS-1.png differ diff --git a/about/running-instances/img/ORBIS-2.png b/about/running-instances/img/ORBIS-2.png new file mode 100644 index 0000000..6fb41a6 Binary files /dev/null and b/about/running-instances/img/ORBIS-2.png differ diff --git a/about/running-instances/img/RBIS-1.png b/about/running-instances/img/RBIS-1.png new file mode 100644 index 0000000..1dc36c7 Binary files /dev/null and b/about/running-instances/img/RBIS-1.png differ diff --git a/about/running-instances/img/RBIS-2.png b/about/running-instances/img/RBIS-2.png new file mode 100644 index 0000000..1cd1fa7 Binary files /dev/null and b/about/running-instances/img/RBIS-2.png differ diff --git a/about/running-instances/img/naming-convention.README b/about/running-instances/img/naming-convention.README new file mode 100644 index 0000000..74a045a --- /dev/null +++ b/about/running-instances/img/naming-convention.README @@ -0,0 +1,7 @@ +# Image naming convention + +Images should be named according to reference doc, sub-section and order in the document. +e.g. + +- The 1st image in instructions regarding zooming will be something like zooming-1, the 2nd image will be zooming-2, etc. +- The 1st image in quickstart regarding logging in will be login-1, etc diff --git a/about/running-instances/index.html b/about/running-instances/index.html new file mode 100644 index 0000000..cfd53e1 --- /dev/null +++ b/about/running-instances/index.html @@ -0,0 +1,1164 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+3. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

3. Running instances of BIMS

+

Examples of running instances of the Biodiversity Information Management System (BIMS) are:

+
    +
  • FBIS: The Freshwater Biodiversity Information System, South Africa.
  • +
  • RBIS: The Rwanda Biodiversity Information System, Rwanda.
  • +
  • ORBIS: The Okavango Repository for BiodiverSity Data, Botswana
  • +
+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/about/running-instances/orbis/index.html b/about/running-instances/orbis/index.html new file mode 100644 index 0000000..1871c25 --- /dev/null +++ b/about/running-instances/orbis/index.html @@ -0,0 +1,1166 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+6. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

6. ORBIS

+

ORBIS

+

Web Site: https://orbis.kartoza.com

+

The Okavango Repository for BiodiverSity Data (ORBIS), Botswana

+

ORBIS

+

The Okavango Repository for BIodiverSity Data (ORBIS) is conceptualised to bridge the gap between biodiversity data collectors and users in Botswana, with an emphasis on policymakers responsible for conservation management decisions.

+

Through continued engagement with stakeholders via the ORBIS reference group and capacity-building activities, ORBIS will improve the pathways from biodiversity data to policies, ensuring that stakeholders are empowered to make evidence-based decisions relating to biodiversity management.

+

For more information, contact us at: ebennitt@ub.ac.bw

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/about/running-instances/rbis/index.html b/about/running-instances/rbis/index.html new file mode 100644 index 0000000..66b9c38 --- /dev/null +++ b/about/running-instances/rbis/index.html @@ -0,0 +1,1170 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+5. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

5. RBIS

+

RBIS

+

Web Site: https://rbis.ur.ac.rw/

+

We are CoEB - the Center of Excellence in Biodiversity and Natural Resource Management, Rwanda

+

RBIS

+

CoEB is a Rwandan Government institution that functions as a consortium of governmental and non-governmental organizations, bringing together expertise and skills to produce information needed for effective policy and science-driven economic transformation. The Center is hosted at University of Rwanda and works in three areas: research and monitoring, bioprospecting, and conservation education and awareness raising.

+

The Center plays a catalytic and coordinating role to ensure sharing of scientific knowledge and expertise for evidence-based decisions in conservation, natural resource management and climate resiliency. We provide leadership, best practices, research, support and training in the domain of biodiversity, natural resource management, and impacts of climate change on ecosystems and livelihoods. The goal is to encourage, enable and support stakeholders to generate and apply knowledge on biodiversity and natural resources for sustainable development. We address the need for data for national reporting requirements (CBD, NDC, etc.) and to inform existing indicators of global biodiversity trends, such as the Living Planet Index from WWF, the Red List Index, GEO BON Species Protection Index, and the need for data in land use planning decisions, restoration projects, and ecosystem health and services provisioning.

+

A biodiversity information system takes biodiversity observation records that are stored in a variety of sources and formats and puts them into a standardized format on a viewing platform to enable stakeholders to access and use the information. Biodiversity data for Rwanda have been scattered and difficult to access, but are critical to understanding patterns of biodiversity distribution, ecosystem functioning, and early detection of environmental change. Species records can provide indication of climate change impacts, pollution effects, and guide development, land use planning, tourism opportunities, and monitoring of restoration efforts. An information system puts data at your fingertips for national reporting requirement needs like the CBD and NDC. The system effectively links research to conservation and policy.

+

With funding from the JRS Biodiversity Foundation https://jrsbiodiversity.org/ we are developing the first national biodiversity information system for Rwanda. We call it the Rwanda Biodiversity Information System or RBIS. Thanks to generous collaboration from data holders who graciously shared their data sets, including independent researchers, NGOs and government institutions, we have already mobilized more than 30,000 biodiversity data records.

+

We begin the RBIS with a focus on biodiversity data in freshwater ecosystems. We have mobilized data on odonates, anurans, and birds, thanks to the generous data sharing by data holders. Our aim is to demonstrate the power of the RBIS to inform wetlands and catchment management using biodiversity data to indicate ecosystem health. We will eventually scale the RBIS up to include all ecosystems in Rwanda.

+

When you enter the Explore button, you will see the base map of Rwanda and you can begin to explore and query the system for information. We hope you find this resource valuable and we welcome your feedback.

+

For more information, contact us at: coeb1@ur.ac.rw

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/biodiversity-data/data-management/index.html b/administrator/biodiversity-data/data-management/index.html new file mode 100644 index 0000000..70fadce --- /dev/null +++ b/administrator/biodiversity-data/data-management/index.html @@ -0,0 +1,2008 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+32. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

32. FBIS data management guidelines

+

Data management guide for the Freshwater Biodiversity Information System (FBIS): a platform for housing and serving freshwater biodiversity data.

+

32.1 Introduction

+

These documents serves as a guideline for the management of freshwater biodiversity data in the Freshwater Biodiversity Information System (FBIS). It provides an overview of the recommended steps, processes and systems for sourcing, extracting, consolidating, uploading and serving biodiversity data in an information system such as FBIS. It is based on the experiences gained and systems developed during the development of the Freshwater Biodiversity Information System (FBIS) in South Africa (Freshwater Biodiversity Information System. 2020. FBIS Version 3; Dallas et al. 2022).

+

32.2 Managing data consolidation

+

Establishing what data are available in a country is the first step in the data process. To assist with the managing of data we recommend developing a DataSet Tracker.

+

32.2.1 Setting up a DataSet Tracker

+

Often the amount of data available for consolidation into an information system, exceeds the amount of data that can actually be consolidated based on time and financial constraints. It is thus critical that the FBIS data team prioritise the data for FBIS. This is best done through consultation with the end-users and stakeholders of FBIS. To manage the prioritisation of data and keep track of progress, a DataSet Tracker is used. This is an excel spreadsheet that keeps track of the data available for inclusion in FBIS, and importantly allows for prioritisation of each data set into FBIS.

+

The DataSet Tracker provides a list and details of data sets identified by the FBIS team and stakeholders, which are being considered for inclusion in the FBIS. Data are best divided into four broad categories, namely:

+
    +
  • Biodiversity data (e.g. wetland birds, wetland plants, fish, invertebrates, algae etc.)
  • +
  • Abiotic data (e.g. hydrological data, physico-chemical data, wetland condition data, etc.)
  • +
  • Spatial data (used for filters and / or spatial layers; e.g. Rivers and dams, Provinces, Freshwater Ecoregions of the World, Water Management Areas, etc.)
  • +
  • Third Party data (existing hydrological or water quality data sites, GBIF, etc.)
  • +
+

For each category, the FBIS team needs to specify the following:

+
    +
  • Component (specify component)
  • +
  • Details (provide details of data set, e.g. number of records, type of records etc)
  • +
  • Accessibility (who has the data, is it freely available, is a MOU required?)
  • +
  • Data priority ranking (ranking based on user workshop to evaluate the relative importance of different data sets, where 1 = high priority, 2 = medium and 3 = low; these rankings can also be linked to FBIS versions)
  • +
  • Spatial scale (specify if the data are regional or national)
  • +
  • Progress (record progress on obtaining data and inclusion in FBIS)
  • +
+

A DataSet Tracker template has been generated for FBIS (FBIS DataSet Tracker Template.xlsx). For spatial data it is important to indicate if this layer is to be used as a filter, spatial layer, or both (see details in 32.3.3 Spatial Data).

+

32.2.2 Using GitHub for managing data consolidation

+

Data sourcing, extraction and consolidation requires careful, accurate and concise work to ensure quality data. A robust system for managing the data consolidation process is recommended. Github is an excellent tool for managing this process as it allows multiple team members to work together in one project, which allows for easy management of workflows for data consolidation. A screenshot of the FBIS Data Management project on GitHub is provided (Figure 1). Using GitHub one can:

+
    +
  • Create a “ticket”/ “issue” for each data set to be consolidated
  • +
  • Assign each “ticket” to a team member
  • +
  • Label each issue with an appropriate label such as bird data, fish data, algal data, etc.
  • +
  • Easily see when a ticket is “In progress”, “Done” and “Checked and Signed off” by a senior staffer.
  • +
+

The FBIS will be introduced to GitHub for managing both the technical and data side of the FBIS project.

+

Figure 1. Example of data management workflow in GitHub

+

Data Management 1

+

32.3 Types of data

+

32.3.1 Biodiversity data

+

Biodiversity data is the primary currency of FBIS. The lowest unit is an occurrence record for a Taxon taken at a Site (identified by a latitude / longitude) on a particular Sampling Date (so Taxon, location and date – these are mandatory attributes for each record). For some taxa extra attributes may be included such as habitat or biotope. Additional data may be associated with each occurrence record, although this is often dependent on the group (birds, fish, invertebrates, wetland plants, algae) being focused on, and may vary somewhat from one group to another. For each occurrence record, Presence = 1 indicates that the species was recorded at a site on a particular sampling date. In addition, we have included the option to include sampling method, sampling effort, abundance measure, and abundance for each; as well as a number of abiotic parameters associated with each occurrence record (see 32.3.2 Abiotic data). Further details are provided in 32.4.2 Data Upload Templates.

+

32.3.1.1 Creating Taxonomic Master Lists

+

A taxonomic Master List is a list of all species and/or taxa within a particular group such as birds, fish, invertebrates, wetland plants, algae, etc. For some groups a species list is easy to produce as species level is commonly identified in studies (e.g. birds, fish). For other groups, the taxonomic level (family, genus, species etc) varies considerably from study to study, and thus it is recommended that the lowest taxonomic level is used and that Taxon is used in preference to Species (e.g. invertebrates, algae).

+

The purpose of the Master List is threefold:

+
    +
  1. To provide a comprehensive and up to date list of species/taxa for a specific group in a specific region. This needs to be done during the initial development of an information system such as FBIS, but once the system is up and running, then the further updating of the Taxonomic backbone is done using GBIF and user-defined taxonomic uploads.
  2. +
  3. To facilitate downloading of data from the Global Biodiversity Information Facility’s (GBIF), thereby ensuring that the correct taxa are included on the information system.
  4. +
  5. To provide the taxonomic hierarchy for taxa not yet on GBIF.
  6. +
+

The generation of a Master List requires consultation with available resources, relevant publications and experts. A Master List is intended to be an updatable resource, improved and added to as new data and studies are published, or new taxa are described. If no species lists are available for a country then the GBIF Taxonomic Master List may be generated by extracting data from GBIF. This Master List should then ideally be checked and validated for accuracy by the FBIS team.

+

The format of the Master List is important to ensure consistency for ingestion of data into the information system. The following columns are included in the Master Lists, provided as excel file template that will be used for each FBIS group (Master List Template final for FBIS Generic 2022_08_01.xlsx). It is recommended that all columns be populated, with black compulsory and blue optional (explanations given in parenthesis):

+
    +
  • On GBIF (Yes or No if the taxon is on GBIF)
  • +
  • GBIF Link (link to GBIF taxon)
  • +
  • Taxon Rank
  • +
  • Kingdom
  • +
  • Phylum
  • +
  • Class
  • +
  • SubClass
  • +
  • Order
  • +
  • Family
  • +
  • SubFamily
  • +
  • Genus
  • +
  • Species
  • +
  • SubSpecies
  • +
  • Variety
  • +
  • Taxon
  • +
  • Scientific name and authority
  • +
  • Taxonomic status
  • +
  • Origin (Native, Non-native, Unknown)
  • +
  • Endemism (Endemism categories):
  • +
  • Micro-endemic level 2 (Endemic to a single river or wetland)
  • +
  • Micro-endemic level 1 (Endemic to less than 5 rivers or wetlands)
  • +
  • Regional endemic level 2 (Endemic to a single primary catchment)
  • +
  • Regional endemic level 1 (Endemic to a single Freshwater Ecoregion, more than one primary catchment)
  • +
  • National endemic (Endemic to South Africa, occurs in more than one Freshwater Ecoregion within Botswana)
  • +
  • Subregional endemic (Endemic to southern Africa)
  • +
  • Widespread (Occurs beyond southern Africa)
  • +
  • Unknown (Endemism is unknown)
  • +
  • Global Conservation status The IUCN Red List of Threatened Species website (IUCN Red List, 2020) classifies species into eight main categories based on their extinction risk. Each species was classified:
  • +
  • Extinct
  • +
  • Critically Endangered
  • +
  • Endangered
  • +
  • Vulnerable
  • +
  • Near Threatened
  • +
  • Least Concern
  • +
  • Data Deficient
  • +
  • Not Evaluated
  • +
  • National Conservation status The SANBI National Red List Categories (SANBI, 2020) classifies species into 12 main categories based on their extinction risk. Each species was classified as:
  • +
  • Extinct
  • +
  • Extinct in the Wild
  • +
  • Regionally Extinct
  • +
  • Critically Endangered, Possibly Extinct
  • +
  • Critically Endangered
  • +
  • Endangered
  • +
  • Vulnerable
  • +
  • Near Threatened
  • +
  • Critically Rare
  • +
  • Rare
  • +
  • Declining
  • +
  • Data Deficient - Insufficient Information
  • +
  • Data Deficient - Taxonomically Problematic Not Evaluated
  • +
  • Least Concern
  • +
  • Common Name
  • +
  • Former scientific names
  • +
  • Division (algae only)
  • +
  • Growth form (algae only)
  • +
  • Water dependence (anurans only)
  • +
  • BDI Link (anurans only)
  • +
  • Wetland Indicator Status (plants only)
  • +
  • SANBI RedList Links
  • +
+

A separate Master List of Species / Taxa needs to be created for each group for which biodiversity data are served on FBIS. The Master List is ideally created before the consolidation of data so that the correct GBIF Taxonomic Backbone (https://www.gbif.org/dataset/d7dddbf4-2cf0-4f39-9b2a-bb099caae36c) is used for the data consolidation files. The taxonomy from GBIF should be used when the taxon is on GBIF. The FBIS team can check if the taxon is on GBIF using the following link: https://www.gbif.org/species/1 and insert the relevant species, genus, family etc. in the “Select a species” box.

+

Data Management 2

+

It is important that the correct Taxon Rank should always be used to ensure correct uploading of the data files into FBIS.

+

Note: It is recommended that significant time and resources are used to generate and refine the master list for each group (birds, fish, invertebrates etc) as much as possible before proceeding with data collation. This is the list around-which all of the occurrence data will pivot: the more accurate it is at the start, the more time you save in the long run when collating the biodiversity data for those taxa.

+

32.3.1.2 Sources of biodiversity data

+

Multiple sources of taxon occurrence data generally exist, although this is highly dependent on the country. Potential sources of biodiversity data include the following study reference categories:

+
    +
  • Peer-reviewed scientific articles
  • +
  • Theses
  • +
  • Published reports
  • +
  • Databases
  • +
  • Unpublished data
  • +
+

The following sections provide details of the recommended processes for sourcing taxon occurrence data from the different sources.

+
32.3.1.2.1 Peer-reviewed scientific article
+

Data from peer-reviewed scientific articles are best sourced by undertaking a literature search using Google Scholar. To ensure that relevant papers are identified, appropriate search term combination should be used. For example, for all native freshwater fishes in South Africa: “Genus species” & “South Africa” (where “Genus species” represents the scientific name for each taxon). Relevant articles are identified based on their titles, abstracts and methods section. The first 500 search results returned by Google Scholar should be assessed for relevancy. Each relevant article should be inspected for GPS coordinates – if these are not provided then the article may be catalogued but not included for data extraction (see 32.4 Extracting data and preparing bulk data for uploading into FBIS).

+

Note: It is important that search terms are clearly-defined and consistent, so that the process is repeatable and defensible.

+
32.3.1.2.2 Thesis
+

University theses are easily searched using relevant university search engines. Often local experts also know of relevant theses and can be contacted directly. Where possible, electronic data should be sourced directly from individuals, as this saves significant time that would otherwise be occupied in transcription of paper to digital records during data consolidation.

+
32.3.1.2.3 Published report
+

Technical and consultancy reports are often difficult to source and requires knowledge of local experts who have undertaken relevant studies. Where possible, electronic data should be sourced directly from individuals, as this saves significant time during data consolidation.

+
32.3.1.2.4 Database
+

Identify and contact relevant organisations who may have data to share that is already in a database. Data sharing agreements may be needed depending on the organisation.

+
32.3.1.2.5 Unpublished data
+

Identify individuals who may have data to share. Where possible, electronic data should be sourced directly from individuals, as this saves significant time during data consolidation.

+

32.3.1.3 Generation of a Knowledge Database for each group

+

A Knowledge Database is a record of all study references from which data have been extracted for a particular group (e.g. birds, fish, wetland plants, invertebrates, algae, etc.). It is a useful record of all peer-reviewed scientific articles, theses and published reports for a group and each record should ideally be linked to a GitHub ticket to keep track of the data extraction (see 32.2.2 Using GitHub for managing data consolidation). An example of a Knowledge Database has been generated (FBIS Knowledge Database Example Template.xlsx). The following columns are included in the Knowledge Database, provided as excel file template that will be used for each FBIS group.

+
    +
  • Data captured (Yes / No)
  • +
  • Data capturer (Name of person that entered the data)
  • +
  • Author(s) (Study author(s))
  • +
  • Year (Publication Year)
  • +
  • Title (Publication Title)
  • +
  • Source (Publication Source)
  • +
  • Reference Category (peer-reviewed scientific article, thesis, published report, database, unpublished data)
  • +
  • Electronic Copy (Yes / No)
  • +
  • Electronic Data (Yes / No)
  • +
  • Notes (Relevant notes)
  • +
  • GitHub Ticket Number (Link to ticket/issue on GitHub)
  • +
+

32.3.2 Abiotic data

+

Whilst abiotic data are not the main currency for FBIS, it is extremely useful to provide associated abiotic data when these have been collected concurrently with biotic data. For this reason, a number of abiotic spatial layers may be served, and a number of abiotic parameters may be included in the Data Upload Templates. These include aspects related to sampling method and effort, abundance, habitat/biotope, flow and physico-chemistry. Abiotic data associated with biodiversity data are included in the 32.4.2 Data Upload Templates. Examples are given below. These abiotic factors may need to be adapted depending on the taxonomic group being dealt with – for example bird abiotic data may need different habitat related attributes. These can easily be added in the administration section.

+
    +
  • Sampling method
  • +
  • Sampling effort measure
  • +
  • Sampling effort value
  • +
  • Abundance measure
  • +
  • Abundance value
  • +
  • Broad biotope
  • +
  • Specific biotope
  • +
  • Substratum
  • +
  • Water Level
  • +
  • Water Turbidity
  • +
  • Embeddedness
  • +
  • Depth
  • +
  • Near Bed Velocity
  • +
  • Conductivity
  • +
  • PH
  • +
  • Dissolved Oxygen
  • +
  • Dissolved Oxygen
  • +
  • Temperature
  • +
  • Turbidity
  • +
+

32.3.3 Spatial data

+

Spatial data often take the form of shapefiles containing geometries representing physical properties or landscape features (e.g. catchments, habitat types etc.) and that have attribute data associated with them. These spatial layers may be hidden/shown for visualisation on the map by a user, while the data in these layers may be used to facilitate spatial filters which are used to select a subset of records based on the filter specified. Spatial layers and filters may be the same, although not always as it is dependent on the data attributes.

+

32.3.3.1 Selection of spatial filters and geocontext data

+

Geocontext data are contextual data for any geographical point, sourced from relevant spatial layers and aggregated as properties of a site. Often spatial layers are used for generating geocontext data. The examples below are the spatial filters used in FBIS (see 32.2.1 Setting up a Dataset Tracker).

+
    +
  • Geomorphological Zone
  • +
  • Freshwater Ecoregions of the World
  • +
  • Province
  • +
  • Management Area
  • +
  • Catchment
  • +
  • Ecoregion
  • +
  • National Critical Biodiversity Areas
  • +
  • National Freshwater Ecosystem Priority Area
  • +
  • Strategic Water Source Area
  • +
  • National Biodiversity Assessment 2018
  • +
+

32.3.3.2 Selection of spatial layers

+

Spatial layers, which may be turned on and off in the FBIS map, function as background layers upon which biodiversity data are displayed. The examples below are the spatial layers used in FBIS.

+
    +
  • Administrative boundaries
  • +
  • Rivers
  • +
  • Dams
  • +
  • Geomorphological zones
  • +
  • Freshwater Ecoregions of the World
  • +
  • Water Management Areas
  • +
  • Sub Water Management Areas
  • +
  • River Management Units
  • +
  • Catchments (Primary, Secondary, Tertiary, Quaternary, Quinary)
  • +
  • SA Ecoregions (Ecoregion Level 1, Ecoregion Level 2)
  • +
  • National Critical Biodiversity areas
  • +
  • Protected areas
  • +
  • National Freshwater Ecosystem Priority Areas
  • +
  • Strategic Water Source Areas
  • +
  • Land Use Classes
  • +
+

32.3.4 Third party data

+

Where databases and data platforms already exist, it is recommended that links (APIs) be created to access these data from the platform. Third party databases that FBIS links to includes data from Global Biodiversity Information Facility (GBIF) (taxonomy, diatom, invertebrate and fish data), the IUCN Red List of Threatened Species database, the MiniSASS database, which provides citizen science river health data, and DWS water quality database accessed via the Integrated Water Resources Decision Support System (InWaRDS 2020), and a ‘knowledge database’, which serves as a catalogue of metadata for all occurrence records. Data from certain modules of the Virtual Museum (Fitzpatrick Institute of African Ornithology, University of Cape Town 2021) are also included. GBIF and Virtual Museum data are harvested and served in FBIS, as a separate Data Source that complements collated data. In FBIS, freshwater species occurrence data available for South Africa in GBIF includes periodically-updated data from the South African Institute for Aquatic Biodiversity (SAIAB), as well as 'Research Grade' iNaturalist data (i.e. records from non-captive individuals, with a picture, locality and date, and with two or more IDs in agreement at species level). Invertebrate data includes both aquatic and aerial stages. The FBIS team need to provide guidance on the taxonomic groups for which GBIF data should be harvested, and should be based on the Master Lists (see Creating Taxonomic Master Lists).

+

32.4 Extracting data and preparing bulk data for uploading into FBIS

+

FBIS includes data capture forms for adding sites, fish, invertebrate and algae data, as well as associated abiotic data. However, these forms are intended for the capture of individual site visits, and at times, especially during the development phase of an information system, it is useful to be able to upload large amounts of data at a time. To ensure that bulk data are readily ingested into FBIS, a standardised Data Upload Template needs to be produced for each group. This will ensure that data are cleaned and provided in a standardised manner so that the data uploading process runs smoothly and so that the resultant FBIS platform serves quality data.

+

32.4.1 Data Extraction

+

Data extracted from peer-reviewed articles, theses and published reports need to be standardised to allow for comparison of data amongst studies. Each article/thesis/report needs to be inspected for GPS coordinates. Publications without GPS coordinates cannot be included in the information system. All relevant information, as specified in Table 1, 32.4.2 Data Upload Templates, pertaining to the occurrence record is then extracted from the publication and added to the Date Upload Template for the relevant group.

+

32.4.2 Data Upload Templates

+

Standardised data upload templates in excel have been generated for four biodiversity groups, namely anurans, fish, invertebrates and algae. Additional upload templates may be added as new biodiversity modules are added. These templates include a number of dropdown attributes. It is critical that all taxa in the Data Upload file for a particular biodiversity group are present in the Master List of Taxa for that group. If not, the upload process will not work. For this reason, it is recommended that where possible dropdown lists are used in the Data Upload files to ensure that all data entered in the sheet is valid. As an example, the Master List of fish species in South Africa has been included as dropdown list for the FBIS Fish Data Upload Template.

+ +

The following data upload templates are provided:

+
    +
  • FBIS Fish Data Upload Template.xlsx
  • +
  • FBIS Algae Data Upload Template.xlsx
  • +
  • FBIS Invertebrate Data Upload Template.xlsx
  • +
  • FBIS Anuran Data Upload Template.xlsx
  • +
+

Many of the columns are the same for each group, although some additional columns are included for algae, and the dropdown options (e.g. biotopes) sometimes vary amongst groups. The common columns used in each group are given in Table 1. Relevant dropdown lists are provided in each template and additional group-specific columns are included in the relevant templates.

+

Table 1. Column headers with details used in data upload templates

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Column HeaderDetails
UUIDA unique identifier for each record. Drag and copy the formula down.
Original River or Wetland name NameName given in study reference
Original Site CodeSite Code given in study reference
FBIS Site CodeLeave blank (autogenerated)
Site descriptionDescription given in study reference
Refined Geomorphological ZoneAs given in study reference (if available) - Select from dropdown options
LatitudeDecimal degrees with "-" in front & "," for decimal point
LongitudeDecimal degrees with "," for decimal point
Sampling Dateyyyy/mm/dd
KingdomNot necessary to fill in as they are derived from the Master Lists
PhylumNot necessary to fill in as they are derived from the Master Lists
ClassNot necessary to fill in as they are derived from the Master Lists
OrderNot necessary to fill in as they are derived from the Master Lists
FamilyNot necessary to fill in as they are derived from the Master Lists
GenusNot necessary to fill in as they are derived from the Master Lists
SpeciesNot necessary to fill in as they are derived from the Master Lists
Taxon
Taxon rankSelect from dropdown options
PresentFill in with "1"
Sampling methodSelect from dropdown options
Sampling effort measureSelect from dropdown options
Sampling effort value
Abundance measureSelect from dropdown options
Abundance valueLeave blank if only presence data
Record typeSelect from dropdown options
Broad biotopeSelect from dropdown options
Specific biotopeSelect from dropdown options
SubstratumSelect from dropdown options
Water LevelSelect from dropdown options
Water TurbiditySelect from dropdown options
EmbeddednessSelect from dropdown options
DepthDepth (m)
Near Bed VelocityNear Bed Velocity (m/s)
CONDConductivity (mS/cm)
PHPH
DOPERDissolved Oxygen (%)
DODissolved Oxygen (mg/L)
TEMPTemperature (deg C)
TURBTurbidity (NTU)
Collector/OwnerFull name
Collector/Owner InstituteInstitute of collector/owner
Author(s)Surname + Initials
YearYear of study
SourceSource of data if from thesis or database
TitleTitle of data source if thesis or published report
Reference categorySelect from dropdown options
URLThesis handle, or article link if no DOI available
DOIDOI for reference ( e.g. 10.2989/16085914.2018.1491385)
Document Upload LinkLink to "Documents" page on FBIS after uploading PDF of published report
NotesAny details related to sampling, species, life form etc.
+

32.5 Managing citations and documents

+

All biodiversity data served on FBIS need to have associated Metadata (Figure 2). A Source Reference Management system have been incorporated in FBIS. This metadata allows the users to establish exactly where the data originated from and to navigate to the study reference if desired. As per Sources of biodiversity data, five types of study references are served, namely peer-reviewed scientific articles, theses, published reports, databases and unpublished data. This is described in a separate document: Managing Source References.

+

Figure 2. Metadata Table

+

Data Management 3

+

32.6 References

+

Dallas HF, Shelton JM, Sutton T, Tri Ciputra D, Kajee M and Job N. 2022. The Freshwater Biodiversity Information System (FBIS) – mobilising data for evaluating long-term change in South African rivers, African Journal of Aquatic Science 47(3): 291-306, DOI: 10.2989/16085914.2021.1982672

+ +

Freshwater Biodiversity Information System (FBIS). 2022. Downloaded from https://freshwaterbiodiversity.org on [current date]

+ +

Freshwater Biodiversity Information System (FBIS). 2022. FBIS User Manual. Prepared by the Freshwater Research Centre and Kartoza.

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/biodiversity-data/harvesting-gbif-data/index.html b/administrator/biodiversity-data/harvesting-gbif-data/index.html new file mode 100644 index 0000000..259a6d4 --- /dev/null +++ b/administrator/biodiversity-data/harvesting-gbif-data/index.html @@ -0,0 +1,1205 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+35. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

35. Harvesting GBIF data

+

All existing taxon occurrence data are harvested per Taxon Group from the Global Biodiversity Information Facility (GBIF). This section outlines the steps for harvesting GBIF data.

+

Only registered users with super user status are able to do this, typically the administrators .

+

The Master List of Taxa for a Taxon Group is used to facilitate harvesting of data from GBIF, thereby ensuring that the correct taxa are included on the information system.

+

35.1 Steps

+

Click on your profile and select Harvest from GBIF.

+

Harvesting GBIF data 1

+

Select the Taxon Group using the dropdown and click Start harvesting.

+

Harvesting GBIF data 2

+

You can keep track of progress. The more taxa in the master list, the longer the time needed for harvesting data from GBIF. You can keep it running in the background and continue with other work as it harvests the data.

+

Harvesting GBIF data 3

+

You can view the GBIF data harvested via the Download Logs.

+

Harvesting GBIF data 4

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800.png new file mode 100644 index 0000000..81819c2 Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_2iVgpkp.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_2iVgpkp.png new file mode 100644 index 0000000..3a58354 Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_2iVgpkp.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_486ozdK.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_486ozdK.png new file mode 100644 index 0000000..7eed3bf Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_486ozdK.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_4duvzKV.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_4duvzKV.png new file mode 100644 index 0000000..a234936 Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_4duvzKV.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_D1S6pAk.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_D1S6pAk.png new file mode 100644 index 0000000..e0f3634 Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_D1S6pAk.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_EkFBDbF.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_EkFBDbF.png new file mode 100644 index 0000000..301d0c4 Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_EkFBDbF.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_OWJAj84.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_OWJAj84.png new file mode 100644 index 0000000..bc4f63a Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_OWJAj84.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_R971XOp.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_R971XOp.png new file mode 100644 index 0000000..518e6a1 Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_R971XOp.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_X53f2uL.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_X53f2uL.png new file mode 100644 index 0000000..8bdc9fb Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_X53f2uL.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_YRMlFmI.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_YRMlFmI.png new file mode 100644 index 0000000..4303b26 Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_YRMlFmI.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_c5NXklp.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_c5NXklp.png new file mode 100644 index 0000000..be4117c Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_c5NXklp.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_gtlAfPD.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_gtlAfPD.png new file mode 100644 index 0000000..04f7784 Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_gtlAfPD.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_h4kch8c.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_h4kch8c.png new file mode 100644 index 0000000..9c1794d Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_h4kch8c.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_hsgw3On.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_hsgw3On.png new file mode 100644 index 0000000..231fddf Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_hsgw3On.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_mI1AGaF.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_mI1AGaF.png new file mode 100644 index 0000000..df29ecc Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_mI1AGaF.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_nP3N63A.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_nP3N63A.png new file mode 100644 index 0000000..c5dee16 Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_nP3N63A.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_qWlwCaa.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_qWlwCaa.png new file mode 100644 index 0000000..8c7ab55 Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_qWlwCaa.png differ diff --git a/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_yEZXcKS.png b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_yEZXcKS.png new file mode 100644 index 0000000..081fb24 Binary files /dev/null and b/administrator/biodiversity-data/img/Preparing_and_checking_an_Occurrence_Data_File.width-800_yEZXcKS.png differ diff --git a/administrator/biodiversity-data/img/chemistry-units-1.png b/administrator/biodiversity-data/img/chemistry-units-1.png new file mode 100644 index 0000000..d13c629 Binary files /dev/null and b/administrator/biodiversity-data/img/chemistry-units-1.png differ diff --git a/administrator/biodiversity-data/img/chemistry-units-2.png b/administrator/biodiversity-data/img/chemistry-units-2.png new file mode 100644 index 0000000..11727e9 Binary files /dev/null and b/administrator/biodiversity-data/img/chemistry-units-2.png differ diff --git a/administrator/biodiversity-data/img/data-management-1.png b/administrator/biodiversity-data/img/data-management-1.png new file mode 100644 index 0000000..92873b6 Binary files /dev/null and b/administrator/biodiversity-data/img/data-management-1.png differ diff --git a/administrator/biodiversity-data/img/data-management-2.png b/administrator/biodiversity-data/img/data-management-2.png new file mode 100644 index 0000000..f878da3 Binary files /dev/null and b/administrator/biodiversity-data/img/data-management-2.png differ diff --git a/administrator/biodiversity-data/img/data-management-3.png b/administrator/biodiversity-data/img/data-management-3.png new file mode 100644 index 0000000..6d5e85a Binary files /dev/null and b/administrator/biodiversity-data/img/data-management-3.png differ diff --git a/administrator/biodiversity-data/img/download-request-purposes-1.png b/administrator/biodiversity-data/img/download-request-purposes-1.png new file mode 100644 index 0000000..2f965f1 Binary files /dev/null and b/administrator/biodiversity-data/img/download-request-purposes-1.png differ diff --git a/administrator/biodiversity-data/img/download-requests-1.png b/administrator/biodiversity-data/img/download-requests-1.png new file mode 100644 index 0000000..a09ce83 Binary files /dev/null and b/administrator/biodiversity-data/img/download-requests-1.png differ diff --git a/administrator/biodiversity-data/img/download-requests-2.png b/administrator/biodiversity-data/img/download-requests-2.png new file mode 100644 index 0000000..dc21f27 Binary files /dev/null and b/administrator/biodiversity-data/img/download-requests-2.png differ diff --git a/administrator/biodiversity-data/img/endemism-1.png b/administrator/biodiversity-data/img/endemism-1.png new file mode 100644 index 0000000..7c5cd18 Binary files /dev/null and b/administrator/biodiversity-data/img/endemism-1.png differ diff --git a/administrator/biodiversity-data/img/endemism-2.png b/administrator/biodiversity-data/img/endemism-2.png new file mode 100644 index 0000000..6d67696 Binary files /dev/null and b/administrator/biodiversity-data/img/endemism-2.png differ diff --git a/administrator/biodiversity-data/img/fbis-uuids-1.png b/administrator/biodiversity-data/img/fbis-uuids-1.png new file mode 100644 index 0000000..82d9b1a Binary files /dev/null and b/administrator/biodiversity-data/img/fbis-uuids-1.png differ diff --git a/administrator/biodiversity-data/img/flat-pages-1.png b/administrator/biodiversity-data/img/flat-pages-1.png new file mode 100644 index 0000000..c3ecd83 Binary files /dev/null and b/administrator/biodiversity-data/img/flat-pages-1.png differ diff --git a/administrator/biodiversity-data/img/flat-pages-2.png b/administrator/biodiversity-data/img/flat-pages-2.png new file mode 100644 index 0000000..5b54b79 Binary files /dev/null and b/administrator/biodiversity-data/img/flat-pages-2.png differ diff --git a/administrator/biodiversity-data/img/flat-pages-3.png b/administrator/biodiversity-data/img/flat-pages-3.png new file mode 100644 index 0000000..ca21e6e Binary files /dev/null and b/administrator/biodiversity-data/img/flat-pages-3.png differ diff --git a/administrator/biodiversity-data/img/flat-pages-4.png b/administrator/biodiversity-data/img/flat-pages-4.png new file mode 100644 index 0000000..6715e30 Binary files /dev/null and b/administrator/biodiversity-data/img/flat-pages-4.png differ diff --git a/administrator/biodiversity-data/img/harvesting-gbif-data-1.png b/administrator/biodiversity-data/img/harvesting-gbif-data-1.png new file mode 100644 index 0000000..04ba366 Binary files /dev/null and b/administrator/biodiversity-data/img/harvesting-gbif-data-1.png differ diff --git a/administrator/biodiversity-data/img/harvesting-gbif-data-2.png b/administrator/biodiversity-data/img/harvesting-gbif-data-2.png new file mode 100644 index 0000000..771e2f5 Binary files /dev/null and b/administrator/biodiversity-data/img/harvesting-gbif-data-2.png differ diff --git a/administrator/biodiversity-data/img/harvesting-gbif-data-3.png b/administrator/biodiversity-data/img/harvesting-gbif-data-3.png new file mode 100644 index 0000000..5d88544 Binary files /dev/null and b/administrator/biodiversity-data/img/harvesting-gbif-data-3.png differ diff --git a/administrator/biodiversity-data/img/harvesting-gbif-data-4.png b/administrator/biodiversity-data/img/harvesting-gbif-data-4.png new file mode 100644 index 0000000..4633df8 Binary files /dev/null and b/administrator/biodiversity-data/img/harvesting-gbif-data-4.png differ diff --git a/administrator/biodiversity-data/img/iucn-conservation-status-1.png b/administrator/biodiversity-data/img/iucn-conservation-status-1.png new file mode 100644 index 0000000..ab0412a Binary files /dev/null and b/administrator/biodiversity-data/img/iucn-conservation-status-1.png differ diff --git a/administrator/biodiversity-data/img/iucn-conservation-status-2.png b/administrator/biodiversity-data/img/iucn-conservation-status-2.png new file mode 100644 index 0000000..ada2bf5 Binary files /dev/null and b/administrator/biodiversity-data/img/iucn-conservation-status-2.png differ diff --git a/administrator/biodiversity-data/img/location-context-filter-group-orders-1.png b/administrator/biodiversity-data/img/location-context-filter-group-orders-1.png new file mode 100644 index 0000000..a6a461e Binary files /dev/null and b/administrator/biodiversity-data/img/location-context-filter-group-orders-1.png differ diff --git a/administrator/biodiversity-data/img/location-context-filter-group-orders-2.png b/administrator/biodiversity-data/img/location-context-filter-group-orders-2.png new file mode 100644 index 0000000..54daf3b Binary files /dev/null and b/administrator/biodiversity-data/img/location-context-filter-group-orders-2.png differ diff --git a/administrator/biodiversity-data/img/location-context-filter-order-1.png b/administrator/biodiversity-data/img/location-context-filter-order-1.png new file mode 100644 index 0000000..b498ed1 Binary files /dev/null and b/administrator/biodiversity-data/img/location-context-filter-order-1.png differ diff --git a/administrator/biodiversity-data/img/location-context-filters-1.png b/administrator/biodiversity-data/img/location-context-filters-1.png new file mode 100644 index 0000000..7dedb87 Binary files /dev/null and b/administrator/biodiversity-data/img/location-context-filters-1.png differ diff --git a/administrator/biodiversity-data/img/location-context-filters-2.png b/administrator/biodiversity-data/img/location-context-filters-2.png new file mode 100644 index 0000000..13ca31a Binary files /dev/null and b/administrator/biodiversity-data/img/location-context-filters-2.png differ diff --git a/administrator/biodiversity-data/img/location-context-groups-1.png b/administrator/biodiversity-data/img/location-context-groups-1.png new file mode 100644 index 0000000..5483b9a Binary files /dev/null and b/administrator/biodiversity-data/img/location-context-groups-1.png differ diff --git a/administrator/biodiversity-data/img/location-sites-1.png b/administrator/biodiversity-data/img/location-sites-1.png new file mode 100644 index 0000000..6e987d0 Binary files /dev/null and b/administrator/biodiversity-data/img/location-sites-1.png differ diff --git a/administrator/biodiversity-data/img/location-sites-2.png b/administrator/biodiversity-data/img/location-sites-2.png new file mode 100644 index 0000000..902f339 Binary files /dev/null and b/administrator/biodiversity-data/img/location-sites-2.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-1.png b/administrator/biodiversity-data/img/managing-source-references-1.png new file mode 100644 index 0000000..f3f88df Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-1.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-10.png b/administrator/biodiversity-data/img/managing-source-references-10.png new file mode 100644 index 0000000..2493e70 Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-10.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-11.png b/administrator/biodiversity-data/img/managing-source-references-11.png new file mode 100644 index 0000000..cdc7252 Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-11.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-12.png b/administrator/biodiversity-data/img/managing-source-references-12.png new file mode 100644 index 0000000..45825e1 Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-12.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-13.png b/administrator/biodiversity-data/img/managing-source-references-13.png new file mode 100644 index 0000000..f5c1f0f Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-13.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-14.png b/administrator/biodiversity-data/img/managing-source-references-14.png new file mode 100644 index 0000000..ebe4427 Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-14.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-2.png b/administrator/biodiversity-data/img/managing-source-references-2.png new file mode 100644 index 0000000..6d5e85a Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-2.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-3.png b/administrator/biodiversity-data/img/managing-source-references-3.png new file mode 100644 index 0000000..7c59ce6 Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-3.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-4.png b/administrator/biodiversity-data/img/managing-source-references-4.png new file mode 100644 index 0000000..c78fc57 Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-4.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-5.png b/administrator/biodiversity-data/img/managing-source-references-5.png new file mode 100644 index 0000000..382a77c Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-5.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-6.png b/administrator/biodiversity-data/img/managing-source-references-6.png new file mode 100644 index 0000000..719f0e0 Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-6.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-7.png b/administrator/biodiversity-data/img/managing-source-references-7.png new file mode 100644 index 0000000..a3f15d4 Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-7.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-8.png b/administrator/biodiversity-data/img/managing-source-references-8.png new file mode 100644 index 0000000..7a87af6 Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-8.png differ diff --git a/administrator/biodiversity-data/img/managing-source-references-9.png b/administrator/biodiversity-data/img/managing-source-references-9.png new file mode 100644 index 0000000..6c906bb Binary files /dev/null and b/administrator/biodiversity-data/img/managing-source-references-9.png differ diff --git a/administrator/biodiversity-data/img/master-list-preparation-1.png b/administrator/biodiversity-data/img/master-list-preparation-1.png new file mode 100644 index 0000000..193937b Binary files /dev/null and b/administrator/biodiversity-data/img/master-list-preparation-1.png differ diff --git a/administrator/biodiversity-data/img/master-list-preparation-2.png b/administrator/biodiversity-data/img/master-list-preparation-2.png new file mode 100644 index 0000000..56ca62b Binary files /dev/null and b/administrator/biodiversity-data/img/master-list-preparation-2.png differ diff --git a/administrator/biodiversity-data/img/master-list-preparation-3.png b/administrator/biodiversity-data/img/master-list-preparation-3.png new file mode 100644 index 0000000..2a39841 Binary files /dev/null and b/administrator/biodiversity-data/img/master-list-preparation-3.png differ diff --git a/administrator/biodiversity-data/img/master-list-preparation-4.png b/administrator/biodiversity-data/img/master-list-preparation-4.png new file mode 100644 index 0000000..8b83a6f Binary files /dev/null and b/administrator/biodiversity-data/img/master-list-preparation-4.png differ diff --git a/administrator/biodiversity-data/img/master-list-preparation-5.png b/administrator/biodiversity-data/img/master-list-preparation-5.png new file mode 100644 index 0000000..e5ab9a5 Binary files /dev/null and b/administrator/biodiversity-data/img/master-list-preparation-5.png differ diff --git a/administrator/biodiversity-data/img/master-list-preparation-6.png b/administrator/biodiversity-data/img/master-list-preparation-6.png new file mode 100644 index 0000000..08c4b46 Binary files /dev/null and b/administrator/biodiversity-data/img/master-list-preparation-6.png differ diff --git a/administrator/biodiversity-data/img/master-list-preparation-7.png b/administrator/biodiversity-data/img/master-list-preparation-7.png new file mode 100644 index 0000000..ce994c5 Binary files /dev/null and b/administrator/biodiversity-data/img/master-list-preparation-7.png differ diff --git a/administrator/biodiversity-data/img/naming-convention.README b/administrator/biodiversity-data/img/naming-convention.README new file mode 100644 index 0000000..74a045a --- /dev/null +++ b/administrator/biodiversity-data/img/naming-convention.README @@ -0,0 +1,7 @@ +# Image naming convention + +Images should be named according to reference doc, sub-section and order in the document. +e.g. + +- The 1st image in instructions regarding zooming will be something like zooming-1, the 2nd image will be zooming-2, etc. +- The 1st image in quickstart regarding logging in will be login-1, etc diff --git a/administrator/biodiversity-data/img/non-biodiversity-layers-1.png b/administrator/biodiversity-data/img/non-biodiversity-layers-1.png new file mode 100644 index 0000000..9b278d0 Binary files /dev/null and b/administrator/biodiversity-data/img/non-biodiversity-layers-1.png differ diff --git a/administrator/biodiversity-data/img/non-biodiversity-layers-2.png b/administrator/biodiversity-data/img/non-biodiversity-layers-2.png new file mode 100644 index 0000000..5e6568a Binary files /dev/null and b/administrator/biodiversity-data/img/non-biodiversity-layers-2.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-1.png b/administrator/biodiversity-data/img/occurence-data-preparation-1.png new file mode 100644 index 0000000..252c546 Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-1.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-10.png b/administrator/biodiversity-data/img/occurence-data-preparation-10.png new file mode 100644 index 0000000..e28d228 Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-10.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-11.png b/administrator/biodiversity-data/img/occurence-data-preparation-11.png new file mode 100644 index 0000000..4a0cef6 Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-11.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-12.png b/administrator/biodiversity-data/img/occurence-data-preparation-12.png new file mode 100644 index 0000000..9609c79 Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-12.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-13.png b/administrator/biodiversity-data/img/occurence-data-preparation-13.png new file mode 100644 index 0000000..a139338 Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-13.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-14.png b/administrator/biodiversity-data/img/occurence-data-preparation-14.png new file mode 100644 index 0000000..2c58b2d Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-14.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-15.png b/administrator/biodiversity-data/img/occurence-data-preparation-15.png new file mode 100644 index 0000000..577848a Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-15.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-16.png b/administrator/biodiversity-data/img/occurence-data-preparation-16.png new file mode 100644 index 0000000..638d0af Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-16.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-17.png b/administrator/biodiversity-data/img/occurence-data-preparation-17.png new file mode 100644 index 0000000..4ff30e8 Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-17.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-18.png b/administrator/biodiversity-data/img/occurence-data-preparation-18.png new file mode 100644 index 0000000..58b0f5e Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-18.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-2.png b/administrator/biodiversity-data/img/occurence-data-preparation-2.png new file mode 100644 index 0000000..086e059 Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-2.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-3.png b/administrator/biodiversity-data/img/occurence-data-preparation-3.png new file mode 100644 index 0000000..c4d5939 Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-3.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-4.png b/administrator/biodiversity-data/img/occurence-data-preparation-4.png new file mode 100644 index 0000000..3ebe95b Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-4.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-5.png b/administrator/biodiversity-data/img/occurence-data-preparation-5.png new file mode 100644 index 0000000..0063d49 Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-5.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-6.png b/administrator/biodiversity-data/img/occurence-data-preparation-6.png new file mode 100644 index 0000000..58a1da3 Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-6.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-7.png b/administrator/biodiversity-data/img/occurence-data-preparation-7.png new file mode 100644 index 0000000..bfc4470 Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-7.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-8.png b/administrator/biodiversity-data/img/occurence-data-preparation-8.png new file mode 100644 index 0000000..28dd90a Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-8.png differ diff --git a/administrator/biodiversity-data/img/occurence-data-preparation-9.png b/administrator/biodiversity-data/img/occurence-data-preparation-9.png new file mode 100644 index 0000000..75f9d20 Binary files /dev/null and b/administrator/biodiversity-data/img/occurence-data-preparation-9.png differ diff --git a/administrator/biodiversity-data/img/occurrence-data-uploading-1.png b/administrator/biodiversity-data/img/occurrence-data-uploading-1.png new file mode 100644 index 0000000..79f4e66 Binary files /dev/null and b/administrator/biodiversity-data/img/occurrence-data-uploading-1.png differ diff --git a/administrator/biodiversity-data/img/occurrence-data-uploading-2.png b/administrator/biodiversity-data/img/occurrence-data-uploading-2.png new file mode 100644 index 0000000..ce4c2f8 Binary files /dev/null and b/administrator/biodiversity-data/img/occurrence-data-uploading-2.png differ diff --git a/administrator/biodiversity-data/img/occurrence-data-uploading-3.png b/administrator/biodiversity-data/img/occurrence-data-uploading-3.png new file mode 100644 index 0000000..857b2b8 Binary files /dev/null and b/administrator/biodiversity-data/img/occurrence-data-uploading-3.png differ diff --git a/administrator/biodiversity-data/img/occurrence-data-uploading-4.png b/administrator/biodiversity-data/img/occurrence-data-uploading-4.png new file mode 100644 index 0000000..c4cf583 Binary files /dev/null and b/administrator/biodiversity-data/img/occurrence-data-uploading-4.png differ diff --git a/administrator/biodiversity-data/img/people-1.png b/administrator/biodiversity-data/img/people-1.png new file mode 100644 index 0000000..534cc45 Binary files /dev/null and b/administrator/biodiversity-data/img/people-1.png differ diff --git a/administrator/biodiversity-data/img/people-2.png b/administrator/biodiversity-data/img/people-2.png new file mode 100644 index 0000000..42ba5d0 Binary files /dev/null and b/administrator/biodiversity-data/img/people-2.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-1.png b/administrator/biodiversity-data/img/physico-chemical-data-1.png new file mode 100644 index 0000000..7905b69 Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-1.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-10.png b/administrator/biodiversity-data/img/physico-chemical-data-10.png new file mode 100644 index 0000000..e2d51bd Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-10.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-11.png b/administrator/biodiversity-data/img/physico-chemical-data-11.png new file mode 100644 index 0000000..624eb27 Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-11.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-12.png b/administrator/biodiversity-data/img/physico-chemical-data-12.png new file mode 100644 index 0000000..723bf09 Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-12.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-13.png b/administrator/biodiversity-data/img/physico-chemical-data-13.png new file mode 100644 index 0000000..ac0b61f Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-13.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-14.png b/administrator/biodiversity-data/img/physico-chemical-data-14.png new file mode 100644 index 0000000..6403863 Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-14.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-15.png b/administrator/biodiversity-data/img/physico-chemical-data-15.png new file mode 100644 index 0000000..40c9c1d Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-15.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-16.png b/administrator/biodiversity-data/img/physico-chemical-data-16.png new file mode 100644 index 0000000..040a6bb Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-16.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-17.png b/administrator/biodiversity-data/img/physico-chemical-data-17.png new file mode 100644 index 0000000..4f85100 Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-17.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-18.png b/administrator/biodiversity-data/img/physico-chemical-data-18.png new file mode 100644 index 0000000..b0dbb5f Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-18.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-19.png b/administrator/biodiversity-data/img/physico-chemical-data-19.png new file mode 100644 index 0000000..bae5d6e Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-19.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-2.png b/administrator/biodiversity-data/img/physico-chemical-data-2.png new file mode 100644 index 0000000..7f55b53 Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-2.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-20.png b/administrator/biodiversity-data/img/physico-chemical-data-20.png new file mode 100644 index 0000000..f049736 Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-20.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-3.png b/administrator/biodiversity-data/img/physico-chemical-data-3.png new file mode 100644 index 0000000..086e059 Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-3.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-4.png b/administrator/biodiversity-data/img/physico-chemical-data-4.png new file mode 100644 index 0000000..caac56a Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-4.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-5.png b/administrator/biodiversity-data/img/physico-chemical-data-5.png new file mode 100644 index 0000000..dc9f40e Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-5.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-6.png b/administrator/biodiversity-data/img/physico-chemical-data-6.png new file mode 100644 index 0000000..874a5a9 Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-6.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-7.png b/administrator/biodiversity-data/img/physico-chemical-data-7.png new file mode 100644 index 0000000..2b05a16 Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-7.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-8.png b/administrator/biodiversity-data/img/physico-chemical-data-8.png new file mode 100644 index 0000000..cd1aa6b Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-8.png differ diff --git a/administrator/biodiversity-data/img/physico-chemical-data-9.png b/administrator/biodiversity-data/img/physico-chemical-data-9.png new file mode 100644 index 0000000..5791788 Binary files /dev/null and b/administrator/biodiversity-data/img/physico-chemical-data-9.png differ diff --git a/administrator/biodiversity-data/img/sampling-methods-1.png b/administrator/biodiversity-data/img/sampling-methods-1.png new file mode 100644 index 0000000..47aaae6 Binary files /dev/null and b/administrator/biodiversity-data/img/sampling-methods-1.png differ diff --git a/administrator/biodiversity-data/img/sampling-methods-2.png b/administrator/biodiversity-data/img/sampling-methods-2.png new file mode 100644 index 0000000..a51ec37 Binary files /dev/null and b/administrator/biodiversity-data/img/sampling-methods-2.png differ diff --git a/administrator/biodiversity-data/img/sampling-methods-3.png b/administrator/biodiversity-data/img/sampling-methods-3.png new file mode 100644 index 0000000..b2033b3 Binary files /dev/null and b/administrator/biodiversity-data/img/sampling-methods-3.png differ diff --git a/administrator/biodiversity-data/img/sampling-methods-4.png b/administrator/biodiversity-data/img/sampling-methods-4.png new file mode 100644 index 0000000..7701a18 Binary files /dev/null and b/administrator/biodiversity-data/img/sampling-methods-4.png differ diff --git a/administrator/biodiversity-data/img/site-biodiversity-data-1.png b/administrator/biodiversity-data/img/site-biodiversity-data-1.png new file mode 100644 index 0000000..30bf393 Binary files /dev/null and b/administrator/biodiversity-data/img/site-biodiversity-data-1.png differ diff --git a/administrator/biodiversity-data/img/site-biodiversity-data-10.png b/administrator/biodiversity-data/img/site-biodiversity-data-10.png new file mode 100644 index 0000000..3f0ad01 Binary files /dev/null and b/administrator/biodiversity-data/img/site-biodiversity-data-10.png differ diff --git a/administrator/biodiversity-data/img/site-biodiversity-data-11.png b/administrator/biodiversity-data/img/site-biodiversity-data-11.png new file mode 100644 index 0000000..5106208 Binary files /dev/null and b/administrator/biodiversity-data/img/site-biodiversity-data-11.png differ diff --git a/administrator/biodiversity-data/img/site-biodiversity-data-2.png b/administrator/biodiversity-data/img/site-biodiversity-data-2.png new file mode 100644 index 0000000..255f657 Binary files /dev/null and b/administrator/biodiversity-data/img/site-biodiversity-data-2.png differ diff --git a/administrator/biodiversity-data/img/site-biodiversity-data-3.png b/administrator/biodiversity-data/img/site-biodiversity-data-3.png new file mode 100644 index 0000000..c48691a Binary files /dev/null and b/administrator/biodiversity-data/img/site-biodiversity-data-3.png differ diff --git a/administrator/biodiversity-data/img/site-biodiversity-data-4.png b/administrator/biodiversity-data/img/site-biodiversity-data-4.png new file mode 100644 index 0000000..a646bea Binary files /dev/null and b/administrator/biodiversity-data/img/site-biodiversity-data-4.png differ diff --git a/administrator/biodiversity-data/img/site-biodiversity-data-5.png b/administrator/biodiversity-data/img/site-biodiversity-data-5.png new file mode 100644 index 0000000..6f6e2b7 Binary files /dev/null and b/administrator/biodiversity-data/img/site-biodiversity-data-5.png differ diff --git a/administrator/biodiversity-data/img/site-biodiversity-data-6.png b/administrator/biodiversity-data/img/site-biodiversity-data-6.png new file mode 100644 index 0000000..c0f7503 Binary files /dev/null and b/administrator/biodiversity-data/img/site-biodiversity-data-6.png differ diff --git a/administrator/biodiversity-data/img/site-biodiversity-data-7.png b/administrator/biodiversity-data/img/site-biodiversity-data-7.png new file mode 100644 index 0000000..2da603c Binary files /dev/null and b/administrator/biodiversity-data/img/site-biodiversity-data-7.png differ diff --git a/administrator/biodiversity-data/img/site-biodiversity-data-8.png b/administrator/biodiversity-data/img/site-biodiversity-data-8.png new file mode 100644 index 0000000..5ce8b1a Binary files /dev/null and b/administrator/biodiversity-data/img/site-biodiversity-data-8.png differ diff --git a/administrator/biodiversity-data/img/site-biodiversity-data-9.png b/administrator/biodiversity-data/img/site-biodiversity-data-9.png new file mode 100644 index 0000000..980e2c3 Binary files /dev/null and b/administrator/biodiversity-data/img/site-biodiversity-data-9.png differ diff --git a/administrator/biodiversity-data/img/site-settings-1.png b/administrator/biodiversity-data/img/site-settings-1.png new file mode 100644 index 0000000..92eaf7b Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-1.png differ diff --git a/administrator/biodiversity-data/img/site-settings-10.png b/administrator/biodiversity-data/img/site-settings-10.png new file mode 100644 index 0000000..60b2fc4 Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-10.png differ diff --git a/administrator/biodiversity-data/img/site-settings-11.png b/administrator/biodiversity-data/img/site-settings-11.png new file mode 100644 index 0000000..c64568e Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-11.png differ diff --git a/administrator/biodiversity-data/img/site-settings-12.png b/administrator/biodiversity-data/img/site-settings-12.png new file mode 100644 index 0000000..8ebf3cd Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-12.png differ diff --git a/administrator/biodiversity-data/img/site-settings-13.png b/administrator/biodiversity-data/img/site-settings-13.png new file mode 100644 index 0000000..540fef8 Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-13.png differ diff --git a/administrator/biodiversity-data/img/site-settings-14.png b/administrator/biodiversity-data/img/site-settings-14.png new file mode 100644 index 0000000..05c2768 Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-14.png differ diff --git a/administrator/biodiversity-data/img/site-settings-15.png b/administrator/biodiversity-data/img/site-settings-15.png new file mode 100644 index 0000000..9d14fc9 Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-15.png differ diff --git a/administrator/biodiversity-data/img/site-settings-2.png b/administrator/biodiversity-data/img/site-settings-2.png new file mode 100644 index 0000000..35522bc Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-2.png differ diff --git a/administrator/biodiversity-data/img/site-settings-3.png b/administrator/biodiversity-data/img/site-settings-3.png new file mode 100644 index 0000000..224e68b Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-3.png differ diff --git a/administrator/biodiversity-data/img/site-settings-4.png b/administrator/biodiversity-data/img/site-settings-4.png new file mode 100644 index 0000000..f2b2733 Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-4.png differ diff --git a/administrator/biodiversity-data/img/site-settings-5.png b/administrator/biodiversity-data/img/site-settings-5.png new file mode 100644 index 0000000..1dfa147 Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-5.png differ diff --git a/administrator/biodiversity-data/img/site-settings-6.png b/administrator/biodiversity-data/img/site-settings-6.png new file mode 100644 index 0000000..b932290 Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-6.png differ diff --git a/administrator/biodiversity-data/img/site-settings-7.png b/administrator/biodiversity-data/img/site-settings-7.png new file mode 100644 index 0000000..b3d9f4f Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-7.png differ diff --git a/administrator/biodiversity-data/img/site-settings-8.png b/administrator/biodiversity-data/img/site-settings-8.png new file mode 100644 index 0000000..59e1bae Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-8.png differ diff --git a/administrator/biodiversity-data/img/site-settings-9.png b/administrator/biodiversity-data/img/site-settings-9.png new file mode 100644 index 0000000..f006bd7 Binary files /dev/null and b/administrator/biodiversity-data/img/site-settings-9.png differ diff --git a/administrator/biodiversity-data/img/source-references-1.png b/administrator/biodiversity-data/img/source-references-1.png new file mode 100644 index 0000000..9a54590 Binary files /dev/null and b/administrator/biodiversity-data/img/source-references-1.png differ diff --git a/administrator/biodiversity-data/img/source-references-2.png b/administrator/biodiversity-data/img/source-references-2.png new file mode 100644 index 0000000..20b444d Binary files /dev/null and b/administrator/biodiversity-data/img/source-references-2.png differ diff --git a/administrator/biodiversity-data/img/source-references-3.png b/administrator/biodiversity-data/img/source-references-3.png new file mode 100644 index 0000000..0d64c62 Binary files /dev/null and b/administrator/biodiversity-data/img/source-references-3.png differ diff --git a/administrator/biodiversity-data/img/taxa-1.png b/administrator/biodiversity-data/img/taxa-1.png new file mode 100644 index 0000000..762bfd7 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-1.png differ diff --git a/administrator/biodiversity-data/img/taxa-2.png b/administrator/biodiversity-data/img/taxa-2.png new file mode 100644 index 0000000..a727ed1 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-2.png differ diff --git a/administrator/biodiversity-data/img/taxa-3.png b/administrator/biodiversity-data/img/taxa-3.png new file mode 100644 index 0000000..4781dc8 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-3.png differ diff --git a/administrator/biodiversity-data/img/taxa-4.png b/administrator/biodiversity-data/img/taxa-4.png new file mode 100644 index 0000000..daa5d78 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-4.png differ diff --git a/administrator/biodiversity-data/img/taxa-5.png b/administrator/biodiversity-data/img/taxa-5.png new file mode 100644 index 0000000..c436fa9 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-5.png differ diff --git a/administrator/biodiversity-data/img/taxa-6.png b/administrator/biodiversity-data/img/taxa-6.png new file mode 100644 index 0000000..a520582 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-6.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-1.png b/administrator/biodiversity-data/img/taxa-management-1.png new file mode 100644 index 0000000..c3d9848 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-1.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-10.png b/administrator/biodiversity-data/img/taxa-management-10.png new file mode 100644 index 0000000..475788a Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-10.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-11.png b/administrator/biodiversity-data/img/taxa-management-11.png new file mode 100644 index 0000000..6fa1daa Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-11.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-12.png b/administrator/biodiversity-data/img/taxa-management-12.png new file mode 100644 index 0000000..da49aba Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-12.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-13.png b/administrator/biodiversity-data/img/taxa-management-13.png new file mode 100644 index 0000000..42c5643 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-13.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-14.png b/administrator/biodiversity-data/img/taxa-management-14.png new file mode 100644 index 0000000..91d5dde Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-14.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-15.png b/administrator/biodiversity-data/img/taxa-management-15.png new file mode 100644 index 0000000..0cef10d Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-15.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-16.png b/administrator/biodiversity-data/img/taxa-management-16.png new file mode 100644 index 0000000..c5ae838 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-16.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-17.png b/administrator/biodiversity-data/img/taxa-management-17.png new file mode 100644 index 0000000..8a6b0d8 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-17.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-18.png b/administrator/biodiversity-data/img/taxa-management-18.png new file mode 100644 index 0000000..cdde727 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-18.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-19.png b/administrator/biodiversity-data/img/taxa-management-19.png new file mode 100644 index 0000000..cb509fd Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-19.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-2.png b/administrator/biodiversity-data/img/taxa-management-2.png new file mode 100644 index 0000000..9e092d3 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-2.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-20.png b/administrator/biodiversity-data/img/taxa-management-20.png new file mode 100644 index 0000000..01b6207 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-20.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-21.png b/administrator/biodiversity-data/img/taxa-management-21.png new file mode 100644 index 0000000..15a3b6c Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-21.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-22.png b/administrator/biodiversity-data/img/taxa-management-22.png new file mode 100644 index 0000000..18931c9 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-22.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-23.png b/administrator/biodiversity-data/img/taxa-management-23.png new file mode 100644 index 0000000..7e80ace Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-23.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-3.png b/administrator/biodiversity-data/img/taxa-management-3.png new file mode 100644 index 0000000..91e33f0 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-3.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-4.png b/administrator/biodiversity-data/img/taxa-management-4.png new file mode 100644 index 0000000..8f99cae Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-4.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-5.png b/administrator/biodiversity-data/img/taxa-management-5.png new file mode 100644 index 0000000..f331452 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-5.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-6.png b/administrator/biodiversity-data/img/taxa-management-6.png new file mode 100644 index 0000000..2b9401c Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-6.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-7.png b/administrator/biodiversity-data/img/taxa-management-7.png new file mode 100644 index 0000000..10b033a Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-7.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-8.png b/administrator/biodiversity-data/img/taxa-management-8.png new file mode 100644 index 0000000..73b8c8f Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-8.png differ diff --git a/administrator/biodiversity-data/img/taxa-management-9.png b/administrator/biodiversity-data/img/taxa-management-9.png new file mode 100644 index 0000000..2da3cb6 Binary files /dev/null and b/administrator/biodiversity-data/img/taxa-management-9.png differ diff --git a/administrator/biodiversity-data/img/taxon-group-upload-1.png b/administrator/biodiversity-data/img/taxon-group-upload-1.png new file mode 100644 index 0000000..a1a5932 Binary files /dev/null and b/administrator/biodiversity-data/img/taxon-group-upload-1.png differ diff --git a/administrator/biodiversity-data/img/taxon-group-upload-2.png b/administrator/biodiversity-data/img/taxon-group-upload-2.png new file mode 100644 index 0000000..c508106 Binary files /dev/null and b/administrator/biodiversity-data/img/taxon-group-upload-2.png differ diff --git a/administrator/biodiversity-data/img/taxon-group-upload-3.png b/administrator/biodiversity-data/img/taxon-group-upload-3.png new file mode 100644 index 0000000..2d20751 Binary files /dev/null and b/administrator/biodiversity-data/img/taxon-group-upload-3.png differ diff --git a/administrator/biodiversity-data/img/taxon-group-upload-4.png b/administrator/biodiversity-data/img/taxon-group-upload-4.png new file mode 100644 index 0000000..fe6a18e Binary files /dev/null and b/administrator/biodiversity-data/img/taxon-group-upload-4.png differ diff --git a/administrator/biodiversity-data/img/taxon-group-upload-5.png b/administrator/biodiversity-data/img/taxon-group-upload-5.png new file mode 100644 index 0000000..a0c00d6 Binary files /dev/null and b/administrator/biodiversity-data/img/taxon-group-upload-5.png differ diff --git a/administrator/biodiversity-data/img/taxon-group-upload-6.png b/administrator/biodiversity-data/img/taxon-group-upload-6.png new file mode 100644 index 0000000..e9392e6 Binary files /dev/null and b/administrator/biodiversity-data/img/taxon-group-upload-6.png differ diff --git a/administrator/biodiversity-data/img/taxon-group-upload-7.png b/administrator/biodiversity-data/img/taxon-group-upload-7.png new file mode 100644 index 0000000..1db6176 Binary files /dev/null and b/administrator/biodiversity-data/img/taxon-group-upload-7.png differ diff --git a/administrator/biodiversity-data/img/taxon-group-upload-8.png b/administrator/biodiversity-data/img/taxon-group-upload-8.png new file mode 100644 index 0000000..e1e3973 Binary files /dev/null and b/administrator/biodiversity-data/img/taxon-group-upload-8.png differ diff --git a/administrator/biodiversity-data/img/taxon-groups-1.png b/administrator/biodiversity-data/img/taxon-groups-1.png new file mode 100644 index 0000000..27b86fc Binary files /dev/null and b/administrator/biodiversity-data/img/taxon-groups-1.png differ diff --git a/administrator/biodiversity-data/img/taxon-groups-2.png b/administrator/biodiversity-data/img/taxon-groups-2.png new file mode 100644 index 0000000..a75552a Binary files /dev/null and b/administrator/biodiversity-data/img/taxon-groups-2.png differ diff --git a/administrator/biodiversity-data/img/taxon-groups-3.png b/administrator/biodiversity-data/img/taxon-groups-3.png new file mode 100644 index 0000000..4899b01 Binary files /dev/null and b/administrator/biodiversity-data/img/taxon-groups-3.png differ diff --git a/administrator/biodiversity-data/img/validate-records-1.png b/administrator/biodiversity-data/img/validate-records-1.png new file mode 100644 index 0000000..0ea1054 Binary files /dev/null and b/administrator/biodiversity-data/img/validate-records-1.png differ diff --git a/administrator/biodiversity-data/img/validate-records-2.png b/administrator/biodiversity-data/img/validate-records-2.png new file mode 100644 index 0000000..9bf84f9 Binary files /dev/null and b/administrator/biodiversity-data/img/validate-records-2.png differ diff --git a/administrator/biodiversity-data/img/validate-records-3.png b/administrator/biodiversity-data/img/validate-records-3.png new file mode 100644 index 0000000..a28d98f Binary files /dev/null and b/administrator/biodiversity-data/img/validate-records-3.png differ diff --git a/administrator/biodiversity-data/img/validate-records-4.png b/administrator/biodiversity-data/img/validate-records-4.png new file mode 100644 index 0000000..be09ea1 Binary files /dev/null and b/administrator/biodiversity-data/img/validate-records-4.png differ diff --git a/administrator/biodiversity-data/img/validate-records-5.png b/administrator/biodiversity-data/img/validate-records-5.png new file mode 100644 index 0000000..432140e Binary files /dev/null and b/administrator/biodiversity-data/img/validate-records-5.png differ diff --git a/administrator/biodiversity-data/img/validate-records-6.png b/administrator/biodiversity-data/img/validate-records-6.png new file mode 100644 index 0000000..b355461 Binary files /dev/null and b/administrator/biodiversity-data/img/validate-records-6.png differ diff --git a/administrator/biodiversity-data/img/validate-records-7.png b/administrator/biodiversity-data/img/validate-records-7.png new file mode 100644 index 0000000..772abea Binary files /dev/null and b/administrator/biodiversity-data/img/validate-records-7.png differ diff --git a/administrator/biodiversity-data/img/validate-records-8.png b/administrator/biodiversity-data/img/validate-records-8.png new file mode 100644 index 0000000..9a5507b Binary files /dev/null and b/administrator/biodiversity-data/img/validate-records-8.png differ diff --git a/administrator/biodiversity-data/img/validate-records-9.png b/administrator/biodiversity-data/img/validate-records-9.png new file mode 100644 index 0000000..6293cbb Binary files /dev/null and b/administrator/biodiversity-data/img/validate-records-9.png differ diff --git a/administrator/biodiversity-data/index.html b/administrator/biodiversity-data/index.html new file mode 100644 index 0000000..2024c94 --- /dev/null +++ b/administrator/biodiversity-data/index.html @@ -0,0 +1,1177 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+31. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

31. Administration of biodiversity data

+

This section provides a guide for biodiversity data administrators to mobilize and ingest biodiversity data. The steps outlined are sequential and each provides details on the process and key considerations.

+
+

Only registered users with super user status, typically the site administrators, are able to view the administration sections and undertake the following steps related to the mobilization and ingestion of biodiversity data.

+
+

The sections covered include:

+
+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/biodiversity-data/manage-admin-tables/index.html b/administrator/biodiversity-data/manage-admin-tables/index.html new file mode 100644 index 0000000..176f970 --- /dev/null +++ b/administrator/biodiversity-data/manage-admin-tables/index.html @@ -0,0 +1,2044 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+42. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

42. Managing BIMS Admin tables

+

Several backend tables can be updated and managed by administrators, including the Biodiversity Information Management System (BIMS), and are accessible via the Admin Page. Provided here, is a list of actions related to the Site Administration including the BIMS table management that an administrator (super user status) may need to edit or check. Currently, only the tables that the administrator needs to be able to revise have been described, and not all the tables in the Site Administration and BIMS. They are described chronologically as they appear in Site Administration. This document will continually need to be updated as new administration functions are added.

+

Link to specific sub-sections in BIMS as well as other admin tasks:

+

Managing BIMS Admin tables

+ +

42.1 BIMS - Biotopes

+

Here you manage the broad biotope categories, description and order; the specific biotope categories, description and order; and the substratum. These biotopes are initially populated by the biodiversity data upload files, where each biotope is specified in the dropdowns. Details are provided below. Certain biotopes and substrata may be associated with one or more modules. As more biodiversity modules are added, it may be necessary for the administrator to update biotopes.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ModuleBroad BiotopeSpecific BiotopeSubstratum
AllUnspecified  
AllMixed  
Algae, invertebrates, anuransStones In Current  
algae, invertebrates, anuransStones Out Of Current  
algae, invertebrates, anuransMarginal Vegetation  
algae, invertebrates, anuransAquatic Vegetation  
algae, invertebrates, anuransGravel/Sand/Mud  
algae, invertebratesArtificial substrate  
Fish onlySlow-Shallow  
Fish onlySlow-Deep  
Fish onlyFast-Shallow  
Fish onlyFast-Deep  
All Backwater 
All Bedrock 
All Cascade 
All Chute 
All Detritus 
All Mixed 
All Pool 
All Rapid 
All Riffle 
All Run 
All Slackwater 
All Unspecified 
All Waterfall 
All  Unspecified
All  Mixed
All  Bedrock
All  Boulder
All  Cobble
All  Detritus
All  Gravel
All  Pebble
All  Sand
All  Silt/Mud/Clay
+

If these have not been included in the data occurrence upload files, then they are blank. New biotopes can be added by clicking the “+ Add biotope”.

+

42.2 BIMS - Chemistry units

+

Here you manage the physico-chemical data including the Chem Code (NB this needs to match the column in the physico-chemical data upload template), chem description, chem unit, whether the variable needs to be shown in abiotic form (abiotic list), minimum and maximum values. New chemistry units can be added by clicking the “+ Add chemistry unit”.

+

Chemistry units 1

+

Changes can be made to each variable by clicking on the relevant Chem code and editing the appropriate field. Here one can also specify the number of decimal places.

+

Chemistry units 2

+

42.3 BIMS - Download request purposes

+

Here you manage the download request purposes that a user chooses when requesting a download of a graph or csv file. New purposes can be added by selecting “Add download request purpose” and the sort order can be updated.

+

Download request purposes 1

+

42.4 BIMS - Download requests

+

Here you can see all download requests from users, including details of the requester, resource type (csv, table, chart), resource name and purpose (as specified in the download request purposes). One can find out further details of the request by clicking on the Request date link, which opens up a second form. This is useful to track the progress of the large request downloads.

+

Download requests 1

+

Download requests 2

+

42.5 BIMS - Endemism

+

Here you manage the endemism categories including the Name (what is shown on the dashboard), description and display order. The endemism categories are added during the uploading of the taxonomic master lists. Note that if the description is used in the master list, then this will be shown on the side panel and / or dashboard. It is important to always upload the Name only.

+

Endemism 1

+

Each endemism category can be edited by clicking on the Name

+

Endemism 2

+

42.6 BIMS - FBIS UUIDs

+

Here you can view all the uuids - this is a unique id for each occurrence record. It also allows the administrator to delete a specific record based on it uuid.

+

FBIS UUIDs 1

+

42.7 BIMS - IUCN Conservation status

+

Here you can manage the Conservation status categories for global and national. Global is pulled down from the IUCN, while national is from SANBI. Status’s only applicable to national need to be opened and national checked. To change a status click on category.

+

IUCN Conservation status 1

+

IUCN Conservation status 2

+

42.8 BIMS - Location context filter group orders

+

Here you can manage the spatial layers shown in the side panel and dashboards, as well as the display and filter orders. This is done by clicking on the ID link, which opens up a separate form for each spatial layer.

+

Location context filter group orders 1

+

Location context filter group orders 2

+

42.9 BIMS - Location context filter order

+

Here you can change the display order of the spatial filters.

+

Location context filter order 1

+

42.10 BIMS - Location context groups

+

Here you can manage the spatial layers and groups, which relate to geocontext. Each layer can be opened to view detail.

+

Location context groups 1

+

42.11 BIMS - Location context filters

+

Here you manage what is seen on the Side panel and Dashboard for a single site. Information included in the dashboards is indicated with a green tick.

+

Location context filters 1

+

To change what is displayed click the ID Number and check or uncheck the box for each. Note that there are some extra aspects that still need clarifying related to order etc.

+

Location context filters 2

+

42.12 BIMS - Location sites

+

Here you can view sites, filter for specific site and update site codes.

+

Location sites 1

+

Here we are also able to update the geocontext data for each site or selection of sites.

+

Location sites 2

+

42.13 BIMS - Non-biodiversity layers

+

Here you manage the order that spatial layers are shown. This includes viewing and/or editing the order, name, wms url and Wms layer name. By clicking on the order, the details of the layer can be viewed and edited. Only administrators experienced in geocontext and GGIS should edit this as it links directly to these components.

+

Non-biodiversity layers 1

+

Non-biodiversity layers 2

+

42.14 BIMS - Notifications

+

***To Be Updated***

+

42.15 BIMS - Sampling methods

+

Here you manage the sampling methods used for collection of biodiversity occurrence data. These sampling methods are initially populated by the biodiversity data upload files, where each sampling method is specified in the dropdowns. Details are provided below.

+

For each sampling method the administrator needs to select the taxon group or groups that the method is associated with and certain sampling methods may be associated with one or more taxon groups / modules. As more biodiversity modules are added, it may be necessary for the administrator to update the sampling methods.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ModuleSampling method
Invertebrates onlyBaited Line
Invertebrates onlyBox/Surber
Invertebrates onlyDrift Net
Invertebrates onlyKick Net
Invertebrates onlyLight Trap
Invertebrates onlyStone
Invertebrates, fishHand Net
Fish onlyFyke net
Fish onlyGill net
Fish onlyRod and line angling
Fish onlySeine net
Fish onlySnorkelling
Fish, anuransUnderwater video analysis
Fish, anuransElectro-fishing
Fish, anuransVisual survey
AnuransActive acoustic survey
AnuransPassive acoustic survey
AnuransBaited trapping
AnuransNon-baited survey
AllUnspecified
AllMultiple
+

Sampling methods 1

+

Changes can be made to each sampling method by clicking on the Sampling method and editing the name, order and Taxon group it is appropriate to. To select more than one taxon group click Control Select simultaneously. If these have not been included in the data occurrence upload files, then they are blank. New sampling methods can be added by clicking the “+ Add sampling method”.

+

We have also added functionality to merge sampling methods, in the event that the same sampling method is added, but with a slight variation. For example:

+

Sampling methods 2

+

To merge these two or more sampling methods, first you need to verify the correct one, by opening the method and ticking the verify box.

+

Sampling methods 3

+

Then you use the select “Merge sampling methods” and click go.

+

Sampling methods 4

+

42.16 BIMS - Site settings

+

Here you manage several components related to the setting of the site (i.e. webpage, url for the information systems, e.g. FBIS, RBIS, ORBIS etc.). Details of the sections that an administrator can change are provided below.

+

Site notice can be changed in the Site settings section.

+

Site settings 1

+

You can specify the readme file that is bundled with the downloaded occurrence data.

+

Site settings 2

+

You can specify the taxonomic upload template for the Master lists. This is then downloadable on the Upload – Taxonomic data.

+

Site settings 3

+

You can specify the occurrence upload template for the occurrence data. This is then downloadable on the Upload – Occurrence data.

+

Site settings 4

+

You can view and/or edit the disclaimer form text and disclaimer doc text.

+

Site settings 5

+

You can enable or disable the third party layer as not all information systems have links to third party data

+

Site settings 6

+

Site settings 7

+

You can enable or disable sass as not all information systems have sass data

+

Site settings 8

+

You can enable or disable water temperature data as not all information systems have water temperature data

+

Site settings 9

+

You can enable or disable download request approval. If this is disabled then the user can download the data without waiting for approval from the administrator.

+

Site settings 10

+

You can enable or disable the module summary on the landing page dashboard. This is not applicable to FBIS, only RBIS and ORBIS.

+

Site settings 11

+

Site settings 12

+

You can enable or disable the remove all occurrence tool in Taxon Management. This should never be activated on the live/production site as clicking the Remove all button, will delete all the occurrence data for the module. It can be enabled on the testing site as this allows administrators to practice the creation of new modules, uploading of taxonomic master lists and the uploading f occurrence data.

+

Site settings 13

+

Site settings 14

+

You can view and/or edit the copyright text that is visible at the bottom of the landing page.

+

Site settings 15

+

42.17 BIMS - Source references

+

Generally it is easiest to manage source references (i.e. the metadata associated with each occurrence record).

+

Source references 1

+

However, on occasions, issues arise whereby the source reference is duplicated, possibly because of a small typo during data capture. In the Admin - Source references – section it is possible to merge two source references. One does this by finding the two relevant source reference, opening the correct one and selecting “Verify”, the checking the box next to the two (or more) references to be merged, and using the Merge from the dropdown lists, the Go. Note that the Source reference needs to be the same type to be able to merge.

+

Source references 2

+

Source references 3

+

42.18 BIMS - Taxa

+

Here you manage all aspects related taxa within the information system. Most of this is done easily within Taxon Management, but there are some actions that can only be done within this table, including deleting a taxon (this cannot be done if occurrence data are associated with it), merging taxa and updating taxa (when one taxon is a synonym of another).

+

The table includes the Canonical Name (also referred to as the "true name”), the Link to gbif, the Scientific Name, the Taxonomic Rank, the Parent, the Import date, the Taxonomic Status, the Legacy Canonical Name, and whether the taxon has been Verified. Ultimately all taxa in the information system should be verified.

+

Taxa 1

+

Clicking on the canonical name opens up the Change Taxonomy form for the selected species. Note that this is same as that accessed within Taxon Management.

+

Taxa 2

+

A search field and filters are also included to assist you to navigate.

+

Taxa 3

+

To delete a taxon, click the check box, and select Delete selected taxon, and click GO

+

Taxa 5

+

There is a check, and if you click, Yes, I am sure, then the taxon will be deleted

+

Taxa 6

+

Sometimes errors are picked up in the taxa, for example there are two taxa that are the same. One the needs to merge these taxa. Prior to merging, the correct taxon needs to be checked and the verified button checked. Then to merge the two taxa, click the check box, and select Merge taxa, and click GO.

+

Taxa 7

+

Updating is used when one wants to update a synonym with the accepted name. Prior to updating, the accepted taxon needs to be checked and the verified button checked. Then to update the synonym, click the check box of both taxa, and select Update taxa, and click GO. This functionality is currently being refined.

+

42.19 BIMS - Taxon groups

+

Here you manage the taxon groups added to the information systems. To note is the need to add the singular name so that it is correct in the Add XXXX data form.

+

Taxon groups 1

+

Taxon groups 2

+

Taxon groups 3

+

42.20 Flat pages

+

This is access outside of the BIMS section, in Flat Pages. From here you can update the “About us”, Citation guidelines and Help page.

+

Flat Pages 1

+

42.20.1 Flat pages - about us

+

Text for the About Us on the menu bar can be modified here: +https://freshwaterbiodiversity.org/admin/flatpages/flatpage/3/change/

+

42.20.2 Flat pages - citation guidelines

+

Flat Pages 2

+

Text for the Citation on the landing page can be modified here: +https://freshwaterbiodiversity.org/admin/flatpages/flatpage/3/change/

+

42.20.3 Flat pages - Help (FBIS only)

+

Text for the Help on the menu bar can be modified here: +https://freshwaterbiodiversity.org/admin/flatpages/flatpage/2/change/

+

Here's how to update the link to the FBIS manual:

+
    +
  • open this page https://freshwaterbiodiversity.org/admin/flatpages/flatpage/2/change/
  • +
  • double click the user manual + Flat Pages 3
  • +
  • open the Link tab, and change the url + Flat Pages 4
  • +
  • click Ok, and then click Save
  • +
+

Get the url for the FBIS Manual by opening Source References and right clicking the green title, and choose 'Copy link address'. Then insert this url into the URL in the Link tab and save.

+

42.21 People

+

42.21.1 People - Users

+

People 1

+

Details of all users are visible here and can be edited as needed. When a user first registers they are activated by clicking the Permission – Active box.

+

Several filters have been included to manage and find users

+

People 2

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/biodiversity-data/managing-source-references/index.html b/administrator/biodiversity-data/managing-source-references/index.html new file mode 100644 index 0000000..6e7f6c3 --- /dev/null +++ b/administrator/biodiversity-data/managing-source-references/index.html @@ -0,0 +1,1478 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+39. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

39. Managing Source references

+

A specific administration module has been developed to allow administrators to manage metadata and citations associated with each biological occurrence record.

+

Managing Source References 1

+

Only registered users with super user status are able to access Source References, typically the administrators.

+

All biodiversity data served need to have associated Metadata, which is visible in the metadata table in the dashboards. This metadata allows the users to establish exactly where the data originated from and to navigate to the study reference if desired.

+

Managing Source References 2

+

39.1 Types of source references

+

Multiple sources of taxon occurrence data generally exist, although this is highly dependent on the country. Potential sources of biodiversity data include the following source reference categories:

+
    +
  • Peer-reviewed scientific articles
  • +
  • Theses
  • +
  • Published reports
  • +
  • Databases
  • +
  • Unpublished data
  • +
+

The following sections provide details of the recommended processes for sourcing taxon occurrence data from the different reference categories. This is done by all users adding data and by administrators.

+

39.1.1 Peer-reviewed scientific article

+

Data from peer-reviewed scientific articles are best sourced by undertaking a literature search using Google Scholar. To ensure that relevant papers are identified, appropriate search term combination should be used. For example, for all native freshwater fishes in South Africa: “Genus species” & “South Africa” (where “Genus species” represents the scientific name for each taxon). It is important that search terms are clearly-defined and consistent, so that the process is repeatable and defensible.

+

39.1.2 Thesis

+

University theses are easily searched using relevant university search engines. Often local experts also know of relevant theses and can be contacted directly. Where possible, electronic data should be sourced directly from individuals, as this saves significant time that would otherwise be occupied in transcription of paper to digital records during data consolidation.

+

39.1.3 Published report

+

Technical and consultancy reports are often difficult to source and requires knowledge of local experts who have undertaken relevant studies. Where possible, electronic data should be sourced directly from individuals, as this saves significant time during data consolidation.

+

39.1.4 Database

+

Identify and contact relevant organisations who may have data to share that is already in a database. Data sharing agreements may be needed depending on the organisation. For organisation that regularly add data it is useful to set up a database in the organisation’s name.

+

39.1.5 Unpublished data

+

Identify individuals who may have data to share. Where possible, electronic data should be sourced directly from individuals, as this saves significant time during data consolidation.

+

Source reference system can store either an electronic document (e.g. by attaching a PDF to the document record) or a link to an online resource (URL). The order of preference should be:

+
    +
  1. Use DOI based citations wherever possible (in which case the URL attribute described below should not be needed).
  2. +
  3. Use documents with references to external resources (i.e. a URL that points to a published PDF on a web site).
  4. +
  5. Used documents with attached PDF as a last resort (this will require first uploading the document in the document management system and then providing the link to the uploaded document in the metadata table described below).
  6. +
+

39.2 Adding source references to occurrence data

+

Source references are either added when data are added using the data capture forms on FBIS, or when uploading occurrence data using the data upload excel file. (See Preparing and checking an Occurrence Data File before uploading).

+

39.2.1 Adding a source reference using data capture forms

+

When adding data, three data capture forms are shown in sequence, namely 1) an occurrence record form, where you capture which taxa were present; 2) an abiotic data form where you capture physico-chemical and other abiotic data; and 3) a source reference for records form, where you capture the source reference or metadata for the biological record.

+

Managing Source References 3

+

39.2.2 Peer-reviewed scientific articles

+

Select the reference category and insert the DOI or URL and click the search button. The citation is then retrieved via an online citation management system and inserted. Click Submit to save.

+

Managing Source References 4

+

39.2.3 Published reports and theses

+

Select the reference category and select from the dropdown list of titles, if the published report or thesis is already uploaded, or select “Upload new” to add a new published report or thesis.

+

Managing Source References 5

+

When uploading a new published report or thesis, complete the fields using the format indicated including Author(s), Year, Source, Title, Description (if desired) and Url or upload file. Confirm that you are owner of the document being added and Upload. This is then submitted.

+

Managing Source References 6

+

Managing Source References 7

+

39.2.4 Databases

+

Select the reference category and select from the dropdown list of databases, if the database is already created, or select “Add new” to add a new database.

+

Managing Source References 8

+

When adding a new database, complete the name and provide a description. Add the url if it exists and click create. Add notes if desired.

+

Managing Source References 9

+

39.2.5 Unpublished data

+

Select the reference category and select from the dropdown list under notes. If the unpublished dataset exists, select the unpublished dataset name, or if the unpublished dataset needs to be created, select “Add new” to add a new unpublished dataset. In the notes, add the name of the person, details of the study and date if possible or applicable.

+

Managing Source References 10

+

39.3 Adding a source reference using occurrence upload excel files

+

Where data are uploaded using the Data Upload Templates, the data capturer needs to specify the following:

+
    +
  • Author(s): Surname + Initials
  • +
  • Year: Year of study
  • +
  • Source: Details such as journal name, report, thesis, database and unpublished data.
  • +
  • Title: Title of the report. thesis, database or unpublished dataset.
  • +
  • Reference category: Select from dropdown options
  • +
  • URL: Thesis handle, or article link if no DOI available
  • +
  • DOI: DOI for reference ( e.g. 10.2989/16085914.2018.1491385) – the citation for articles with DOIs is done automatically.
  • +
  • Document Upload Link: Link to "Source Reference" page after uploading PDF or URL of published report or thesis.
  • +
+

When adding occurrence data using the upload excel files, the following columns are populated for each reference category:

+

39.3.1 Using Source References as an administrator

+

Errors can arise when source references are added to the information system by users. These can be picked up and fixed by undertaking various filters, checking and edits, including those listed below.

+
    +
  • Search for a reference type or category + Managing Source References 11
  • +
  • Search by author(s) + Managing Source References 12
  • +
  • Search using free text + Managing Source References 13
  • +
+

Once the source reference has been found, it can be updated, deleted (only if there are not records associated with it), and the Document ID can be copied. This is needed when uploading occurrence records using the excel template.

+

Managing Source References 14

+

By clicking on the records button you can check exactly which sites and data are linked to the source reference.

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/biodiversity-data/master-list-preparation/index.html b/administrator/biodiversity-data/master-list-preparation/index.html new file mode 100644 index 0000000..03bb3f6 --- /dev/null +++ b/administrator/biodiversity-data/master-list-preparation/index.html @@ -0,0 +1,1303 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+33. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

33. Preparing and checking a Master List of Taxa before uploading

+

A taxonomic Master List is a list of all species and/or taxa within a particular group such as birds, fish, invertebrates, wetland plants, algae, etc. This section highlights issues and specific checks to improve accuracy of the Master List. The format of the Master List is important to ensure consistency for ingestion of data into the information system. The columns included in the Master Lists are detailed in the Data Management Guidelines.

+
+

Only registered users with super user status are able to do this, typically the administrators.

+
+

33.1 Creating a Master List

+

A taxonomic Master List is a list of all species and/or taxa within a particular group such as birds, fish, invertebrates, wetland plants, algae, etc. For some groups a species list is easy to produce as species level is commonly identified in studies (e.g. birds, fish). For other groups, the taxonomic level (family, genus, species etc) varies considerably from study to study, and thus it is recommended that the lowest taxonomic level is used and that Taxon is used in preference to Species (e.g. invertebrates, algae).

+

The purpose of the Master List is threefold:

+
    +
  1. To provide a comprehensive and up to date list of species/taxa for a specific group in a specific region. This needs to be done during the initial development of an information system such as FBIS or FBIS, but once the system is up and running, then the further updating of the Taxonomic backbone is done using GBIF and user-defined taxonomic uploads.
  2. +
  3. To facilitate downloading of data from the Global Biodiversity Information Facility’s (GBIF), thereby ensuring that the correct taxa are included on the information system.
  4. +
  5. To provide the taxonomic hierarchy for taxa not yet on GBIF.
  6. +
+

The generation of a Master List requires consultation with available resources, relevant publications and experts. A Master List is intended to be an updatable resource, improved and added to as new data and studies are published, or new taxa are described. If no species lists are available for a country then the GBIF Taxonomic Master List may be generated by extracting data from GBIF. This Master List should then ideally be checked and validated for accuracy by the FBIS team.

+

The format of the Master List is important to ensure consistency for ingestion of data into the information system. The following columns are included in the Master Lists, provided as excel file template that will be used for each FBIS group (FBIS Master List of Taxa Template.xlsx). It is recommended that all columns be populated, with black compulsory and blue optional (explanations given in parenthesis):

+
    +
  • On GBIF (Yes or No if the taxon is on GBIF)
  • +
  • GBIF URL (link to GBIF taxon)
  • +
  • Country records (Yes, No, unknown – records in the country of interest)
  • +
  • Comments (Details such as other countries if unknown or No above)
  • +
  • Source (Details of the publication source for this taxon)
  • +
  • Taxon Rank
  • +
  • Kingdom
  • +
  • Phylum
  • +
  • Class
  • +
  • SubClass
  • +
  • Order
  • +
  • Family
  • +
  • SubFamily
  • +
  • Genus
  • +
  • Species
  • +
  • SubSpecies
  • +
  • Variety
  • +
  • Taxon
  • +
  • Scientific name and authority
  • +
  • Origin (Native, Non-native, Unknown)
  • +
  • Endemism (Endemism categories):
  • +
  • Micro-endemic level 2 (Endemic to a single river or wetland)
  • +
  • Micro-endemic level 1 (Endemic to less than 5 rivers or wetlands)
  • +
  • Regional endemic level 2 (Endemic to a single primary catchment)
  • +
  • Regional endemic level 1 (Endemic to a single Freshwater Ecoregion (e.g. CFE), more than one primary catchment)
  • +
  • National endemic (Endemic to South Africa, occurs in more than one Freshwater Ecoregion within SA)
  • +
  • Subregional endemic (Endemic to southern Africa)
  • +
  • Widespread (Occurs beyond southern Africa)
  • +
  • Unknown (Endemism is unknown)
  • +
  • Conservation status (Global) - The IUCN Red List of Threatened Species website (IUCN Red List, 2020)) classifies species into six main categories based on their extinction risk.
  • +
  • Extinct
  • +
  • Critically Endangered
  • +
  • Endangered
  • +
  • Vulnerable
  • +
  • Near Threatened
  • +
  • Least Concern
  • +
  • Data Deficient
  • +
  • Not Evaluated
  • +
  • Conservation status (Global) - This is the red list specific to South Africa based on SANBI’s categorisation and classification. See http://redlist.sanbi.org/ and http://redlist.sanbi.org/redcat.php
  • +
+

Master List Preparation 1 +* Common name +* Former scientific names

+

A separate Master List of Species/Taxa needs to be created for each group for which biodiversity data are served on FBIS. The Master List is ideally created before the consolidation of data so that the correct GBIF Taxonomic Backbone (https://www.gbif.org/dataset/d7dddbf4-2cf0-4f39-9b2a-bb099caae36c) is used for the data consolidation files. The taxonomy from GBIF should be used when the taxon is on GBIF. The FBIS team can check if the taxon is on GBIF using the following link: https://www.gbif.org/species/1 and insert the relevant species, genus, family etc. in the “Select a species” box.

+

Master List Preparation 2

+

Taxa that are not on GBIF may be included in a Master List but the Source (Details of the publication source for this taxon) needs to be provided. Unfortunately several taxa may be missing from GBIF which, while it is the best available, is not always 100% correct.

+

There is also another platform that is useful, the Freshwater Animal Diversity Assessment (FADA) Project (http://fada.biodiversity.be/). FADA is the taxonomic backbone for its Freshwater Biodiversity Data Portal. One is able to consult and download FADA data, although it is not always up to date.

+

Important notes and common errors:

+

It is important that the correct Taxon Rank is always used to ensure correct uploading of the data files. Taxon Rank is case sensitive so Species will upload but species will fail. Always ensure the correct Taxon Rank is applied by using the dropdown list. There should be no spaces in SubClass, SubOrder, SubFamily, SubSpecies.

+

The column On GBIF: If the taxon is on GBIF, this must be Yes, then it is not necessary to add the GBIF URL. However, it is recommended that the GBIF URL be added to ensure the correct taxon is added. However, if the taxon is not on GBIF, then this must be No. Always include the full taxonomic hierarchy for all taxa (Kingdom, Phylum, Class, Order, etc.).

+

Note: It is recommended that significant time and resources are used to generate and refine the master list for each group (birds, fish, invertebrates etc) as much as possible before proceeding with data collation. This is the list around-which all of the occurrence data will pivot: the more accurate it is at the start, the more time you save in the long run when collating the biodiversity data for those taxa.

+

33.2 Checking a Master List for accuracy

+

To ensure the Master list is accurate, several steps should be taken before uploading taxonomic data. After consolidating the master list, you should check the following:

+

Apply filters for checking the data by highlighting the header row, clicking Data, Filter. All columns should be checked for consistencies and typos. Systematically work from column A to W. In particular, check consistency of the Taxon Rank and taxonomic hierarchy (Kingdom, Phylum, Class, Order, Family, Genus, Species, SubSpecies, Taxon).

+

Master List Preparation 3

+

It is important to check the GBIF taxonomy for accepted names and synonyms. For example, in the avian master list, Ardea alba - is the accepted name, whereas Casmerodius albus is the synonym. Preferably only accepted names should be included in the Master List of Taxa.

+

Master List Preparation 4

+

Taxa should be checked for duplicates by highlighting the Taxon column, and from the Home Menu, selecting Conditional Formatting, Highlight Cells Rules, Duplicate Values.

+

Master List Preparation 5

+

GBIF URLs should also be checked for duplicates by highlighting the GBIF URL column, and from the Home Menu, selecting Conditional Formatting, Highlight Cells Rules, Duplicate Values.

+

Note: All taxa can be updated after ingestion through the Taxon Management section.

+

Delete blank rows and columns. Lastly, ensure that there are no extra blank rows or columns, by deleting them.

+

Master List Preparation 6

+

33.3 Adding additional attributes for a specific taxon group

+

It may be desirable to add attributes for specific taxon groups such as “Water dependence” (Highly dependent, Moderately dependent, Minimally dependent, Terrestrial). These additional attributes are assigned to each taxon during the uploading of the master lists as long as the additional attribute is added in Taxon Management before uploading.

+

This is done in the Edit Module form, Add attribute. The attribute needs to match the attribute column header in your Master List for uploading.

+

Master List Preparation 7

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/biodiversity-data/occurrence-data-preparation/index.html b/administrator/biodiversity-data/occurrence-data-preparation/index.html new file mode 100644 index 0000000..213ce2a --- /dev/null +++ b/administrator/biodiversity-data/occurrence-data-preparation/index.html @@ -0,0 +1,1512 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+37. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

37. Preparing and checking an Occurrence Data File before uploading

+

37.1 Extracting data and preparing bulk data for uploading into FBIS

+

FBIS includes data capture forms for adding sites, fish, invertebrate and algae data, as well as associated abiotic data. However, these forms are intended for the capture of individual site visits, and at times, especially during the development phase of an information system, it is useful to be able to upload large amounts of data at a time. To ensure that bulk data are readily uploaded into FBIS, a standardised Data Upload Template needs to be produced for each group. This will ensure that data are cleaned and provided in a standardised manner so that the data uploading process runs smoothly and so that the resultant FBIS platform serves quality data.

+

37.2 Data Upload Templates

+

Standardised data upload templates in excel have been generated for four biodiversity groups, namely anurans, fish, invertebrates and algae. Additional upload templates may be added as new biodiversity modules are added. These templates include a number of dropdown attributes. It is critical that all taxa in the Data Upload file for a particular biodiversity group are present in the Master List of Taxa for that group. If not, the upload process will not work. For this reason, it is recommended that where possible dropdown lists are used in the Data Upload files to ensure that all data entered in the sheet are valid. As an example, the Master List of fish species in South Africa has been included as dropdown list for the FBIS Fish Data Upload Template.

+

The following data upload templates are provided:

+
    +
  • FBIS Fish Data Upload Template.xlsx
  • +
  • FBIS Algae Data Upload Template.xlsx
  • +
  • FBIS Invertebrate Data Upload Template.xlsx
  • +
  • FBIS Anuran Data Upload Template.xlsx
  • +
+

Many of the columns are the same for each group, although some additional columns are included for algae, and the dropdown options (e.g. biotopes) sometimes vary amongst groups. The common columns used in each group are given in Table 1. Relevant dropdown lists are provided in each template and additional group-specific columns are included in the relevant templates. Those column headers in red have to be filled in the occurrence upload file. See section on Check the Source Reference for details of which columns are relevant for different reference categories. Those column headers shaded green use dropdown lists in the excel file. These can be modified in the Admin page (BIMS).

+

Table 1. Column headers with details used in data upload templates

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Column HeaderDetails
UUIDA unique identifier for each record. Drag and copy the formula down.
Original River or Wetland NameName given in study reference
Original Site CodeSite Code given in study reference
Site CodeLeave blank (autogenerated)
Site descriptionDescription given in study reference
Refined Geomorphological ZoneAs given in study reference (if available) - Select from dropdown options
LatitudeDecimal degrees with "-" in front & "," for decimal point
LongitudeDecimal degrees with "," for decimal point
Sampling Dateyyyy/mm/dd
KingdomNot necessary to fill in as they are derived from the Master Lists
PhylumNot necessary to fill in as they are derived from the Master Lists
ClassNot necessary to fill in as they are derived from the Master Lists
OrderNot necessary to fill in as they are derived from the Master Lists
FamilyNot necessary to fill in as they are derived from the Master Lists
GenusNot necessary to fill in as they are derived from the Master Lists
SpeciesNot necessary to fill in as they are derived from the Master Lists
Taxon
Taxon rankSelect from dropdown options
PresentFill in with "1"
Sampling methodSelect from dropdown options
Sampling effort measureSelect from dropdown options
Sampling effort value
Abundance measureSelect from dropdown options
Abundance valueLeave blank if only presence data
Record typeSelect from dropdown options
Broad biotopeSelect from dropdown options
Specific biotopeSelect from dropdown options
SubstratumSelect from dropdown options
Water LevelSelect from dropdown options
Water TurbiditySelect from dropdown options
EmbeddednessSelect from dropdown options
DepthDepth (m)
Near Bed VelocityNear Bed Velocity (m/s)
CONDConductivity (mS/cm)
PHPH
DOPERDissolved Oxygen (%)
DODissolved Oxygen (mg/L)
TEMPTemperature (deg C)
TURBTurbidity (NTU)
Collector/OwnerFull name
Collector/Owner InstituteInstitute of collector/owner
Author(s)Surname + Initials
YearYear of study
SourceSource of data if from thesis or database
TitleTitle of data source if thesis or published report
Reference categorySelect from dropdown options
URLThesis handle, or article link if no DOI available
DOIDOI for reference ( e.g. 10.2989/16085914.2018.1491385)
Document Upload LinkLink to "Documents" page on FIBbio after uploading PDF of published report
NotesAny details related to sampling, species, life form etc.
+

It is recommended that separate data upload files be created for each Source Reference, with each linked to a GitHub ticket. This ensures accurate management of data preparation and management.

+

37.3 Preparing and checking an Occurrence Data File

+

To ensure that data are accurate, several steps should be taken before uploading occurrence data. After consolidating the occurrence data in the data file, you should check the following:

+

Apply filters for checking the data by highlighting the header row, clicking Data, Filter

+

Occurrence Data Preparation 1

+

UUID: This is a unique id for each occurrence record. It needs to be copied and pasted so that the formula used to generate it is saved as a number.

+

The UUID formula is available here: +

=LOWER(CONCATENATE(DEC2HEX(RANDBETWEEN(0,POWER(16,8)),8),"-",DEC2HEX(RANDBETWEEN(0,POWER(16,4)),4),"-","4",
+DEC2HEX(RANDBETWEEN(0,POWER(16,3)),3),"-",DEC2HEX(RANDBETWEEN(8,11)),DEC2HEX(RANDBETWEEN(0,POWER(16,3)),3),
+"-",DEC2HEX(RANDBETWEEN(0,POWER(16,8)),8),DEC2HEX(RANDBETWEEN(0,POWER(16,4)),4)))
+
+

Systematically check each column using the dropdown arrows, and look for inconsistencies. Some common issues include, #num in UUID column instead of the UUID, incorrect spelling in the Site description column (e.g. Gakiriro wetland, Gakirirowetland), latitude with missing “-“ (e.g. 2.60059 as latitude is incorrect – should be -2.60059), longitude.

+

Also check that all sites fall within the country boundary so that Site Codes may be generated correctly and geocontext data harvested for each site.

+

Occurrence Data Preparation 2 +Occurrence Data Preparation 3

+

Check that the sampling date is in the correct format: yyyy/mm/dd. If the format is not correct then the upload will not work.

+

Check that all taxa are correct and are present in the Master List. If the dropdown of master taxa list was used then this should not be an issue. Check that the Taxon rank is correct. It is important that the correct Taxon Rank is always used to ensure correct uploading of the data files. Taxon Rank is case sensitive so Species will upload but species will fail. Always ensure the correct Taxon Rank is applied by using the dropdown list. There should be no spaces in SubClass, SubOrder, SubFamily, SubSpecies.

+

Occurrence Data Preparation 4

+

Check presence is all “1”, check sampling method is correct.

+

Occurrence Data Preparation 5 +Occurrence Data Preparation 6

+

Check Collector/Owner and Collector/Owner Institute. Ideally CAPITALS should not be used, First name Surname if known. Do not use middle initial and punctuation.

+

Occurrence Data Preparation 7

+

Check the Source Reference (Author(s), Year, Source, Title, Reference category, URL, DOI, Document Upload Link). For each study reference type, you need to populate the following columns:

+
    +
  • Peer-reviewed scientific article (Collector/Owner; Collector/Owner Institute; Author(s); Year; Source; Title; DOI or URL (if DOI is not available)). For Peer-reviewed scientific article the Source is the Journal, For Peer-reviewed scientific article the Title is the title of the article.
  • +
  • Published report (Collector/Owner; Collector/Owner Institute; Author(s); Year; Source; Title; URL or Document Upload Link). Note the Document Upload Link is obtained after the report is added.
  • +
  • Thesis (Collector/Owner; Collector/Owner Institute; Author(s); Year; Source; Title; URL or Document Upload Link)
  • +
  • Database (Collector/Owner; Collector/Owner Institute; Author(s); Year; Source)
  • +
  • Unpublished data (Collector/Owner; Collector/Owner Institute; Author(s); Year; Source)
  • +
+

Check format of Author(s). It needs to be: Surname + Initials, no punctuation. (e.g. Tumushimire L, Mindje M, Sinsch U & Dehling JM not Lambert Tumushimire, Mapendo MINDJE, Prof. Ulrich Sinsch & Julian Maxmillian Dehling). It is important to get the authors correct (e.g. Sinsch Ulrich and Dehling, J. Maximilian, Lümkemann Katrin, Rosar Katharina, Christiane Schwarz should be Sinsch U, Lümkemann K, Rosar K, Schwarz C & Dehling M as per the doi).

+

Occurrence Data Preparation 8

+

Check the Date: This is the publication date (so 2012-2013 should be 2019 as this is when the article was published - Ecology and Evolution. 2019. Same with all other data from this study).

+

Occurrence Data Preparation 9

+

Check the Source. Please note when to include source or not, and what to include. (e.g. Mindje, M., Tumushimire, L., & Sinsch, U. (2020). Diversity assessment of anurans in the Mugesera wetland (eastern Rwanda): impact of habitat disturbance and partial recovery. Salamandra, 56, 27-38. Should be Salamandra)

+
    +
  • For Peer-reviewed scientific articles - the Source is the Journal.
  • +
  • For Published Reports and Theses - the Source is the publisher of the Report.
  • +
  • For Unpublished Data - the source is the title of the study.
  • +
+

Occurrence Data Preparation 10

+

Check the Title. For Peer-reviewed scientific article the Title is the title of the article, for Published reports or theses, it is the title of the thesis. Unpublished data don’t need a title.

+

Occurrence Data Preparation 11

+

Check all Reference Categories are correct: options include:

+
    +
  • Database
  • +
  • Peer-reviewed scientific article
  • +
  • Published report
  • +
  • Thesis
  • +
  • Unpublished data
  • +
+

Occurrence Data Preparation 12

+

Check URL and DOI. Use a DOI if it is available, URL – only needed for Peer-reviewed scientific article if there is no DOI. For the DOI you only need to include the number part, so 10.1080/15627020.2012.11407524, not https://doi.org/10.1080/15627020.2012.11407524.

+

Occurrence Data Preparation 13 +Occurrence Data Preparation 14

+

Check the document upload link is correct. Note the Document Upload Link is obtained after the report is added. Reports are only uploaded when there is no DOI or URL to link the data to.

+

Checking for duplicate occurrence records. Use this formula for checking for duplicates. This is a combination of Site description, latitude, longitude, sampling date, Taxon, sampling method, author, year, source and title. Copy and paste the formula below into a new column at the end and name it “Duplicate check”.

+
=CONCATENATE(E2,G2,H2,I2,Q2,T2,W2,X2,Y2,Z2)
+
+

Then copy and paste the formula down to the end of the data rows. Then Highlight the column, and from the Home menu, select Conditional Formatting, Highlight Cells Rules, Duplicate Values.

+

Occurrence Data Preparation 15

+

Any duplicates will be highlighted. Check and delete duplicate occurrence records. Then delete the Duplicate Check column.

+

Delete blank rows and columns. Lastly, ensure that there are no extra blank rows or columns, by deleting them.

+

Occurrence Data Preparation 16

+

Occurrence Data Preparation 17

+

Remove the data filter, save the file in excel, and save the file as csv file.

+

Occurrence Data Preparation 18

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/biodiversity-data/occurrence-data-uploading/index.html b/administrator/biodiversity-data/occurrence-data-uploading/index.html new file mode 100644 index 0000000..1772394 --- /dev/null +++ b/administrator/biodiversity-data/occurrence-data-uploading/index.html @@ -0,0 +1,1213 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+38. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

38. Occurrence data uploading

+

38.1 Steps

+

Click on your profile and select Upload Occurrence Data

+

Occurrence Data Uploading 1

+

Select the Taxon Group using the dropdown and browse to the file containing the occurrence data for the taxon group, click upload

+

Occurrence Data Uploading 2

+
+

Note: The Excel file needs to be saved as a csv using the following option:

+
+

Occurrence Data Uploading 3

+

Progress is shown:

+

Occurrence Data Uploading 4

+

A Success file will indicate occurrence records uploaded to the system. An Error file will give details of occurrence records not uploaded. The last column in this csv file provides an indication of the reason the occurrence record was not uploaded. The administrator then needs to check the data and correct before uploading again.

+

Common errors:

+
    +
  • Taxon not in Master list
  • +
  • Taxon Rank incorrect
  • +
+

Occurrence records may be updated by uploaded corrected records in the csv file. As long as the UUID is the same then the old occurrence record will be updated.

+

New occurrence records may be added by repeating the steps from (4), to upload the additional occurrence records for the Taxon Group.

+

Note that once the occurrence data has been uploaded, geocontext data (i.e. information about the site such as province, catchment etc.) are automatically populated for each site. This takes time and it is recommended that the next step (i.e. harvesting from GBIF), is done at least 24 hours after uploading occurrence data.

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/biodiversity-data/physico-chemical-data/index.html b/administrator/biodiversity-data/physico-chemical-data/index.html new file mode 100644 index 0000000..3734766 --- /dev/null +++ b/administrator/biodiversity-data/physico-chemical-data/index.html @@ -0,0 +1,1727 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+41. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

41. Adding physico-chemical data

+

This section explains how an administrator or user adds physico-chemical data to a site or prepares an excel template for bulk uploading of physico-chemical data for multiple sites and or sampling dates. In either case it is important to note that physico-chemical data can only be added for a specific variable, if that variable already exists in the Admin/Bims/Chemistry units table. If the variable is missing from this table, it will not show in the list and the upload will fail. This is described in detail in a separate document: 11. Managing BIMS Admin tables

+

41.1 Adding physico-chemical data to a single site

+

A data capture form has been added for uploading physico-chemical data to a single site. The user needs to follow the following steps:

+
    +
  • Select the Date
  • +
  • Select the Owner
  • +
  • Select Source Reference by using search filter and selecting.
  • +
  • Add specific variables by checking the Measured box and adding the value of each variable. Note all units have been standardised and users need to convert to these standard unit before capturing the data. Minimum and maximum values have also been included for data integrity checks.
  • +
  • Click “I agree to these data being shared via the RBIS platform for visualisation and download by registered FBIS/RBIS users” and Submit.
  • +
+

Adding physico-chemical data.

+

Physico-chemical Data 1

+

41.2 Preparing and checking a physico-chemical data file before uploading

+

A physico-chemical template has been created for uploading physico-chemical records for multiple sites and sampling dates. Each line represents a unique Site-Sampling date. The template provided includes the full list of variables currently in the FBIS system, however these can be modified for the needs of the RBIS.

+

Here is the full list of columns included in the physico-chemical template. It resembles the occurrence data upload template for the more generic column headers.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
UUID
Original Wetland Name
Original Site Code
Site Code
Site description
Latitude
Longitude
Sampling Date
Collector/Owner
Collector/Owner Institute
Author(s)
Year
Source
Title
Reference category
URL
DOI
Document Upload Link
Notes
+

Proceeding this is each variable (with the header as the Chem code), each in a separate column. Here is the master list of physico-chemical variables currently in FBIS, giving the Chem code, description and unit of measurement.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Chem codeChem descriptionUnit
ALAluminiummg/l
ASArsenicmg/l
BBoronmg/l
BABariummg/l
BEBerylliummg/l
BODBiological Oxygen Demandmg/l (5 days)
CACalciummg/l
CACO3Total hardnessmg/l
CDCadmiummg/l
CLChloridemg/l
COCoboltmg/l
CO3Carbonatemg/l
CODChemical Oxygen Demandmg/l
COLColourAPHA units
CONDConductivitymS/m
CRChromiummg/l
CUCoppermg/l
DINNitrogen: dissolved inorganic (NH4+NO3+NO2)-Nmg/l
DOOxygen: dissolvedmg/l
DOCCarbon: dissolved organicmg/l
DONNitrogen: dissolved organicmg/l
DOPEROxygen: dissolved: percentage saturation%
ECOLIColiforms: Escherichia coli (E. coli)Cfu/100ml
FFluoridemg/l
FAECAL CColiforms: Total faecal colifomsCfu/100ml
FEIronmg/l
HCO3Bicarbonatemg/l
HGMercurymg/l
KPotassiummg/l
KJNNitrogen: kjeldahlmg/l
MGMagnesiummg/l
MNManganesemg/l
MOMolybdenummg/l
NASodiummg/l
NH3-NNitrogen: ammoniamg/l
NH4-NNitrogen: ammoniummg/l
NINickelmg/l
NO2-NNitrogen: nitritemg/l
NO2+NO3-NNitrogen: Nitrate + nitritemg/l
NO3-NNitrogen: nitratemg/l
PBLeadmg/l
pHpH
PHALKAlkalinity: phenolthaleinmeq/l
PHENPhenolsmg/l
PO4-PPhosphorus: orthophosphatemg/l
POMParticulate organic mattermg/l
SALINITYSalinity%
SDSecchi depthm
SIO2Silicamg/l
SIO4Orthosilicatemg/l
SO4Sulphatemg/l
SRStrontiummg/l
SRPPhosphorus: soluble reactivemg/l
TALAlkalinity: totalmeq/l
TDSTotal dissolved solidsmg/l
TEMPTemperaturedeg C
TITitaniummg/l
TICCarbon: total inorganicmg/l
TINNitrogen: total inorganicmg/l
TOCCarbon: total organicmg/l
TORGSTotal suspended solids: organicsmg/l
TORGS%Total suspended solids: organic fraction (%)%
TOT-NNitrogen: totalmg/l
TOT-PPhosphorus: totalmg/l
TSSTotal suspended solidsmg/l
TURBTurbidityNTU
VVanadiummg/l
ZNZincmg/l
ZRZirconiummg/l
+

The data is added to the physico-chemical template and checked for accuracy in the same way that biodiversity occurrence data are checked prior to uploading. To ensure that data are accurate, several steps should be taken before uploading physico-chemical data. After consolidating the physico-chemical data in the data file, you should check the following:

+

Apply filters for checking the data by highlighting the header row, clicking Data, Filter

+

Physico-chemical Data 2

+

UUID. This is a unique if for each occurrence record. It needs to be copied and pasted so that the formula used to generate it is saved as a number. See below for guidance. https://docs.rbis.kartoza.com/batch-importing-taxon-occurrence-data-bims/dealing-unique-identifiers/

+

The UUID formula is available here:

+
=LOWER(CONCATENATE(DEC2HEX(RANDBETWEEN(0,POWER(16,8)),8),"-",DEC2HEX(RANDBETWEEN(0,POWER(16,4)),4),"-","4",
+DEC2HEX(RANDBETWEEN(0,POWER(16,3)),3),"-",DEC2HEX(RANDBETWEEN(8,11)),DEC2HEX(RANDBETWEEN(0,POWER(16,3)),3),
+"-",DEC2HEX(RANDBETWEEN(0,POWER(16,8)),8),DEC2HEX(RANDBETWEEN(0,POWER(16,4)),4)))
+
+

Systematically check each column using the dropdown arrows, and look for inconsistencies. Some common issues include, #num in UUID column instead of the UUID, incorrect spelling in the Site description column (e.g. Gakiriro wetland, Gakirirowetland), latitude with missing “-“ (e.g. 2.60059 as latitude is incorrect – should be -2.60059), longitude.

+

Also check that all sites fall within the country boundary so that Site Codes may be generated correctly and geocontext data harvested for each site.

+

Physico-chemical Data 3 +Physico-chemical Data 4

+

Check Sampling date is in the correct format : yyyy/mm/dd

+

Check that all Chem codes are correct and are present in the Chemistry units table. New variables can be added. See Managing BIMS Admin tables – Chemistry tables.

+

Physico-chemical Data 5

+

Check that all variables have been converted to their correct unit of measurement.

+

Check Collector/Owner and Collector/Owner Institute. Ideally CAPITALS should not be used, First name Surname if known. Do not use middle initial and punctuation.

+

Physico-chemical Data 6

+

Check the metadata (Author(s), Year, Source, Title, Reference category, URL, DOI, Document Upload Link). For each study reference type, you need to populate the following columns:

+
    +
  • Peer-reviewed scientific article (Collector/Owner; Collector/Owner Institute; Author(s); Year; Source; Title; DOI or URL (if DOI is not available)). For Peer-reviewed scientific article the Source is the Journal, For Peer-reviewed scientific article the Title is the title of the article.
  • +
  • Published report (Collector/Owner; Collector/Owner Institute; Author(s); Year; Source; Title; URL or Document Upload Link). Note the Document Upload Link is obtained after the report is added.
  • +
  • Thesis (Collector/Owner; Collector/Owner Institute; Author(s); Year; Source; Title; URL or Document Upload Link)
  • +
  • Database (Collector/Owner; Collector/Owner Institute; Author(s); Year; Source)
  • +
  • Unpublished data (Collector/Owner; Collector/Owner Institute; Author(s); Year; Source)
  • +
+

Check format of Author(s). It needs to be: Surname + Initials, no punctuation. (e.g. Tumushimire L, Mindje M, Sinsch U & Dehling JM not Lambert Tumushimire, Mapendo MINDJE, Prof. Ulrich Sinsch & Julian Maxmillian Dehling). It is important to get the authors correct (e.g. Sinsch Ulrich and Dehling, J. Maximilian, Lümkemann Katrin, Rosar Katharina, Christiane Schwarz should be Sinsch U, Lümkemann K, Rosar K, Schwarz C & Dehling M as per the doi).

+

Physico-chemical Data 7

+

Check the Date: This is the publication date (so 2012-2013 should be 2019 as this is when the article was published - Ecology and Evolution. 2019. Same with all other data from this study).

+

Physico-chemical Data 8

+

Check the Source. Please note when to include source or not, and what to include. (e.g. Mindje, M., Tumushimire, L., & Sinsch, U. (2020). Diversity assessment of anurans in the Mugesera wetland (eastern Rwanda): impact of habitat disturbance and partial recovery. Salamandra, 56, 27-38. Should be Salamandra)

+
    +
  • For Peer-reviewed scientific articles - the Source is the Journal.
  • +
  • For Published Reports and Theses - the Source is the publisher of the Report.
  • +
  • For Unpublished Data - the source is the title of the study.
  • +
+

Physico-chemical Data 9

+

Check the Title. For Peer-reviewed scientific article the Title is the title of the article, for Published reports or theses, it is the title of the thesis. Unpublished data don’t need a title.

+

Physico-chemical Data 10

+

Check all Reference Categories are correct: options include:

+
    +
  • Database
  • +
  • Peer-reviewed scientific article
  • +
  • Published report
  • +
  • Thesis
  • +
  • Unpublished data
  • +
+

Physico-chemical Data 11

+

Check URL and DOI. Use a DOI if it is available, URL – only needed for Peer-reviewed scientific article if there is no DOI. For the DOI you only need to include the number part, so 10.1080/15627020.2012.11407524, not https://doi.org/10.1080/15627020.2012.11407524.

+

Physico-chemical Data 12 +Physico-chemical Data 13

+

Check the document upload link is correct. Note the Document Upload Link is obtained after the report is added. Reports are only uploaded when there is no DOI or URL to link the data to.

+

Checking for duplicate occurrence records. Use this formula for checking for duplicates. This is a combination of Site description, latitude, longitude, sampling date, Chem code, author, year, source and title. Copy and paste the formula below into a new column at the end and name it “Duplicate check”.

+
=CONCATENATE(E2,G2,H2,I2,Q2,T2,W2,X2,Y2,Z2)
+
+

Then copy and paste the formula down to the end of the data rows. Then Highlight the column, and from the Home menu, select Conditional Formatting, Highlight Cells Rules, Duplicate Values.

+

Physico-chemical Data 14

+

Any duplicates will be highlighted. Check and delete duplicate occurrence records. Then delete the Duplicate Check column.

+

Delete blank rows and columns. Lastly, ensure that there are no extra blank rows or columns, by deleting them.

+

Physico-chemical Data 15

+

Physico-chemical Data 16

+

Remove the data filter, save the file in excel, and save the file as csv file.

+

Physico-chemical Data 17

+

41.3 Uploading a physico-chemical data file

+

Go to Profile – Upload Physico-chemical data

+

Physico-chemical Data 18

+

This opens the Upload Physical Chemical Data form. Browse to the correct file and click upload.

+

Physico-chemical Data 19

+

On completion the following success file is shown.

+

Physico-chemical Data 20

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/biodiversity-data/site-biodiversity-data/index.html b/administrator/biodiversity-data/site-biodiversity-data/index.html new file mode 100644 index 0000000..469911c --- /dev/null +++ b/administrator/biodiversity-data/site-biodiversity-data/index.html @@ -0,0 +1,1232 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+40. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

40. Adding a site and biodiversity data

+

This section explains how an administrator or user adds a site and data to a site.

+

40.1 Adding a site

+

An administrator or user can add a new site using the Add Site button on the menu bar.

+

Site Biodiversity Data 1

+

This opens the Add a Location Site form:

+

Site Biodiversity Data 2

+

The user then adds the latitude and longitude by inserting the co-ordinates or clicking on correct location on the map, click Generate Site Code. This is automated and includes the Catchment + Province ID +District ID + Site count.

+

Site Biodiversity Data 3

+

An original site code can also be added if this was included in the source reference, as well as a description of the site. The owner is specified using the dropdown if the logged in user is not the owner. Site images can be added. Lastly, the user agrees to these data being shared via the RBIS platform for visualisation and download by registered RBIS users, and click Add. The new site is thus created.

+

40.2 Adding new biodiversity records

+

New occurrence data can be added from both the site form and by using the + Add on the side panel.

+

Site Biodiversity Data 4

+

Site Biodiversity Data 5

+

Clicking Add on either, opens the data capture form for a specific biodiversity module. The administrator or user needs to add the Date, specify the owner, and select the broad biotope, specific biotope, substratum, sampling method, sampling effort and record type using the relevant dropdowns. Note that only options specified in the Administrations tables are available for selection here (see separate documentation on Managing BIMS Admin tables). If this information is not available then it is left blank. A site image can be added.

+

Site Biodiversity Data 6

+

Occurrence data is then added. The taxa included in the form include all taxa recorded within a 25km radius of the site as a default. The user then needs to check the box, and add a number recorded. If abundance has not been recorded then this is left blank. The user can add abundance as number, percentage abundance and density (m2) by changing the selection in the Abundance dropdown.

+

Site Biodiversity Data 7

+

If the species observed is not shown in the default list, then the user can click Add Taxon, which links to the master list for the taxon group, or Add New Taxon, which open GBIF and allows the administrator or user to select a species in GBIF. After completion of the data, the user agrees to these data being shared via the RBIS platform for visualisation and download by registered RBIS users, and clicks Next, and Submit.

+

Site Biodiversity Data 8

+

This opens the Abiotic form, which is populated using the dropdowns, check boxes and value fields. If no abiotic or physico-chemical data have been recorded then these fields are left blank. Units for measurement are specified for each and the user needs to convert their physico-chemical data to the correct unit before adding values. After completion of the data, the user agrees to these data being shared via the RBIS platform for visualisation and download by registered RBIS users, and clicks Next, and Submit.

+

Site Biodiversity Data 9

+

The last form is for adding the Source Reference

+

Site Biodiversity Data 10

+

Then confirm Submit

+

Site Biodiversity Data 11

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/biodiversity-data/taxa-management/index.html b/administrator/biodiversity-data/taxa-management/index.html new file mode 100644 index 0000000..8b8b8f1 --- /dev/null +++ b/administrator/biodiversity-data/taxa-management/index.html @@ -0,0 +1,1476 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+36. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

36. Managing taxa in Taxon Management

+

A specific administration module has been developed to allow administrators to manage taxa within the information system. The taxa shown in Taxon Management are those taxa that have been uploaded via the “Upload Taxonomic Data”.

+

Taxa Management 1

+

Only registered users with super user status are able to access Taxon Administration, typically the administrators .

+

36.1 Taxon Management allows you to do the following

+
    +
  • Updating the Taxon Group Name and logo
  • +
  • Searching for a specific taxon
  • +
  • Sorting taxa
  • +
  • Filtering taxa
  • +
  • Checking and/or changing a taxon’s origin, endemism, conservation status and common name
  • +
  • Checking the GBIF link
  • +
  • Checking the IUCN link
  • +
  • Adding a new taxon
  • +
  • Removing a taxon from the taxon group
  • +
  • Viewing records associated with the taxon
  • +
  • Downloading all taxa in a group as a CSV file
  • +
  • Adding images of a taxon
  • +
  • Adding additional attributes specific to a taxon group
  • +
+

36.1.1 Updating the Taxon Group Name and logo – Edit Module

+

The name of the Taxon Group and logo can be updated easily by highlighting the group, and clicking “Edit”, then typing the new name in “Label”, and browsing to the correct logo.

+

Taxa Management 2

+

Taxa Management 3

+

36.1.2 Searching for a specific taxon

+
    +
  • Search for a specific taxon within a taxon group.
  • +
+

Taxa Management 4

+

The taxon is then shown: +Taxa Management 5

+

36.1.3 Sorting taxa

+
    +
  • Taxa can be sorted using up ↑↓ arrow, by each of the headers given below.
  • +
+

Taxa Management 6

+

36.1.4 Filtering taxa

+
    +
  • Filter for specific taxa – by Taxonomic Rank, Conservation Status, Origin and/or Endemism category. The number of taxa returned is shown.
  • +
+

Taxa Management 7

+

36.1.5 Checking and/or changing a taxon’s origin, endemism, conservation status and common name

+

Click “Edit” to open up a pop up, which allows you to edit the details of a taxon.

+

Taxa Management 8

+

Several fields (indicated with a red arrow) can be edited and changed if they are incorrect including, GBIF Key, Scientific Name, Canonical Name, Legacy Canonical Name, Taxonomic Rank, Vernacular or common name, Taxonomic status, Parent taxon, National Conservation Status (SANBI Red Listing), Global Conservation Status (IUCN Red Listing), Endemism and Origin. Most of these are auto-populated when a taxon is uploaded using the Master List or added as a new Taxon in Taxon Management.

+

Taxa Management 9

+ +

Click the “GBIF” to link to the species on GBIF:

+

Taxa Management 10

+

Taxa Management 11

+ +

Click the “GBIF” to link to the species on GBIF:

+

Taxa Management 12

+

36.1.8 Adding a new Taxon

+

If a new taxon needs to be added to the group, click the “Add a Taxon” button, type in the species name, and click “Find”.

+

Taxa Management 13

+

If the Taxon is on GBIF it will provide the link to the GBIF taxonomic backbone, then click “Add” to confirm the addition of the new taxon to the taxon group.

+

Taxa Management 14

+

If the taxon is not on GBIF, the administrator may add the new taxon, after which they must assign it to the appropriate Family and indicate the taxonomic rank. Note only genus and or species may be added.

+

Taxa Management 15

+

Then edit details of the taxon by following the 36.1.5 Checking and/or changing a taxon’s origin, endemism, conservation status and common name process.

+

36.1.9 Removing a taxon from the taxon group

+

This needs to be used with caution. If data are associated with the taxon, then you will not be able to delete the taxon.

+

Taxa Management 16

+

36.1.10 Viewing records associated with the taxon

+

Click on the magnifying glass symbol, to return the records associated with a specific taxon.

+

Taxa Management 17

+

Taxa Management 18

+

36.1.11 Downloading all taxa in a group as a CSV file

+

Click on the CSV button to download the CSV file of all taxa within a taxon group, or the subset of taxa selected using the filters.

+

Taxa Management 19

+

These can then be viewed in excel.

+

Taxa Management 20

+

36.1.12 Adding images of a taxon

+

By default images of a taxon are harvested from GBIF is they exists. In some instances an administrator may want to add images of a taxon themselves. To do this:

+
    +
  • Open Taxon Management
  • +
  • Select the Taxon Group
  • +
  • Select the Taxon and click Edit + Taxa Management 21
  • +
  • Go to the bottom of the “Change Taxonomy” form and add an image by browsing to the file. This image will then replace any GBIF image. Several images may be added for a taxon if desired.
  • +
  • Click “Save”.
  • +
+

Taxa Management 22

+

36.1.13 Adding additional attributes specific to a taxon group

+

It may be desirable to add attributes for specific taxon groups such as “Water dependence” (Highly dependent, Moderately dependent, Minimally dependent, Terrestrial). These additional attributes are assigned to each taxon during the uploading of the master lists as long as the additional attribute is added in Taxon Management before uploading. +This is done in the Edit Module form, Add attribute. The attribute needs to match the attribute column header in your Master List for uploading.

+

Taxa Management 23

+

You can add taxon specific attributes to a taxon group by adding additional column to the Master list and uploading , or individually by adding to the “Change Taxonomy” form:

+
    +
  • Open Taxon Management
  • +
  • Select the Taxon Group
  • +
  • Select the Taxon and click Edit
  • +
+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/biodiversity-data/taxon-group-uploading/index.html b/administrator/biodiversity-data/taxon-group-uploading/index.html new file mode 100644 index 0000000..b925881 --- /dev/null +++ b/administrator/biodiversity-data/taxon-group-uploading/index.html @@ -0,0 +1,1215 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+34. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

34. Uploading a new Taxon Group (Module) and adding a Master List of Taxa for the Taxon Group

+

Only registered users with super user status are able to do this, typically the administrators.

+

34.1 Steps

+

Click on your name and select Upload Taxonomic Data

+

Taxon Group Upload 1

+

Click Add new – to add a new Taxon Group

+

Taxon Group Upload 2

+

Add the new taxon group by adding the Taxon Group name and selecting the logo using the “Browse”

+

Taxon Group Upload 3

+

Select the new Taxon Group using the dropdown and browse to the file containing the Master List of Taxa for the Taxon Group, click upload.

+

Taxon Group Upload 4

+
+

Note: The Excel file needs to be saved as a csv using the following option:

+
+

Taxon Group Upload 5

+

Progress is shown:

+

Taxon Group Upload 6

+

A Success File will indicate taxa uploaded to the system. An Error file will give details of taxa not uploaded. The last column in this csv file provides an indication of the reason the taxon was not uploaded. The administrator then needs to check the data and correct before uploading again.

+

Taxon Group Upload 7

+

Once the Master List of Taxa has been added it can be viewed in the Taxon Management section. +An Error File provides details of the problem in the last column of the csv. Once these have been corrected, the file can be uploaded again.

+

Taxon Group Upload 8

+

New taxa may be added individually using the Taxon Management, or if there are multiple new taxa to be added, then the steps can be repeated, to upload the additional new taxa for the Taxon Group.

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/biodiversity-data/validate-records/index.html b/administrator/biodiversity-data/validate-records/index.html new file mode 100644 index 0000000..d6f9f89 --- /dev/null +++ b/administrator/biodiversity-data/validate-records/index.html @@ -0,0 +1,1252 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+43. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

43. Validating records (occurrence data) and new taxa

+

This section explains the process when a user adds data to RBIS, and how the administrator views, checks and validates the occurrence record or new taxon.

+

Data served on the platform includes both validated and unvalidated data, where validated implies some degree of checking that the record is accurate. The user is able to select one or the other using the filter:

+

Validate Records 1

+

All data added to platform by administrators using the Upload Occurrence data template, is given the status of validated on the assumption that the administrator has checked the data prior to uploading.

+

However, when a user adds data directly to the platform, this data remains unvalidated until the administrator checks the data.

+

43.1 Validating new biodiversity occurrence records

+

When a user adds new occurrence data, the data is automatically assigned an unvalidated status. The administrator is sent an email alerting them to the new record.

+

Validate Records 2

+

This unvalidated record is also added to the Validate Records form, which the administrator has access to.

+

Validate Records 3

+

This form includes functionality to See Unvalidated data, and filter by Owner, Site Code, Source Collection or Module. The administrator can then undertake the following actions, using these buttons

+

Validate Records 4

+

Validate Records 5

+

43.2 In summary

+

Viewing: the data is viewed by the administrator and checked for accuracy in terms of all entries including the taxa recorded. If a taxon is outside of its expected geographical range, then the administrator would reject the data with a reason to the person who uploaded the data.

+

Reject: the data is rejected and the user receives an email notification with the reason. The user then has the opportunity to edit their data and resubmit for validation.

+

Validate: the data is validated by the administrator if everything is correct.

+

Delete: this is only used when data have been accidentally added to a site but is generally easier done via the data forms.

+

43.3 Validating a new taxon

+

Generally a user should not need to add a new taxon often as the master lists for each biodiversity module are updated and represent the full expected checklist of species for a country. However, in the event that the user records a new taxon not currently in the master list, they are able to add this taxon to the information system. This new taxon then goes through a validation process by the administrator, and the new taxon is either accepted or rejected (with reasons).

+

The administrator receives a message alerting them to a new taxon that has been added. They then follow the link and validate the taxon, then accepting or rejecting it with reasons, which are provided by email to the user who uploaded the new taxon.

+

Validate Records 6

+

Follow the link to Taxon Management:

+

Validate Records 7

+

Check the taxon, and if it is acceptable to add to the Master List, then click Validate. Note the administrators may need to seek expert taxonomic input. The user receives an email indicating that the data has been approved.

+

If it is not acceptable, the Reject the taxon. An email will be sent to the user who uploaded the records, with reasons for the rejection.

+

Note: A new occurrence record (site visit) cannot be validated if the new taxon has not been validated. On Validate records it is shown as an Unvalidated taxon. First the administrator must validate the taxon by following the link in the email, or by clicking on the Validate Taxon button below. The taxon is then either validated or rejected. Once the new taxon has been validated, then the record can be validated.
+Before the taxon is validated:

+

Validate Records 8

+

After the taxon is validated:

+

Validate Records 9

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/customisation/add-inline-images/index.html b/administrator/customisation/add-inline-images/index.html new file mode 100644 index 0000000..784b4e3 --- /dev/null +++ b/administrator/customisation/add-inline-images/index.html @@ -0,0 +1,1212 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+59. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

59. Adding Inline Images on the Landing Page

+

This guide will help you display images inline, just like the one below:

+

Inline image

+
    +
  • +

    Start by navigating to the section editor on the landing page. Once there, create a new section.

    +
  • +
  • +

    To facilitate the upcoming steps, switch the editor to full-screen mode. Click on 'maximize' to do this.

    +
  • +
+

Inline image2

+
    +
  • Next, click on the 'Table' button.
  • +
+

Inline image2

+
    +
  • For this example, we want to showcase three inline images, each with its title underneath. To do this, create a table with 3 columns and 2 rows. Ensure the border width is set to 0.
  • +
+

Inline image2

+
    +
  • Start with the titles so you can easily add images later. Click on the 2nd row and input the corresponding text.
  • +
+

Inline image3

+

To switch to the next column, simply press the 'Tab' key on your keyboard.

+
    +
  • To centralize the text and images in the table, select all contents by pressing Ctrl+A (Cmd+A for Mac). Then, click the 'center alignment' option.
  • +
+

Inline image4

+
    +
  • Now, let's add the images. Click on the first row and select the 'Image' icon.
  • +
+

Inline image5

+
    +
  • Navigate to the 'Upload' tab, choose the desired image file, then click on 'Send it to the Server'.
  • +
+

Inline image6

+
    +
  • Once the image is uploaded, the 'Image Info' tab will open. Set the image width to 300 (to avoid the image taking up the whole screen) and the HSpace (horizontal padding) to 10.
  • +
+

Inline image6

+
    +
  • Follow the same steps for the other two columns. Your table should look something like this:
  • +
+

Inline image7

+
    +
  • +

    Click on 'Maximize' once more to exit the full-screen mode. Click 'Save' to preserve your changes.

    +
  • +
  • +

    Verify that the newly created landing page section has been added to the current theme. This will ensure your changes are visible on the landing page.

    +
  • +
+

Inline image7

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/customisation/adding-landing-page-section/index.html b/administrator/customisation/adding-landing-page-section/index.html new file mode 100644 index 0000000..887273a --- /dev/null +++ b/administrator/customisation/adding-landing-page-section/index.html @@ -0,0 +1,1210 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+57. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

57. Adding a Landing Page Section

+

This guide will help you in adding a new section to your landing page.

+

section 1

+
    +
  • Navigate to Bims Theme in Admin
  • +
+

section 2

+
    +
  • Ensure that there is at least one custom theme enabled. To check this, proceed to 'Custom Theme' and see if a record is present and enabled. If not, you can create a new one.
  • +
+

section 3

+
    +
  • Let's create a new landing page section. Navigate to 'Landing page sections', and click 'Add new section'.
  • +
+

section 4

+
    +
  • +

    (1) Name the new section (note that this name will not appear on the landing page).

    +

    (2) Optionally, add a title that will be displayed on the landing page.

    +

    (3) Set the background color for the section.

    +
  • +
+

section 4

+
    +
  • +

    Click 'Save and continue editing'. This will allow you to add content to the section afterwards.

    +
  • +
  • +

    If you have previously created landing page section content, you can select it in the content field. If not, you can add a new one by clicking the plus button.

    +
  • +
  • +

    Once you have finished editing the new content, click 'Save'. Remember, you can always update this later.

    +
  • +
+

section 4

+
    +
  • Be sure to select at least one content here.
  • +
+

section 5

+
    +
  • +

    Click 'Save'. The next step is to add this section to your theme. Navigate to 'Custom Themes' and select the enabled theme.

    +
  • +
  • +

    Scroll to 'Landing page sections' and select your new section. If you want to select more than one section, hold down the Control key (or Command on a Mac).

    +
  • +
+

section 6

+
    +
  • Finally, click 'Save'. Your new landing page section should now be visible.
  • +
+

section 7

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/customisation/embed-video-on-landing-page/index.html b/administrator/customisation/embed-video-on-landing-page/index.html new file mode 100644 index 0000000..755dd8c --- /dev/null +++ b/administrator/customisation/embed-video-on-landing-page/index.html @@ -0,0 +1,1194 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+58. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

58. Embedding Youtube Video on the Landing Page

+
    +
  • First, select the YouTube video you wish to show on the landing page
  • +
  • Click the 'Share' button under the video
  • +
+

Youtube share

+
    +
  • In the popup, click the 'Embed' button
  • +
+

Youtube embed

+

Click the 'Copy' button on the bottom right. This action copies the video's embed code to your clipboard

+

Youtube popup

+
    +
  • Now, navigate to the admin page and open the landing page section editor
  • +
+

Admin page

+
    +
  • Click on 'Source'
  • +
+

Admin page-2

+
    +
  • Paste the copied embed code into the 'Source' editor using Ctrl+V (or Cmd+V for Mac)
  • +
+

Admin page-3

+
    +
  • Click 'Source' again. You should now see an iframe containing the video player
  • +
+

Admin page-4

+
    +
  • Once the landing page content is added to the current theme, your video will appear on your landing page like this
  • +
+

Admin page-5

+
    +
  • To adjust the video size, double-click the iframe. A popup will appear where you can edit the width and height of the video player. Click 'OK' when done, and then 'Save'
  • +
+

Admin page-6

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 1.09.22 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 1.09.22 PM.png new file mode 100644 index 0000000..d53b81c Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 1.09.22 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 1.12.26 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 1.12.26 PM.png new file mode 100644 index 0000000..8f5da23 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 1.12.26 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 1.13.49 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 1.13.49 PM.png new file mode 100644 index 0000000..d3033e9 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 1.13.49 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 1.16.52 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 1.16.52 PM.png new file mode 100644 index 0000000..d04daf9 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 1.16.52 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 1.20.04 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 1.20.04 PM.png new file mode 100644 index 0000000..43f0dab Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 1.20.04 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 1.21.52 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 1.21.52 PM.png new file mode 100644 index 0000000..1aeeb7d Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 1.21.52 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 1.23.51 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 1.23.51 PM.png new file mode 100644 index 0000000..820b1f1 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 1.23.51 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 1.25.14 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 1.25.14 PM.png new file mode 100644 index 0000000..efbefe1 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 1.25.14 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 1.53.56 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 1.53.56 PM.png new file mode 100644 index 0000000..7cdfd52 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 1.53.56 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 1.55.51 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 1.55.51 PM.png new file mode 100644 index 0000000..ca95a57 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 1.55.51 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 1.57.12 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 1.57.12 PM.png new file mode 100644 index 0000000..4e4b9e9 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 1.57.12 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 1.58.58 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 1.58.58 PM.png new file mode 100644 index 0000000..4f852a5 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 1.58.58 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 11.31.11 AM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 11.31.11 AM.png new file mode 100644 index 0000000..97f3f5b Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 11.31.11 AM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 11.32.38 AM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 11.32.38 AM.png new file mode 100644 index 0000000..377f18d Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 11.32.38 AM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 11.34.25 AM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 11.34.25 AM.png new file mode 100644 index 0000000..716999f Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 11.34.25 AM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 11.36.20 AM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 11.36.20 AM.png new file mode 100644 index 0000000..7baedf9 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 11.36.20 AM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 11.55.00 AM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 11.55.00 AM.png new file mode 100644 index 0000000..99d3a59 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 11.55.00 AM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 11.56.54 AM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 11.56.54 AM.png new file mode 100644 index 0000000..629e1e3 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 11.56.54 AM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 11.58.13 AM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 11.58.13 AM.png new file mode 100644 index 0000000..b173f1c Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 11.58.13 AM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 12.09.46 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 12.09.46 PM.png new file mode 100644 index 0000000..4d51e19 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 12.09.46 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 12.12.59 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 12.12.59 PM.png new file mode 100644 index 0000000..ab3be97 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 12.12.59 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 12.35.47 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 12.35.47 PM.png new file mode 100644 index 0000000..14199ec Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 12.35.47 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 12.40.09 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 12.40.09 PM.png new file mode 100644 index 0000000..59c894a Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 12.40.09 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 12.41.13 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 12.41.13 PM.png new file mode 100644 index 0000000..91a7a52 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 12.41.13 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 2.02.17 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 2.02.17 PM.png new file mode 100644 index 0000000..6ef2786 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 2.02.17 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 2.06.04 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 2.06.04 PM.png new file mode 100644 index 0000000..6390d20 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 2.06.04 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 2.07.28 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 2.07.28 PM.png new file mode 100644 index 0000000..97a0d07 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 2.07.28 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 2.10.38 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 2.10.38 PM.png new file mode 100644 index 0000000..aba1613 Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 2.10.38 PM.png differ diff --git a/administrator/customisation/img/Screenshot 2023-07-16 at 2.12.27 PM.png b/administrator/customisation/img/Screenshot 2023-07-16 at 2.12.27 PM.png new file mode 100644 index 0000000..ccb0fdb Binary files /dev/null and b/administrator/customisation/img/Screenshot 2023-07-16 at 2.12.27 PM.png differ diff --git a/administrator/customisation/img/naming-convention.README b/administrator/customisation/img/naming-convention.README new file mode 100644 index 0000000..74a045a --- /dev/null +++ b/administrator/customisation/img/naming-convention.README @@ -0,0 +1,7 @@ +# Image naming convention + +Images should be named according to reference doc, sub-section and order in the document. +e.g. + +- The 1st image in instructions regarding zooming will be something like zooming-1, the 2nd image will be zooming-2, etc. +- The 1st image in quickstart regarding logging in will be login-1, etc diff --git a/administrator/customisation/index.html b/administrator/customisation/index.html new file mode 100644 index 0000000..8affbd5 --- /dev/null +++ b/administrator/customisation/index.html @@ -0,0 +1,1163 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+56. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+ +
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/geocontext/data/index.html b/administrator/geocontext/data/index.html new file mode 100644 index 0000000..4f6da16 --- /dev/null +++ b/administrator/geocontext/data/index.html @@ -0,0 +1,1365 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+54. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

54. Working with GeoContext Data

+

In this article we explain the concept of the GeoContext platform and how layers are published to it in BIMS.

+

GeoContext

+

54.1 Creating a GeoContext Collection

+

A GeoContext collection is a set up web map services that can be queried in order to discover habitat or other relevant spatial data for a site.

+

GeoContext Collection

+

From GeoContext collection admin page click Add collection button to create a new collection

+

Add button

+

Fill out the required fields :

+
    +
  • Key - Key of the collection
  • +
  • Name - Name of the collection
  • +
+

Click Save when you're done

+

54.2 Adding a GeoContext Group

+

A GeoContext group is a subset of layers from a GeoContext collection that form a logical group, usually based around a theme such as temperature, political regions etc.

+

GeoContext Group

+

54.2.1 Adding groups to existing collection

+
    +
  • From the GeoContext Collection admin page, open the collection that you want to add groups to.
  • +
  • From the Context groups section click Add another collection group link
  • +
  • Find existing group that you want to add to the group.
  • +
  • If you want to create a new group, click + sign next to the dropdown. See Adding new Group to learn how to create a new group from scratch.
  • +
+

+

You can arrange the group order as follows:

+
    +
  • Update the order text manually
  • +
  • Or move the group by dragging the move item icon that is located on the far right before the x sign
  • +
+

In order to remove group from the group just click the x sign

+

2020-09-08_10-24.png

+

54.2.2 Adding a new Group

+

You can create a new group from the context group page or directly from layer admin page.

+

In order to create new group you need to fill out the required fields:

+
    +
  • Key - Key of the context group, this will be used in the bims to fetch the GeoContext data via API
  • +
  • Name - Name of the group
  • +
  • Group Type - Type of the group to determine the UI, choose Graph if this group depicting data over a time period. (e.g. monthly average temperature )
  • +
+

See other existing groups for guidance.

+

54.3 Adding a layer to a GeoContext group

+

In this sectio we describe how you add a layer to a GeoContext group. A layer is a Web Mapping Service intended to make spatial information available over the internet, covering a specific thematic topic e.g. average annual temperature in March

+

+

54.3.1 Adding Layers to an Existing GeoContext Group

+
    +
  • From the GeoContext group admin page, open the group that you want to add layers to.
  • +
  • From the Context group services section click Add another context group service link
  • +
  • Find existing layer that you want to add to the group.
  • +
  • If you want to create a new layer, click + sign next to the dropdown. See Adding new Layer to learn how to create a new layer from scratch.
  • +
+

2020-09-08_10-16.png

+

You can arrange the layer order as follows:

+
    +
  • Update the order text manually
  • +
  • Or move the layer by dragging the move item icon that is located on the far right before the x sign
  • +
+

In order to remove layer from the group just click the x sign

+

+

Click Save when you're done updating the group.

+

54.3.2 Adding a new Layer

+

You can create a new layer from the context group page or directly from layer admin page.

+

In order to create new layer you need to fill out the required fields:

+
    +
  • Key
  • +
  • Name
  • +
  • Url - Url of the layer service, e.g. if you use Geoserver then you can try following link : {geoserver_host}/geoserver/wfs
  • +
  • Query Type - Query type of the layer, usually we use WFS
  • +
  • Layer name - Required name of the actual layer/feature to retrieve (Property name).
  • +
  • Layer typename - Layer type name to get the context.
  • +
  • Service version - Version of the service (e.g. WMS 1.1.0, WFS 2.0.0).
  • +
+

See other existing layers for guidance.

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/geocontext/harvesting/index.html b/administrator/geocontext/harvesting/index.html new file mode 100644 index 0000000..48e2c05 --- /dev/null +++ b/administrator/geocontext/harvesting/index.html @@ -0,0 +1,1343 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+55. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

55. Harvesting GeoContext Data in BIMS

+

In this section we explain the process of configuring BIMS to harvest GeoContext data from a GeoContext server for a collection of layers.

+

BIMS GeoContext Harvesting

+

55.1 Configuring geocontext settings for GeoContext

+

This section describes how to configure your geocontext settings to harvest GeoContext data for each site.

+

BIMS GeoContext Harvesting Settings

+

Open geocontext settings in admin page +Find Geocontext group keys field

+

image

+
    +
  • Add the GeoContext group keys in this field, use commas to separate multiple keys
  • +
  • Click Save when you're done
  • +
  • Now the system will check these keys to fetch GeoContext data for new sites
  • +
+
+

Make sure that the key exists in the GeoContext, to check you can use this api : https://staging.geocontext.kartoza.com/api/v1/geocontext/value/group/1/1/{geocontext_key}/ and change the geocontext_key in the url with the key you want to check

+
+

55.2 Creating a Location Context Group in BIMS

+

In this section we explain how to create a location context group in the django admin interface for BIMS.

+

BIMS GeoContext Harvesting Location Context Group)

+

To create a Location Context Group in BIMS, you need to know what layers are returned from the GeoContext group.

+

For instance, we want to create Location Context Group for Rwanda Catchments.

+

First, check the output from GeoContext with this API : +https://staging.geocontext.kartoza.com/api/v2/query?registry=group&key=river_catchment_areas_group&x=24&y=-29&outformat=json

+

Note : Change river_catchment_areas_group in the url with GeoContext group you want to add.

+

You will receive this data from GeoContext :

+

image

+

There are two service registry values (layers), so you need to add them both to the Location Context Group to display all those layers in the filter.

+

To add those layers please follow these steps :

+

Note : We will use this data for the following steps

+

2020-09-08_14-13.png

+
    +
  • Open Location Context Groups admin page
  • +
  • Click Add location context group button at the top right corner
  • +
  • Fill out these fields :
  • +
  • Name - Name of the layer, Rwanda Catchments Level 1
  • +
  • Key - Layer key, rwanda_catchments_level_1
  • +
  • Geocontext group key - Group key from GeoContext, rwanda_catchments
  • +
  • Click Save
  • +
+

Then you need to do the same thing for other layer.

+

2020-09-08_14-19.png

+

If you've done it correctly, then you will have two new layers in Location Context Group admin page :

+

2020-09-08_14-26.png

+

55.3 Creating a Location Context Group Filter in BIMS

+

In this section we explain how to create a Location Context Filter in BIMS.

+

BIMS GeoContext Harvesting Location Context Group Filter

+

Location context filter is just the filter name for the spatial filter on the Map page.

+

2020-09-08_14-31.png

+

To add groups (Rwanda Catchments Level 1 & Rwanda Catchment Level 2) to the Location context filter please follow this guide.

+

To add new Location context filter please follow these steps :

+
    +
  • Open the Location context filter admin page
  • +
  • Click Add location context filter button at the top right
  • +
  • Fill up these required fields :
  • +
  • Name - Name of the location context filter
  • +
  • Display order - Order of this location context filter
  • +
  • Click Save when you've done
  • +
+

55.4 Configuring the order of Location Context Groups

+

In this section we describe the process of sorting Location Context Groups to control the order in which they appear in BIMS.

+

BIMS GeoContext Harvesting Group Order

+

To do this guide, you need to add Location Context Group and Location Context Group Filter beforehand.

+

Open the admin page for Location Context Filter Group Order +Click Add location context group order button at the top right +Fill up these fields :

+

Group - Choose Location Context Group you want to show in the filter panel +2020-09-08_14-53.png

+

Filter - Choose Location Filter you want to show in the filter panel +2020-09-08_14-52.png

+

Group display order - This is the order of the groups inside the location filter +2020-09-08_14-54.png

+

Show in dashboard (optional) - Whether to show this data in the dashboard or not +2020-09-08_14-56.png

+

Show in side panel (optional) - Whether to show this data in the side panel or not +2020-09-08_14-57.png

+

Click Save when you've done.

+

55.5 Updating GeoContext data for sites using the admin panel

+

In this article we describe the process of updating the GeoContext data in one or more sites using the admin panel.

+

BIMS GeoContext Harvesting Admin Command

+

To update GeoContext data for existing sites please follow these steps :

+
    +
  • Open Location Sites admin page
  • +
  • Select the sites you want to update the geocontext data
  • +
+

BIMS Location Site Update Geocontext

+
    +
  • Select 'Update location context data for selected sites in background.' in the dropdown located at the bottom of the page
  • +
+

BIMS Location Site Update Geocontext Command

+
    +
  • Click Go. The system will try to update the geocontext data in the background
  • +
  • To see the geocontext status open one of the previously selected location sites, scroll down to location context section to view all geocontext data and check if your geocontext data has been retrieved :
  • +
+

BIMS Location Site Update Geocontext Status

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/geocontext/img/2020-09-08_10-16.width-500.png b/administrator/geocontext/img/2020-09-08_10-16.width-500.png new file mode 100644 index 0000000..b1a51a8 Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_10-16.width-500.png differ diff --git a/administrator/geocontext/img/2020-09-08_10-24.width-500.png b/administrator/geocontext/img/2020-09-08_10-24.width-500.png new file mode 100644 index 0000000..6957abd Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_10-24.width-500.png differ diff --git a/administrator/geocontext/img/2020-09-08_10-52.width-500.png b/administrator/geocontext/img/2020-09-08_10-52.width-500.png new file mode 100644 index 0000000..30469f4 Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_10-52.width-500.png differ diff --git a/administrator/geocontext/img/2020-09-08_12-18.width-500.png b/administrator/geocontext/img/2020-09-08_12-18.width-500.png new file mode 100644 index 0000000..b7c4a83 Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_12-18.width-500.png differ diff --git a/administrator/geocontext/img/2020-09-08_12-33.width-500.png b/administrator/geocontext/img/2020-09-08_12-33.width-500.png new file mode 100644 index 0000000..aeaf216 Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_12-33.width-500.png differ diff --git a/administrator/geocontext/img/2020-09-08_14-13.width-800.png b/administrator/geocontext/img/2020-09-08_14-13.width-800.png new file mode 100644 index 0000000..f298e55 Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_14-13.width-800.png differ diff --git a/administrator/geocontext/img/2020-09-08_14-19.width-800.png b/administrator/geocontext/img/2020-09-08_14-19.width-800.png new file mode 100644 index 0000000..ae0c457 Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_14-19.width-800.png differ diff --git a/administrator/geocontext/img/2020-09-08_14-26.width-800.png b/administrator/geocontext/img/2020-09-08_14-26.width-800.png new file mode 100644 index 0000000..66d27f5 Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_14-26.width-800.png differ diff --git a/administrator/geocontext/img/2020-09-08_14-31.width-800.png b/administrator/geocontext/img/2020-09-08_14-31.width-800.png new file mode 100644 index 0000000..b3b7998 Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_14-31.width-800.png differ diff --git a/administrator/geocontext/img/2020-09-08_14-52.width-800.png b/administrator/geocontext/img/2020-09-08_14-52.width-800.png new file mode 100644 index 0000000..eeab9c4 Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_14-52.width-800.png differ diff --git a/administrator/geocontext/img/2020-09-08_14-53.width-800.png b/administrator/geocontext/img/2020-09-08_14-53.width-800.png new file mode 100644 index 0000000..3cca730 Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_14-53.width-800.png differ diff --git a/administrator/geocontext/img/2020-09-08_14-54.width-800.png b/administrator/geocontext/img/2020-09-08_14-54.width-800.png new file mode 100644 index 0000000..d0a98d8 Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_14-54.width-800.png differ diff --git a/administrator/geocontext/img/2020-09-08_14-56.width-800.png b/administrator/geocontext/img/2020-09-08_14-56.width-800.png new file mode 100644 index 0000000..d990cef Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_14-56.width-800.png differ diff --git a/administrator/geocontext/img/2020-09-08_14-57.width-800.png b/administrator/geocontext/img/2020-09-08_14-57.width-800.png new file mode 100644 index 0000000..da88c7c Binary files /dev/null and b/administrator/geocontext/img/2020-09-08_14-57.width-800.png differ diff --git a/administrator/geocontext/img/BIMSGeoContextHarvesting.width-800.png b/administrator/geocontext/img/BIMSGeoContextHarvesting.width-800.png new file mode 100644 index 0000000..6c3d15b Binary files /dev/null and b/administrator/geocontext/img/BIMSGeoContextHarvesting.width-800.png differ diff --git a/administrator/geocontext/img/BIMSGeoContextHarvestingAdminCommand.width-800.png b/administrator/geocontext/img/BIMSGeoContextHarvestingAdminCommand.width-800.png new file mode 100644 index 0000000..6572bb6 Binary files /dev/null and b/administrator/geocontext/img/BIMSGeoContextHarvestingAdminCommand.width-800.png differ diff --git a/administrator/geocontext/img/BIMSGeoContextHarvestingGroupOrder.width-800.png b/administrator/geocontext/img/BIMSGeoContextHarvestingGroupOrder.width-800.png new file mode 100644 index 0000000..27477dd Binary files /dev/null and b/administrator/geocontext/img/BIMSGeoContextHarvestingGroupOrder.width-800.png differ diff --git a/administrator/geocontext/img/BIMSGeoContextHarvestingLocationContextGroup.width-800.png b/administrator/geocontext/img/BIMSGeoContextHarvestingLocationContextGroup.width-800.png new file mode 100644 index 0000000..bc9b36e Binary files /dev/null and b/administrator/geocontext/img/BIMSGeoContextHarvestingLocationContextGroup.width-800.png differ diff --git a/administrator/geocontext/img/BIMSGeoContextHarvestingLocationContextGroupFi.width-800.png b/administrator/geocontext/img/BIMSGeoContextHarvestingLocationContextGroupFi.width-800.png new file mode 100644 index 0000000..70140a4 Binary files /dev/null and b/administrator/geocontext/img/BIMSGeoContextHarvestingLocationContextGroupFi.width-800.png differ diff --git a/administrator/geocontext/img/BIMSGeoContextHarvestingSettings.width-800.png b/administrator/geocontext/img/BIMSGeoContextHarvestingSettings.width-800.png new file mode 100644 index 0000000..2d5afec Binary files /dev/null and b/administrator/geocontext/img/BIMSGeoContextHarvestingSettings.width-800.png differ diff --git a/administrator/geocontext/img/GeoContext.width-800.png b/administrator/geocontext/img/GeoContext.width-800.png new file mode 100644 index 0000000..4f93bb8 Binary files /dev/null and b/administrator/geocontext/img/GeoContext.width-800.png differ diff --git a/administrator/geocontext/img/GeoContextCollection.width-800.png b/administrator/geocontext/img/GeoContextCollection.width-800.png new file mode 100644 index 0000000..b5c3b4e Binary files /dev/null and b/administrator/geocontext/img/GeoContextCollection.width-800.png differ diff --git a/administrator/geocontext/img/GeoContextGroup.width-800.png b/administrator/geocontext/img/GeoContextGroup.width-800.png new file mode 100644 index 0000000..2968d6c Binary files /dev/null and b/administrator/geocontext/img/GeoContextGroup.width-800.png differ diff --git a/administrator/geocontext/img/GeoContextLayer.width-800.png b/administrator/geocontext/img/GeoContextLayer.width-800.png new file mode 100644 index 0000000..f454e7e Binary files /dev/null and b/administrator/geocontext/img/GeoContextLayer.width-800.png differ diff --git a/administrator/geocontext/img/GeoContextWorkflows.width-800.png b/administrator/geocontext/img/GeoContextWorkflows.width-800.png new file mode 100644 index 0000000..db8fac6 Binary files /dev/null and b/administrator/geocontext/img/GeoContextWorkflows.width-800.png differ diff --git a/administrator/geocontext/img/GeoNodeLayer.width-800.png b/administrator/geocontext/img/GeoNodeLayer.width-800.png new file mode 100644 index 0000000..0f59a65 Binary files /dev/null and b/administrator/geocontext/img/GeoNodeLayer.width-800.png differ diff --git a/administrator/geocontext/img/GeoNodeMetadata.width-800.png b/administrator/geocontext/img/GeoNodeMetadata.width-800.png new file mode 100644 index 0000000..fd926d1 Binary files /dev/null and b/administrator/geocontext/img/GeoNodeMetadata.width-800.png differ diff --git a/administrator/geocontext/img/GetWMSURL.width-800.png b/administrator/geocontext/img/GetWMSURL.width-800.png new file mode 100644 index 0000000..3865306 Binary files /dev/null and b/administrator/geocontext/img/GetWMSURL.width-800.png differ diff --git a/administrator/geocontext/img/MetadataDetail.width-800.png b/administrator/geocontext/img/MetadataDetail.width-800.png new file mode 100644 index 0000000..caad0a0 Binary files /dev/null and b/administrator/geocontext/img/MetadataDetail.width-800.png differ diff --git a/administrator/geocontext/img/NonBiodiversityLayer.width-800.png b/administrator/geocontext/img/NonBiodiversityLayer.width-800.png new file mode 100644 index 0000000..8f1f390 Binary files /dev/null and b/administrator/geocontext/img/NonBiodiversityLayer.width-800.png differ diff --git a/administrator/geocontext/img/PublishToGeoNode.width-800.png b/administrator/geocontext/img/PublishToGeoNode.width-800.png new file mode 100644 index 0000000..bda12bf Binary files /dev/null and b/administrator/geocontext/img/PublishToGeoNode.width-800.png differ diff --git a/administrator/geocontext/img/WMS_Server.width-800.png b/administrator/geocontext/img/WMS_Server.width-800.png new file mode 100644 index 0000000..48a53df Binary files /dev/null and b/administrator/geocontext/img/WMS_Server.width-800.png differ diff --git a/administrator/geocontext/img/add_collection.png b/administrator/geocontext/img/add_collection.png new file mode 100644 index 0000000..161a94d Binary files /dev/null and b/administrator/geocontext/img/add_collection.png differ diff --git a/administrator/geocontext/img/geocontext-overview-youtube.png b/administrator/geocontext/img/geocontext-overview-youtube.png new file mode 100644 index 0000000..ee1a83b Binary files /dev/null and b/administrator/geocontext/img/geocontext-overview-youtube.png differ diff --git a/administrator/geocontext/img/location_sites_update_geocontext_1.png b/administrator/geocontext/img/location_sites_update_geocontext_1.png new file mode 100644 index 0000000..d84d593 Binary files /dev/null and b/administrator/geocontext/img/location_sites_update_geocontext_1.png differ diff --git a/administrator/geocontext/img/location_sites_update_geocontext_2.png b/administrator/geocontext/img/location_sites_update_geocontext_2.png new file mode 100644 index 0000000..1c5a7b4 Binary files /dev/null and b/administrator/geocontext/img/location_sites_update_geocontext_2.png differ diff --git a/administrator/geocontext/img/location_sites_update_geocontext_3.png b/administrator/geocontext/img/location_sites_update_geocontext_3.png new file mode 100644 index 0000000..5024541 Binary files /dev/null and b/administrator/geocontext/img/location_sites_update_geocontext_3.png differ diff --git a/administrator/geocontext/img/naming-convention.README b/administrator/geocontext/img/naming-convention.README new file mode 100644 index 0000000..74a045a --- /dev/null +++ b/administrator/geocontext/img/naming-convention.README @@ -0,0 +1,7 @@ +# Image naming convention + +Images should be named according to reference doc, sub-section and order in the document. +e.g. + +- The 1st image in instructions regarding zooming will be something like zooming-1, the 2nd image will be zooming-2, etc. +- The 1st image in quickstart regarding logging in will be login-1, etc diff --git a/administrator/geocontext/index.html b/administrator/geocontext/index.html new file mode 100644 index 0000000..ed03270 --- /dev/null +++ b/administrator/geocontext/index.html @@ -0,0 +1,1178 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+51. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+ +
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/geocontext/layers/index.html b/administrator/geocontext/layers/index.html new file mode 100644 index 0000000..b66c81a --- /dev/null +++ b/administrator/geocontext/layers/index.html @@ -0,0 +1,1290 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+53. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

53. Publishing GeoContext and Visualisation Layers

+

This subsection describes how to publish layers as WMS (Web Mapping Services) for use by GeoContext or as Visualisation layers. BIMS deploys with an instance of GeoNode that can be used for publishing these layers, but you can use any standards compliant web mapping server for this purpose.

+

WMS Server

+

First let us define the terms 'GeoContext Layer' and 'Visualisation Layer':

+
    +
  1. +

    GeoContext layers are layers that you publish online as an OGC web service with the explicit intention that these layers are harvested by the https://staging.geocontext.kartoza.com GeoContext service.

    +
  2. +
  3. +

    Visualisation layers are used in the layer selector in BIMS and allow the user to add map overlays in the BIMS map view - for example to show soil types or catchment boundaries on the map.

    +
  4. +
+

In the next steps we will show you how to publish both of these types of layers.

+

53.1 Publishing a layer in GeoNode

+

This article gives a short explanation of how to publish a layer in GeoNode. This is one way to provide a layer in GeoContext yourself.

+

Publish To GeoNode

+

To publish a layer from GeoNode you can follow this guide : https://docs.geonode.org/en/master/usage/managing_layers/uploading_layers.html

+

53.2 Adding metadata to your published layer

+

The guide shows you how to add metadata to the layer you have published.

+

GeoNodeMetadata

+

To add metadata to the layer in GeoNode please follow this guide : https://docs.geonode.org/en/master/usage/managing_layers/layer_metadata.html.

+

53.3 Discovering the WMS URL for a published layer

+

In this guide we show you how to find out the WMS URL for a published layer so that the layer can be published in GeoContext or as a GeoContext layer.

+

WMS URL

+

Discovering the WMS URL for a map service requires that you have a platform where you can browse the services. This could be done though a GIS client such as QGIS or on a web interface such as GeoNode or GeoServer. For this example we will show you the workflow in GeoNode.

+

First browse to the map layer in GeoNode that you want to publish in BIMS:

+

GeoNodeLayer

+

Next click on the metadata detail button to view the metadata for the layer.

+

MetadataDetail

+

On the metadata page you will see a long list of information about the layer. First make a note of the "Title" of the layer e.g.:

+
+

LULC_2018_

+
+

Now scroll down until you find the section called "References" and then look for the heading "OGC WMS: geonode Service". Right click on the service link and choose "Copy link location" from your browser's context menu.

+

Save the service URL that is now in your clipboard e.g.:

+

https://geonode.rbis.kartoza.com/geoserver/ows

+

53.4 Adding a non-biodiversity layer to FBIS

+

In this guide we will show you how to publish a non-biodiversity layer in FBIS. Non-biodiversity layers can be displayed on top of the base map in FBIS to provide insights about the spatial situation of collection sites.

+

Non-Biodiversity Layer

+

In order to add a layer to the FBIS, follow these steps :

+
    +
  • Go to admin page
  • +
  • Click non biodiversity layer section
  • +
  • Click Add non biodiversity layer button at the top right
  • +
  • Fill out these required fields (see Discovering the WMS URL for a published layer):
  • +
  • Name - The name of the layer, will be displayed in the Layer Selector
  • +
  • WMS url - WMS url for this layer (if you're using GeoNode to host the layer you can try following link : {geonode_url}/geoserver/wms)
  • +
  • WMS layer name - Layer name from layer provider (e.g. geonode:layer_name)
  • +
  • WMS format - Format of the wms, default is in image/png
  • +
  • Get feature format - Output format of the GetFeature function, the default is in text/plain
  • +
  • Click Save button at the bottom right
  • +
  • To set the order in which the layers are displayed on the filter click these buttons :
  • +
+

2020-09-08_12-18.png

+

These layers will appear in the Layer Selector on the map page.

+

2020-09-08_12-33.png

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/geocontext/overview/index.html b/administrator/geocontext/overview/index.html new file mode 100644 index 0000000..12ac1af --- /dev/null +++ b/administrator/geocontext/overview/index.html @@ -0,0 +1,1169 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+52. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

52. Overview of GeoContext Management

+

In this guide we will explain the high level concepts of the GeoContext subsystem which is used to derive location related data for each occurrence record added to RBIS.

+

GeoContext is an independent service, available at https://geocontext.kartoza.com/. The purpose of GeoContext is to harvest data for point locations from a range of online databases. GeoContext allows you to register WMS/WFS/WCS layers in groups which in turn can be registered in a collection. You can then pass it a point locality and it will query every layer in the collection, returning a set of values, one for each layer under the point location.

+

Geocontext Overview

+

As you can see from the above diagram, the workflow consist of three parts:

+

1) Publishing layers under e.g. WMS

+

2) Registering layers, groups and collections in the GeoContext service

+

3) Registering the GeoContext service(s) with BIMS

+

This tutorial will lead you through all of these steps. We expect that you are already familiar with platforms such as GeoNode, GeoServer and concepts such as OGC services. We also expect that you are familiar with and understand the basic operations and management of BIMS.

+

The following YouTube video walks through the steps described in this section of the documentation in detail with examples. If you are viewing this as a PDF or on the web, you can click on the image below to open the YouTube video.

+

Overview

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/geoserver/img/Geoserver_workflow_diagram.png b/administrator/geoserver/img/Geoserver_workflow_diagram.png new file mode 100644 index 0000000..1ee95aa Binary files /dev/null and b/administrator/geoserver/img/Geoserver_workflow_diagram.png differ diff --git a/administrator/geoserver/img/association-style.png b/administrator/geoserver/img/association-style.png new file mode 100644 index 0000000..c25fd6b Binary files /dev/null and b/administrator/geoserver/img/association-style.png differ diff --git a/administrator/geoserver/img/browser.png b/administrator/geoserver/img/browser.png new file mode 100644 index 0000000..56a3476 Binary files /dev/null and b/administrator/geoserver/img/browser.png differ diff --git a/administrator/geoserver/img/db-con-schema.png b/administrator/geoserver/img/db-con-schema.png new file mode 100644 index 0000000..0a67114 Binary files /dev/null and b/administrator/geoserver/img/db-con-schema.png differ diff --git a/administrator/geoserver/img/db-manager-1.png b/administrator/geoserver/img/db-manager-1.png new file mode 100644 index 0000000..fd26f12 Binary files /dev/null and b/administrator/geoserver/img/db-manager-1.png differ diff --git a/administrator/geoserver/img/edit-connection.png b/administrator/geoserver/img/edit-connection.png new file mode 100644 index 0000000..cf96c9d Binary files /dev/null and b/administrator/geoserver/img/edit-connection.png differ diff --git a/administrator/geoserver/img/import-layer-options.png b/administrator/geoserver/img/import-layer-options.png new file mode 100644 index 0000000..4133466 Binary files /dev/null and b/administrator/geoserver/img/import-layer-options.png differ diff --git a/administrator/geoserver/img/layer-panel.png b/administrator/geoserver/img/layer-panel.png new file mode 100644 index 0000000..3e23112 Binary files /dev/null and b/administrator/geoserver/img/layer-panel.png differ diff --git a/administrator/geoserver/img/naming-convention.README b/administrator/geoserver/img/naming-convention.README new file mode 100644 index 0000000..74a045a --- /dev/null +++ b/administrator/geoserver/img/naming-convention.README @@ -0,0 +1,7 @@ +# Image naming convention + +Images should be named according to reference doc, sub-section and order in the document. +e.g. + +- The 1st image in instructions regarding zooming will be something like zooming-1, the 2nd image will be zooming-2, etc. +- The 1st image in quickstart regarding logging in will be login-1, etc diff --git a/administrator/geoserver/img/postgresql-details.png b/administrator/geoserver/img/postgresql-details.png new file mode 100644 index 0000000..a31622b Binary files /dev/null and b/administrator/geoserver/img/postgresql-details.png differ diff --git a/administrator/geoserver/img/postgresql_1.png b/administrator/geoserver/img/postgresql_1.png new file mode 100644 index 0000000..59ca98b Binary files /dev/null and b/administrator/geoserver/img/postgresql_1.png differ diff --git a/administrator/geoserver/img/preview-add-lyr.png b/administrator/geoserver/img/preview-add-lyr.png new file mode 100644 index 0000000..cc32bcd Binary files /dev/null and b/administrator/geoserver/img/preview-add-lyr.png differ diff --git a/administrator/geoserver/img/pub-tabs.png b/administrator/geoserver/img/pub-tabs.png new file mode 100644 index 0000000..591c65e Binary files /dev/null and b/administrator/geoserver/img/pub-tabs.png differ diff --git a/administrator/geoserver/img/raster-data-type.png b/administrator/geoserver/img/raster-data-type.png new file mode 100644 index 0000000..2fdd905 Binary files /dev/null and b/administrator/geoserver/img/raster-data-type.png differ diff --git a/administrator/geoserver/img/raster-navi.png b/administrator/geoserver/img/raster-navi.png new file mode 100644 index 0000000..4ae9c3c Binary files /dev/null and b/administrator/geoserver/img/raster-navi.png differ diff --git a/administrator/geoserver/img/save-style-sld.png b/administrator/geoserver/img/save-style-sld.png new file mode 100644 index 0000000..5acde0a Binary files /dev/null and b/administrator/geoserver/img/save-style-sld.png differ diff --git a/administrator/geoserver/img/save-style.png b/administrator/geoserver/img/save-style.png new file mode 100644 index 0000000..facd5cc Binary files /dev/null and b/administrator/geoserver/img/save-style.png differ diff --git a/administrator/geoserver/img/schema-geo.png b/administrator/geoserver/img/schema-geo.png new file mode 100644 index 0000000..fa9cb12 Binary files /dev/null and b/administrator/geoserver/img/schema-geo.png differ diff --git a/administrator/geoserver/img/search-style.png b/administrator/geoserver/img/search-style.png new file mode 100644 index 0000000..68d698a Binary files /dev/null and b/administrator/geoserver/img/search-style.png differ diff --git a/administrator/geoserver/img/style-choose.png b/administrator/geoserver/img/style-choose.png new file mode 100644 index 0000000..4100bf6 Binary files /dev/null and b/administrator/geoserver/img/style-choose.png differ diff --git a/administrator/geoserver/img/style-tab-opening.png b/administrator/geoserver/img/style-tab-opening.png new file mode 100644 index 0000000..f9d45ba Binary files /dev/null and b/administrator/geoserver/img/style-tab-opening.png differ diff --git a/administrator/geoserver/img/symbology-tab.png b/administrator/geoserver/img/symbology-tab.png new file mode 100644 index 0000000..7ab3b1e Binary files /dev/null and b/administrator/geoserver/img/symbology-tab.png differ diff --git a/administrator/geoserver/img/upload-style.png b/administrator/geoserver/img/upload-style.png new file mode 100644 index 0000000..0dcd36a Binary files /dev/null and b/administrator/geoserver/img/upload-style.png differ diff --git a/administrator/geoserver/img/wms-conn.png b/administrator/geoserver/img/wms-conn.png new file mode 100644 index 0000000..0d100f2 Binary files /dev/null and b/administrator/geoserver/img/wms-conn.png differ diff --git a/administrator/geoserver/index.html b/administrator/geoserver/index.html new file mode 100644 index 0000000..846a8e6 --- /dev/null +++ b/administrator/geoserver/index.html @@ -0,0 +1,1166 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+44. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+ +
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/geoserver/loading-postgis-layers/index.html b/administrator/geoserver/loading-postgis-layers/index.html new file mode 100644 index 0000000..e659148 --- /dev/null +++ b/administrator/geoserver/loading-postgis-layers/index.html @@ -0,0 +1,1291 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+46. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

46. Loading spatial data

+

Spatial data consist of vector and raster data. In this guide we will explain the +process of loading vector data into a PostgreSQL database.

+
+

We assume users have a running instance of QGIS on their machines. If you +do not have a running version you can download and install an appropriate QGIS version based on your architecture. Also acquire the credentials for the database from your database administrator.

+
+

There are various ways to load vector data into the database but, we will concentrate +on the easier methods. This usually involves the following:

+
    +
  • Define a database connection - this is a once off task.
  • +
  • Loading the data through various methods i.e Drag and Drop or Database Manager.
  • +
+

46.1 Setup PostgreSQL Connection Parameters

+

Step 1. Open QGIS Desktop.

+

Step 2. On your icons toolbar click the PostgreSQL icon to add layer or alternatively click on the Layers Menu > Data Source Manager > PostgreSQL postgresql_1.png

+

Step 3. Click to create a new database connection. edit-connection.png

+

Step 4. Populate the dialogue with your user credentials. postgresql-connection

+

Step 5. Save your connection parameters.

+

46.2 Loading Spatial Data

+

46.2.1 Using the QGIS Browser

+

All panels in QGIS can be docked and arranged based per user's needs. It is +encouraged to dock your layers and browser panel on opposite sides in QGIS.

+

qgis-browser.png

+

Step 1. Load your vector layers into QGIS. +Step 2. Open the browser tab that you have docked on the opposite end of the layer panel. +Step 3. In the browser panel navigate to open the PostgreSQL connection you defined +earlier on. +db-schema.png +Step 4. Select the appropriate schema from your PostgreSQL connection. +Step 5. Drag the layer from the layers panel dropping it onto the selected schema +in the browser panel. +Step 6. Wait for the layer to complete loading.

+

After loading the layer it will be available in the selected schema and ready to use in GeoServer.

+

46.2.2 Using DBManager

+

When using this method it is assumed a user has already defined a database connection.

+

Step 1. Navigate to the Database Menu in QGIS and from the drop down choose +DBManager. Database Menu > DB Manager +db-manager-panel.png +Step 2. Select your PostgreSQL connection. +Step 3. Click on the Import Layer/File on top of the DB Manager dialogue. +Step 4. Populate the import layer dialogue choosing the appropriate options. +import-layer.png +Step 5. Accept the values and wait for the layer to be loaded.

+
+

The QGIS processing tool also provides other options to load spatial +data into a PostgreSQL database. Those tools also provide the users with the option +to do bulk inserts of multi layers simultaneously.

+
+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/geoserver/overview/index.html b/administrator/geoserver/overview/index.html new file mode 100644 index 0000000..c680553 --- /dev/null +++ b/administrator/geoserver/overview/index.html @@ -0,0 +1,1230 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+45. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+

45. Introduction to Geoserver

+

GeoServer is a Java based open source software server which has the ability to share and edit geospatial data in open standard format. GeoServer allows a user to add, remove, edit and control geospatial content through a web browser, which can generate different OGC standard services such as WMS, WCS, WFS, and SLD etc. The main objective and purpose of GeoServer is to offer potential to create maps and share data in compliance with OGC standards.

+

45.1 Why use GeoServer?

+
    +
  • Implements OGC compliant standards.
  • +
  • Open Source – freely available to download and use.
  • +
  • Integrates with existing applications and APIs such as Google Earth and ESRI ArcGIS.
  • +
  • Community support relating to developing, troubleshooting and software tutorials.
  • +
  • Frequent upgrades and development, improving the functionality, quality and ease of use.
  • +
+

45.2 Main features and capabilities

+
    +
  • Implements the OGC standards in compliance with the OGC standard specifications.
  • +
  • Easy to use web configuration tool.
  • +
  • Support for PostGIS, Shapefile, ArcSDE, DB2 and Oracle.
  • +
  • Supports a wide range of raster and vector formats (GeoTiff, ESRI Shapefiles, PNG, JPG, KML, GML).
  • +
  • Google Earth support.
  • +
  • Integrates with OpenLayers, GeoWebCache and GeoTools.
  • +
  • User Interface supports multiple languages (English, French, German, Russian etc.)
  • +
  • Flexibility in controlling and setting up GeoServer, tailoring it to the users requirements.
  • +
+

The diagram below shows the workflow relating to ingesting data into GeoServer and previewing the data.

+

geoserver-workflow

+

Content above available from learning geoserver.

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/geoserver/publishing-layers-in-geoserver/index.html b/administrator/geoserver/publishing-layers-in-geoserver/index.html new file mode 100644 index 0000000..8b5ddca --- /dev/null +++ b/administrator/geoserver/publishing-layers-in-geoserver/index.html @@ -0,0 +1,1291 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+47. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+

47. Publishing vector data in GeoServer

+

GeoServer can publish vector data from various sources i.e shapefile, geopackage. In our +use case we already have spatial data stored in a relational database and, we will be publishing this data to GeoServer. A relational database has a lot of advantages over the traditional formats i.e shapefile hence our preference to load the data into the database firstly.

+

The process of publishing vector data in GeoServer involves the following steps:

+
    +
  • Creation of a workspace
  • +
  • Defining a store ( In our case a PostgreSQL connection)
  • +
  • Publishing the layers
  • +
+

Since the GeoServer we are using in being used in production we have already defined the first two steps (for vector data) and will not be focusing on them here. For Raster data +we will be defining step 2 and step 3 for the publishing work-flow.

+

47.1 Publishing PostgreSQL Vector data

+

Step 1. Login to the Geoserver instance i.e Local GeoServer using the credentials that have been shared with you.

+

Step 2. Click on the layer menu option A on the image below. +layer-menu.png

+

Step 3. Click on option B shown on the image above.

+

Step 4. Choose a store you want to publish the layer from. This should be the sanbigis store. +choose-schema.png

+

Step 5. Select the appropriate layer you wish to publish.

+

Step 6. On the Data tab edit the following properties. +publishing-tabs.png to the publishing tab:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDescription
Namename this will be identified with
TitleFriendly name
AbstractAdd short description about the layer
Bounding Boxeschoose compute from data and compute from native bounds
+

Then select an appropriate style to use with your layer. +styles.png

+

Step 7. Save your changes and your layer will be visible within GeoServer.

+

47.2 Publishing Raster data

+

In order to publish raster data, you will need to upload the files onto the server +where your GeoServer instance is hosted. This is usually done by the Administrator +or you can do it yourself if the Resource Browser plugin is installed.

+

Step 1. Make sure the layers you need to publish are already stored on a folder visible within GeoServer data directory.

+

Step 2. Click on Stores in the Data side menu.

+

Step 3. Add a new store selecting the appropriate raster data type. The preferred format is Geotiff. +raster-data-type

+

Step 4. Fill in the raster dialogue as depicted below: +raster-add.png

+

Step 5. Save the values in the dialogue and proceed to publish the layer.

+

Step 6. On the Data tab edit the following properties.

+ + + + + + + + + + + + + + + + + + + + + +
PropertyDescription
Namename this will be identified with
TitleFriendly name
AbstractAdd short description about the layer
+

Step 7. On the publishing tab choose the appropriate style and the layer will be visible in GeoServer.

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/geoserver/styling-layers-in-geoserver/index.html b/administrator/geoserver/styling-layers-in-geoserver/index.html new file mode 100644 index 0000000..f71f5f7 --- /dev/null +++ b/administrator/geoserver/styling-layers-in-geoserver/index.html @@ -0,0 +1,1251 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+48. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+

48. Cartography

+

GeoServer provides a couple of ways to symbolize vector and raster data. The most +common way is by using SLD (Styled Layer Descriptor) which is an OGC standard. +GeoServer also adds some flavour to the format which enriches how to symbolize vector/raster +data. Other less common ways to symbolize data include using CSS(Cascading style sheets) and YSLD.

+

There are various open source software which allows you to export SLD natively. Since we are +familiar with QGIS we will use it as our de facto Desktop GIS system.

+
+

Although QGIS can export SLD it does not produce a 1-1 mapping of the rich +cartography that is available in QGIS. It is recommended to use simple styles when your goal +is to use the SLD exporter from QGIS.

+
+

48.1 Styling Vector layers in QGIS

+

Step 1. Load your vector layers in QGIS.

+

Step 2. Right-click on the vector layer and choose the symbology tab. +symbology.png

+

Step 3. Select an appropriate style from the options. Be thoughtful of all the +cartographic rules and the limitations of the exporter when choosing a style.

+

Step 4. If you are satisfied with your result click Apply.

+

Step 5.Click on the Style link to show the hidden context menu. +style-layer.png

+

Step 6. Save your style as SLD. +save-sld.png

+

Step 7. Export the SLD to disk and wait to upload to GeoServer.

+

48.2 Publishing style in GeoServer

+

Step 1. Navigate to GeoServer and click on the style tab.

+

Step 2. Click to Add New Style.

+

Step 3. Browse and upload your style into GeoServer. +upload-style.png

+

Step 4. Submit your results and this will take you back to your style.

+

Step 5. Use the search box at the top of the style to identify the name of the style you created above. +search-style.png

+

Step 6. Open the style again and indicated below. +open-style-tab-again.png

+

Step 7. Select the layer you want to associate your style with. +associated-style.png

+

There are two options:

+
    +
  • Default style - Visible when you preview the map.
  • +
  • Associated style - Visible when you change the URL for a GetMap / Getlegend request
  • +
+

Step 8. Submit your results.

+
+

This process applies to also styling raster data.

+
+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/geoserver/visualising-geoserver-layers-in-qgis/index.html b/administrator/geoserver/visualising-geoserver-layers-in-qgis/index.html new file mode 100644 index 0000000..0580d52 --- /dev/null +++ b/administrator/geoserver/visualising-geoserver-layers-in-qgis/index.html @@ -0,0 +1,1213 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+49. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

49. Visualising layers in QGIS

+

QGIS provides native ways to interact with services coming from GeoServer. +Both services are OGC compliant and can communicate using the following protocols:

+
    +
  • WFS ( Web Feature Service) - renders vector features.
  • +
  • WMS (Web Map Service) - renders as raster data.
  • +
  • WCS (Web Coverage Service) - render the raw raster data.
  • +
  • WMTS (Web Map Tile Service)
  • +
  • OGC API
  • +
+

For each protocol, QGIS provides a native way to interact and authenticate against.

+

49.1 Loading OGC Protocols in QGIS

+

Step 1. Activate the Data Source Manager.

+

Step 2. Select the protocol you need to define and add a new connection.

+

Step 3. Populate the dialogues. All the dialogues will have the same format. +WMS Dialogue: +wms-coon.png

+

Step 4. Click connect to preview the resources available on the server. +preview-services.png

+

Step 5. Select a layer to load into Geoserver and start interacting with it.

+

Repeat the above procedure for each service types.

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/administrator/img/2020-09-08_09-36.width-500.png b/administrator/img/2020-09-08_09-36.width-500.png new file mode 100644 index 0000000..354c584 Binary files /dev/null and b/administrator/img/2020-09-08_09-36.width-500.png differ diff --git a/administrator/img/2020-09-08_13-37.width-800.png b/administrator/img/2020-09-08_13-37.width-800.png new file mode 100644 index 0000000..9264983 Binary files /dev/null and b/administrator/img/2020-09-08_13-37.width-800.png differ diff --git a/administrator/img/2020-09-08_14-06.width-800.png b/administrator/img/2020-09-08_14-06.width-800.png new file mode 100644 index 0000000..a80d9fc Binary files /dev/null and b/administrator/img/2020-09-08_14-06.width-800.png differ diff --git a/administrator/img/BIMSGeoContextHarvestingOnSiteCRUD.width-800.png b/administrator/img/BIMSGeoContextHarvestingOnSiteCRUD.width-800.png new file mode 100644 index 0000000..48aebbd Binary files /dev/null and b/administrator/img/BIMSGeoContextHarvestingOnSiteCRUD.width-800.png differ diff --git a/administrator/img/upload-spacial-layer-1.png b/administrator/img/upload-spacial-layer-1.png new file mode 100644 index 0000000..0354ced Binary files /dev/null and b/administrator/img/upload-spacial-layer-1.png differ diff --git a/administrator/img/upload-spacial-layer-10.png b/administrator/img/upload-spacial-layer-10.png new file mode 100644 index 0000000..514b381 Binary files /dev/null and b/administrator/img/upload-spacial-layer-10.png differ diff --git a/administrator/img/upload-spacial-layer-11.png b/administrator/img/upload-spacial-layer-11.png new file mode 100644 index 0000000..9c720fc Binary files /dev/null and b/administrator/img/upload-spacial-layer-11.png differ diff --git a/administrator/img/upload-spacial-layer-12.png b/administrator/img/upload-spacial-layer-12.png new file mode 100644 index 0000000..f769968 Binary files /dev/null and b/administrator/img/upload-spacial-layer-12.png differ diff --git a/administrator/img/upload-spacial-layer-13.png b/administrator/img/upload-spacial-layer-13.png new file mode 100644 index 0000000..bb7918e Binary files /dev/null and b/administrator/img/upload-spacial-layer-13.png differ diff --git a/administrator/img/upload-spacial-layer-14.png b/administrator/img/upload-spacial-layer-14.png new file mode 100644 index 0000000..5a79ea6 Binary files /dev/null and b/administrator/img/upload-spacial-layer-14.png differ diff --git a/administrator/img/upload-spacial-layer-15.png b/administrator/img/upload-spacial-layer-15.png new file mode 100644 index 0000000..4e8fd1e Binary files /dev/null and b/administrator/img/upload-spacial-layer-15.png differ diff --git a/administrator/img/upload-spacial-layer-16.png b/administrator/img/upload-spacial-layer-16.png new file mode 100644 index 0000000..91a8d8d Binary files /dev/null and b/administrator/img/upload-spacial-layer-16.png differ diff --git a/administrator/img/upload-spacial-layer-17.png b/administrator/img/upload-spacial-layer-17.png new file mode 100644 index 0000000..8121438 Binary files /dev/null and b/administrator/img/upload-spacial-layer-17.png differ diff --git a/administrator/img/upload-spacial-layer-18.png b/administrator/img/upload-spacial-layer-18.png new file mode 100644 index 0000000..c1d2d86 Binary files /dev/null and b/administrator/img/upload-spacial-layer-18.png differ diff --git a/administrator/img/upload-spacial-layer-19.png b/administrator/img/upload-spacial-layer-19.png new file mode 100644 index 0000000..1def56d Binary files /dev/null and b/administrator/img/upload-spacial-layer-19.png differ diff --git a/administrator/img/upload-spacial-layer-2.png b/administrator/img/upload-spacial-layer-2.png new file mode 100644 index 0000000..e642951 Binary files /dev/null and b/administrator/img/upload-spacial-layer-2.png differ diff --git a/administrator/img/upload-spacial-layer-20.png b/administrator/img/upload-spacial-layer-20.png new file mode 100644 index 0000000..b2fdb13 Binary files /dev/null and b/administrator/img/upload-spacial-layer-20.png differ diff --git a/administrator/img/upload-spacial-layer-21.png b/administrator/img/upload-spacial-layer-21.png new file mode 100644 index 0000000..0611271 Binary files /dev/null and b/administrator/img/upload-spacial-layer-21.png differ diff --git a/administrator/img/upload-spacial-layer-22.png b/administrator/img/upload-spacial-layer-22.png new file mode 100644 index 0000000..b7b6ca5 Binary files /dev/null and b/administrator/img/upload-spacial-layer-22.png differ diff --git a/administrator/img/upload-spacial-layer-3.png b/administrator/img/upload-spacial-layer-3.png new file mode 100644 index 0000000..a860187 Binary files /dev/null and b/administrator/img/upload-spacial-layer-3.png differ diff --git a/administrator/img/upload-spacial-layer-4.png b/administrator/img/upload-spacial-layer-4.png new file mode 100644 index 0000000..4b1c23d Binary files /dev/null and b/administrator/img/upload-spacial-layer-4.png differ diff --git a/administrator/img/upload-spacial-layer-5.png b/administrator/img/upload-spacial-layer-5.png new file mode 100644 index 0000000..4c96376 Binary files /dev/null and b/administrator/img/upload-spacial-layer-5.png differ diff --git a/administrator/img/upload-spacial-layer-6.png b/administrator/img/upload-spacial-layer-6.png new file mode 100644 index 0000000..8cb2bd5 Binary files /dev/null and b/administrator/img/upload-spacial-layer-6.png differ diff --git a/administrator/img/upload-spacial-layer-7.png b/administrator/img/upload-spacial-layer-7.png new file mode 100644 index 0000000..3b2f8d2 Binary files /dev/null and b/administrator/img/upload-spacial-layer-7.png differ diff --git a/administrator/img/upload-spacial-layer-8.png b/administrator/img/upload-spacial-layer-8.png new file mode 100644 index 0000000..789c944 Binary files /dev/null and b/administrator/img/upload-spacial-layer-8.png differ diff --git a/administrator/img/upload-spacial-layer-9.png b/administrator/img/upload-spacial-layer-9.png new file mode 100644 index 0000000..857ef4b Binary files /dev/null and b/administrator/img/upload-spacial-layer-9.png differ diff --git a/administrator/index.html b/administrator/index.html new file mode 100644 index 0000000..c842aac --- /dev/null +++ b/administrator/index.html @@ -0,0 +1,3372 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + BIMS Documentation - BIMS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

BIMS Administration Guide

+

This section contains all documentation relevant to administration procedures.

+

The content is divided into four sections:

+
    +
  • Biodiversity Data, which provides a guide for biodiversity data administrators to mobilize and ingest biodiversity data.
  • +
  • Working with GeoServer, which guides administrators through the process of publishing spatial data in GeoServer and how to do basic cartography.
  • +
  • GIS Data in BIMS, which describes the high level concepts of the GeoContext subsystem.
  • +
  • Customisation, which guides administrators through customising their BIMS instance.
  • +
+ + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/administrator/park-layer/add-park-layer/index.html b/administrator/park-layer/add-park-layer/index.html new file mode 100644 index 0000000..c85ab34 --- /dev/null +++ b/administrator/park-layer/add-park-layer/index.html @@ -0,0 +1,3402 @@ + + + + + + + + + + + + + + + + + + + + + + + BIMS Documentation - BIMS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+ +
+
+ + + +
+
+ + + + + + + +

Adding a Park Layer to the "Add Site" Form

+

This guide will help you fetch the park name from a spatial layer on the "Add Site" form, following the steps outlined below:

+

Inline image

+

Step 1: Upload the Layer

+

As a superuser, navigate to the layer upload page at /upload-spatial-layer/ to upload your shapefiles. When prompted, give the layer an appropriate name based on your needs.

+

Inline image

+

After uploading, wait until the process is completed. The upload status will change to "Success" once it's finished.

+

Step 2: Select the Layer in Site Settings

+

Next, go to the admin page and select Site Setting by visiting /admin/bims/sitesetting/. Click on the first setting that appears.

+

Scroll down to find the Park Layer dropdown, and choose the layer you just uploaded.

+

Step 3: Set the Park Attribute Key

+

Set the Park Attribute Key to specify the attribute you want to use when selecting park names from the layer’s properties.

+

Once all these settings are configured, click Save.

+

Inline image

+

Once all these settings are configured, click Save.

+ + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/administrator/park-layer/img/Screenshot 2024-10-14 at 14.48.33.png b/administrator/park-layer/img/Screenshot 2024-10-14 at 14.48.33.png new file mode 100644 index 0000000..65ce0e3 Binary files /dev/null and b/administrator/park-layer/img/Screenshot 2024-10-14 at 14.48.33.png differ diff --git a/administrator/park-layer/img/Screenshot 2024-10-14 at 14.52.03.png b/administrator/park-layer/img/Screenshot 2024-10-14 at 14.52.03.png new file mode 100644 index 0000000..1f70ac9 Binary files /dev/null and b/administrator/park-layer/img/Screenshot 2024-10-14 at 14.52.03.png differ diff --git a/administrator/park-layer/img/Screenshot 2024-10-14 at 14.53.44.png b/administrator/park-layer/img/Screenshot 2024-10-14 at 14.53.44.png new file mode 100644 index 0000000..7d6f0ff Binary files /dev/null and b/administrator/park-layer/img/Screenshot 2024-10-14 at 14.53.44.png differ diff --git a/administrator/upload-spatial-layers/index.html b/administrator/upload-spatial-layers/index.html new file mode 100644 index 0000000..a9b7671 --- /dev/null +++ b/administrator/upload-spatial-layers/index.html @@ -0,0 +1,1473 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + +
+50. + Skip to content + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

50. BIMS: Upload Spatial Layers

+
+

Note: Only admin/super users can upload spatial layers.

+
+

Click here to access the upload spatial layers page.

+

This is how it looks.

+

Upload Layers UI

+
    +
  • +

    Name: Enter the name of the layer.

    +
  • +
  • +

    Choose files: Select the shape file and auxiliary files to upload.

    +
  • +
  • +

    Submit: Uploads the files.

    +
  • +
  • +

    ❎: Close the form.

    +
  • +
+

50.1 Upload Layers

+

Click on the Choose files button to select the shape file and auxiliary files to upload.

+

Upload Layers UI

+

This will open the file explorer from where user can select the necessary files for their layer.

+
+

Note: Users should select multiple files at the same to upload.

+
+

File Explorer

+
    +
  • +

    Cancel: Cancel the process.

    +
  • +
  • +

    Open: After selecting the files, click on the Open button to upload the files.

    +
  • +
  • +

    ✅ Open files read only: Open the files in read only mode.

    +
  • +
  • +

    None: File extension.

    +
  • +
+

This process will take some time to complete.

+

50.2 413 Request Entity Too Large

+

This error appears when the uploaded files exceeds the maximum size limit.

+

Error

+

50.3 Current Process:

+

50.3.1 Status: Start

+

Indicates that the process has started.

+

Start Status

+

50.3.2 Status: Running

+

Indicates that the process is in progress and may take some time to complete.

+

Running Status

+

50.3.3 Status: Success

+

Indicates that the files have been uploaded successfully.

+

Success Status

+
    +
  • +

    Users will receive a success message.

    +

    Success Status Message

    +
  • +
+

50.3.4 Status: Failed

+

Indicates that the files failed to upload.

+

50.4 Access Editor

+

After successfully completing the process, the user will gain access to the editor page.

+

Click on the Editor button to access the editor page

+

Editor Button

+

This is the UI of the Editor page.

+

Editor UI

+

50.5 Admin page

+
    +
  • +

    To access the admin page, hover on the Administration drop down menu from the top navigation bar.

    +

    Administration tab

    +
  • +
  • +

    Choose the Admin Page option from the drop down menu. This will open the admin page.

    +

    Drop Down Menu

    +
  • +
+

50.5.1 Access the Uploaded Layers

+
    +
  • +

    Navigate to the Cloud Native Layer section from the left menu.

    +

    Cloud Native Layers Section

    +

    Click on the Cloud Native Layer heading to navigate to this section on a new page.

    +

    Cloud Native Layers Section

    +
      +
    1. +

      Layer uploads: By clicking on this, users will be able to see all the uploaded layers.

      +

      Layer Uploads

      +

      1. total: Displays the total number of layers uploaded.

      +

      2. Data: This is the list of uploaded layers with the corresponding details.

      +

      3. Add layer upload: This button is used to upload a new layer.

      +

      4. Filter: By using this, users can filter the data. After clicking on this a dropdown menu will appear.

      +

      Filter

      +
        +
      • +

        Layer: This is used to filter the layers by name.

        +
      • +
      • +

        Status: This filter allows users to arrange the layers by their current status such as success, failed, etc.

        +

        Filter By Status

        +
      • +
      +

      5. Dropdown menu: This menu allows users to perform some actions on the data. This are the available options.

      +

      Dropdown Menu

      +
        +
      • +

        Import data: This option allows users to import the data.

        +
      • +
      • +

        Delete selected layer uploads: This option is used to delete the selected layers. Users can delete multiple layers at once.

        +
      • +
      +

      6. Go: This button allows users to proceed with the actions they have selected from the dropdown menu.

      +
    2. +
    3. +

      Layers: By clicking on this users will be able to see the list of the layers they have uploaded including their details.

      +

      Layers

      +

      1. total: Total number of layers.

      +

      2. Data: This is the list of layers with their details such as id, status, created_by, etc.

      +

      3. Add layer: This button allows users to upload a new layer from the admin panel.

      +

      4. Dropdown menu: This menu allows users to perform some actions on the data. This are the available options.

      +

      Dropdown Menu

      +
        +
      • +

        Delete selected layers: This option is used to delete the selected layers. Users can delete multiple layers at once.

        +
      • +
      • +

        Go: This button allows users to proceed with the actions they have selected from the dropdown menu.

        +
      • +
      +
    4. +
    +
  • +
+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/assets/_mkdocstrings.css b/assets/_mkdocstrings.css new file mode 100644 index 0000000..b500381 --- /dev/null +++ b/assets/_mkdocstrings.css @@ -0,0 +1,143 @@ + +/* Avoid breaking parameter names, etc. in table cells. */ +.doc-contents td code { + word-break: normal !important; +} + +/* No line break before first paragraph of descriptions. */ +.doc-md-description, +.doc-md-description>p:first-child { + display: inline; +} + +/* Max width for docstring sections tables. */ +.doc .md-typeset__table, +.doc .md-typeset__table table { + display: table !important; + width: 100%; +} + +.doc .md-typeset__table tr { + display: table-row; +} + +/* Defaults in Spacy table style. */ +.doc-param-default { + float: right; +} + +/* Parameter headings must be inline, not blocks. */ +.doc-heading-parameter { + display: inline; +} + +/* Prefer space on the right, not the left of parameter permalinks. */ +.doc-heading-parameter .headerlink { + margin-left: 0 !important; + margin-right: 0.2rem; +} + +/* Backward-compatibility: docstring section titles in bold. */ +.doc-section-title { + font-weight: bold; +} + +/* Symbols in Navigation and ToC. */ +:root, :host, +[data-md-color-scheme="default"] { + --doc-symbol-parameter-fg-color: #df50af; + --doc-symbol-attribute-fg-color: #953800; + --doc-symbol-function-fg-color: #8250df; + --doc-symbol-method-fg-color: #8250df; + --doc-symbol-class-fg-color: #0550ae; + --doc-symbol-module-fg-color: #5cad0f; + + --doc-symbol-parameter-bg-color: #df50af1a; + --doc-symbol-attribute-bg-color: #9538001a; + --doc-symbol-function-bg-color: #8250df1a; + --doc-symbol-method-bg-color: #8250df1a; + --doc-symbol-class-bg-color: #0550ae1a; + --doc-symbol-module-bg-color: #5cad0f1a; +} + +[data-md-color-scheme="slate"] { + --doc-symbol-parameter-fg-color: #ffa8cc; + --doc-symbol-attribute-fg-color: #ffa657; + --doc-symbol-function-fg-color: #d2a8ff; + --doc-symbol-method-fg-color: #d2a8ff; + --doc-symbol-class-fg-color: #79c0ff; + --doc-symbol-module-fg-color: #baff79; + + --doc-symbol-parameter-bg-color: #ffa8cc1a; + --doc-symbol-attribute-bg-color: #ffa6571a; + --doc-symbol-function-bg-color: #d2a8ff1a; + --doc-symbol-method-bg-color: #d2a8ff1a; + --doc-symbol-class-bg-color: #79c0ff1a; + --doc-symbol-module-bg-color: #baff791a; +} + +code.doc-symbol { + border-radius: .1rem; + font-size: .85em; + padding: 0 .3em; + font-weight: bold; +} + +code.doc-symbol-parameter { + color: var(--doc-symbol-parameter-fg-color); + background-color: var(--doc-symbol-parameter-bg-color); +} + +code.doc-symbol-parameter::after { + content: "param"; +} + +code.doc-symbol-attribute { + color: var(--doc-symbol-attribute-fg-color); + background-color: var(--doc-symbol-attribute-bg-color); +} + +code.doc-symbol-attribute::after { + content: "attr"; +} + +code.doc-symbol-function { + color: var(--doc-symbol-function-fg-color); + background-color: var(--doc-symbol-function-bg-color); +} + +code.doc-symbol-function::after { + content: "func"; +} + +code.doc-symbol-method { + color: var(--doc-symbol-method-fg-color); + background-color: var(--doc-symbol-method-bg-color); +} + +code.doc-symbol-method::after { + content: "meth"; +} + +code.doc-symbol-class { + color: var(--doc-symbol-class-fg-color); + background-color: var(--doc-symbol-class-bg-color); +} + +code.doc-symbol-class::after { + content: "class"; +} + +code.doc-symbol-module { + color: var(--doc-symbol-module-fg-color); + background-color: var(--doc-symbol-module-bg-color); +} + +code.doc-symbol-module::after { + content: "mod"; +} + +.doc-signature .autorefs { + color: inherit; + border-bottom: 1px dotted currentcolor; +} diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 0000000..1cf13b9 Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.1e8ae164.min.js b/assets/javascripts/bundle.1e8ae164.min.js new file mode 100644 index 0000000..2129798 --- /dev/null +++ b/assets/javascripts/bundle.1e8ae164.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var _i=Object.create;var br=Object.defineProperty;var Ai=Object.getOwnPropertyDescriptor;var Ci=Object.getOwnPropertyNames,Ft=Object.getOwnPropertySymbols,ki=Object.getPrototypeOf,vr=Object.prototype.hasOwnProperty,eo=Object.prototype.propertyIsEnumerable;var Zr=(e,t,r)=>t in e?br(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,F=(e,t)=>{for(var r in t||(t={}))vr.call(t,r)&&Zr(e,r,t[r]);if(Ft)for(var r of Ft(t))eo.call(t,r)&&Zr(e,r,t[r]);return e};var to=(e,t)=>{var r={};for(var o in e)vr.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Ft)for(var o of Ft(e))t.indexOf(o)<0&&eo.call(e,o)&&(r[o]=e[o]);return r};var gr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Hi=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ci(t))!vr.call(e,n)&&n!==r&&br(e,n,{get:()=>t[n],enumerable:!(o=Ai(t,n))||o.enumerable});return e};var jt=(e,t,r)=>(r=e!=null?_i(ki(e)):{},Hi(t||!e||!e.__esModule?br(r,"default",{value:e,enumerable:!0}):r,e));var ro=(e,t,r)=>new Promise((o,n)=>{var i=c=>{try{s(r.next(c))}catch(p){n(p)}},a=c=>{try{s(r.throw(c))}catch(p){n(p)}},s=c=>c.done?o(c.value):Promise.resolve(c.value).then(i,a);s((r=r.apply(e,t)).next())});var no=gr((xr,oo)=>{(function(e,t){typeof xr=="object"&&typeof oo!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(xr,function(){"use strict";function e(r){var o=!0,n=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(C){return!!(C&&C!==document&&C.nodeName!=="HTML"&&C.nodeName!=="BODY"&&"classList"in C&&"contains"in C.classList)}function c(C){var ct=C.type,Ne=C.tagName;return!!(Ne==="INPUT"&&a[ct]&&!C.readOnly||Ne==="TEXTAREA"&&!C.readOnly||C.isContentEditable)}function p(C){C.classList.contains("focus-visible")||(C.classList.add("focus-visible"),C.setAttribute("data-focus-visible-added",""))}function l(C){C.hasAttribute("data-focus-visible-added")&&(C.classList.remove("focus-visible"),C.removeAttribute("data-focus-visible-added"))}function f(C){C.metaKey||C.altKey||C.ctrlKey||(s(r.activeElement)&&p(r.activeElement),o=!0)}function u(C){o=!1}function h(C){s(C.target)&&(o||c(C.target))&&p(C.target)}function w(C){s(C.target)&&(C.target.classList.contains("focus-visible")||C.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(C.target))}function A(C){document.visibilityState==="hidden"&&(n&&(o=!0),Z())}function Z(){document.addEventListener("mousemove",J),document.addEventListener("mousedown",J),document.addEventListener("mouseup",J),document.addEventListener("pointermove",J),document.addEventListener("pointerdown",J),document.addEventListener("pointerup",J),document.addEventListener("touchmove",J),document.addEventListener("touchstart",J),document.addEventListener("touchend",J)}function te(){document.removeEventListener("mousemove",J),document.removeEventListener("mousedown",J),document.removeEventListener("mouseup",J),document.removeEventListener("pointermove",J),document.removeEventListener("pointerdown",J),document.removeEventListener("pointerup",J),document.removeEventListener("touchmove",J),document.removeEventListener("touchstart",J),document.removeEventListener("touchend",J)}function J(C){C.target.nodeName&&C.target.nodeName.toLowerCase()==="html"||(o=!1,te())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",A,!0),Z(),r.addEventListener("focus",h,!0),r.addEventListener("blur",w,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var zr=gr((kt,Vr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof kt=="object"&&typeof Vr=="object"?Vr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof kt=="object"?kt.ClipboardJS=r():t.ClipboardJS=r()})(kt,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return Li}});var a=i(279),s=i.n(a),c=i(370),p=i.n(c),l=i(817),f=i.n(l);function u(D){try{return document.execCommand(D)}catch(M){return!1}}var h=function(M){var O=f()(M);return u("cut"),O},w=h;function A(D){var M=document.documentElement.getAttribute("dir")==="rtl",O=document.createElement("textarea");O.style.fontSize="12pt",O.style.border="0",O.style.padding="0",O.style.margin="0",O.style.position="absolute",O.style[M?"right":"left"]="-9999px";var I=window.pageYOffset||document.documentElement.scrollTop;return O.style.top="".concat(I,"px"),O.setAttribute("readonly",""),O.value=D,O}var Z=function(M,O){var I=A(M);O.container.appendChild(I);var W=f()(I);return u("copy"),I.remove(),W},te=function(M){var O=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},I="";return typeof M=="string"?I=Z(M,O):M instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(M==null?void 0:M.type)?I=Z(M.value,O):(I=f()(M),u("copy")),I},J=te;function C(D){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?C=function(O){return typeof O}:C=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},C(D)}var ct=function(){var M=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},O=M.action,I=O===void 0?"copy":O,W=M.container,K=M.target,Ce=M.text;if(I!=="copy"&&I!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(K!==void 0)if(K&&C(K)==="object"&&K.nodeType===1){if(I==="copy"&&K.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(I==="cut"&&(K.hasAttribute("readonly")||K.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Ce)return J(Ce,{container:W});if(K)return I==="cut"?w(K):J(K,{container:W})},Ne=ct;function Pe(D){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Pe=function(O){return typeof O}:Pe=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},Pe(D)}function xi(D,M){if(!(D instanceof M))throw new TypeError("Cannot call a class as a function")}function Xr(D,M){for(var O=0;O0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof W.action=="function"?W.action:this.defaultAction,this.target=typeof W.target=="function"?W.target:this.defaultTarget,this.text=typeof W.text=="function"?W.text:this.defaultText,this.container=Pe(W.container)==="object"?W.container:document.body}},{key:"listenClick",value:function(W){var K=this;this.listener=p()(W,"click",function(Ce){return K.onClick(Ce)})}},{key:"onClick",value:function(W){var K=W.delegateTarget||W.currentTarget,Ce=this.action(K)||"copy",It=Ne({action:Ce,container:this.container,target:this.target(K),text:this.text(K)});this.emit(It?"success":"error",{action:Ce,text:It,trigger:K,clearSelection:function(){K&&K.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(W){return hr("action",W)}},{key:"defaultTarget",value:function(W){var K=hr("target",W);if(K)return document.querySelector(K)}},{key:"defaultText",value:function(W){return hr("text",W)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(W){var K=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return J(W,K)}},{key:"cut",value:function(W){return w(W)}},{key:"isSupported",value:function(){var W=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],K=typeof W=="string"?[W]:W,Ce=!!document.queryCommandSupported;return K.forEach(function(It){Ce=Ce&&!!document.queryCommandSupported(It)}),Ce}}]),O}(s()),Li=Mi},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,c){for(;s&&s.nodeType!==n;){if(typeof s.matches=="function"&&s.matches(c))return s;s=s.parentNode}}o.exports=a},438:function(o,n,i){var a=i(828);function s(l,f,u,h,w){var A=p.apply(this,arguments);return l.addEventListener(u,A,w),{destroy:function(){l.removeEventListener(u,A,w)}}}function c(l,f,u,h,w){return typeof l.addEventListener=="function"?s.apply(null,arguments):typeof u=="function"?s.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(A){return s(A,f,u,h,w)}))}function p(l,f,u,h){return function(w){w.delegateTarget=a(w.target,f),w.delegateTarget&&h.call(l,w)}}o.exports=c},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(o,n,i){var a=i(879),s=i(438);function c(u,h,w){if(!u&&!h&&!w)throw new Error("Missing required arguments");if(!a.string(h))throw new TypeError("Second argument must be a String");if(!a.fn(w))throw new TypeError("Third argument must be a Function");if(a.node(u))return p(u,h,w);if(a.nodeList(u))return l(u,h,w);if(a.string(u))return f(u,h,w);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function p(u,h,w){return u.addEventListener(h,w),{destroy:function(){u.removeEventListener(h,w)}}}function l(u,h,w){return Array.prototype.forEach.call(u,function(A){A.addEventListener(h,w)}),{destroy:function(){Array.prototype.forEach.call(u,function(A){A.removeEventListener(h,w)})}}}function f(u,h,w){return s(document.body,u,h,w)}o.exports=c},817:function(o){function n(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),p=document.createRange();p.selectNodeContents(i),c.removeAllRanges(),c.addRange(p),a=c.toString()}return a}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,a,s){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var c=this;function p(){c.off(i,p),a.apply(s,arguments)}return p._=a,this.on(i,p,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),c=0,p=s.length;for(c;c{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var Va=/["'&<>]/;qn.exports=za;function za(e){var t=""+e,r=Va.exec(t);if(!r)return t;var o,n="",i=0,a=0;for(i=r.index;i0&&i[i.length-1])&&(p[0]===6||p[0]===2)){r=0;continue}if(p[0]===3&&(!i||p[1]>i[0]&&p[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function V(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],a;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(s){a={error:s}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(a)throw a.error}}return i}function z(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||s(u,h)})})}function s(u,h){try{c(o[u](h))}catch(w){f(i[0][3],w)}}function c(u){u.value instanceof ot?Promise.resolve(u.value.v).then(p,l):f(i[0][2],u)}function p(u){s("next",u)}function l(u){s("throw",u)}function f(u,h){u(h),i.shift(),i.length&&s(i[0][0],i[0][1])}}function so(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof ue=="function"?ue(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(a){return new Promise(function(s,c){a=e[i](a),n(s,c,a.done,a.value)})}}function n(i,a,s,c){Promise.resolve(c).then(function(p){i({value:p,done:s})},a)}}function k(e){return typeof e=="function"}function pt(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var Wt=pt(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Ve(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Ie=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var a=this._parentage;if(a)if(this._parentage=null,Array.isArray(a))try{for(var s=ue(a),c=s.next();!c.done;c=s.next()){var p=c.value;p.remove(this)}}catch(A){t={error:A}}finally{try{c&&!c.done&&(r=s.return)&&r.call(s)}finally{if(t)throw t.error}}else a.remove(this);var l=this.initialTeardown;if(k(l))try{l()}catch(A){i=A instanceof Wt?A.errors:[A]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=ue(f),h=u.next();!h.done;h=u.next()){var w=h.value;try{co(w)}catch(A){i=i!=null?i:[],A instanceof Wt?i=z(z([],V(i)),V(A.errors)):i.push(A)}}}catch(A){o={error:A}}finally{try{h&&!h.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new Wt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)co(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Ve(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Ve(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Er=Ie.EMPTY;function Dt(e){return e instanceof Ie||e&&"closed"in e&&k(e.remove)&&k(e.add)&&k(e.unsubscribe)}function co(e){k(e)?e():e.unsubscribe()}var ke={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var lt={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,a=n.isStopped,s=n.observers;return i||a?Er:(this.currentObservers=null,s.push(r),new Ie(function(){o.currentObservers=null,Ve(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,a=o.isStopped;n?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new j;return r.source=this,r},t.create=function(r,o){return new vo(r,o)},t}(j);var vo=function(e){se(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:Er},t}(g);var St={now:function(){return(St.delegate||Date).now()},delegate:void 0};var Ot=function(e){se(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=St);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,a=o._infiniteTimeWindow,s=o._timestampProvider,c=o._windowTime;n||(i.push(r),!a&&i.push(s.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,a=n._buffer,s=a.slice(),c=0;c0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=ut.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var a=r.actions;o!=null&&((i=a[a.length-1])===null||i===void 0?void 0:i.id)!==o&&(ut.cancelAnimationFrame(o),r._scheduled=void 0)},t}(zt);var yo=function(e){se(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(qt);var de=new yo(xo);var L=new j(function(e){return e.complete()});function Kt(e){return e&&k(e.schedule)}function _r(e){return e[e.length-1]}function Je(e){return k(_r(e))?e.pop():void 0}function Ae(e){return Kt(_r(e))?e.pop():void 0}function Qt(e,t){return typeof _r(e)=="number"?e.pop():t}var dt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Yt(e){return k(e==null?void 0:e.then)}function Bt(e){return k(e[ft])}function Gt(e){return Symbol.asyncIterator&&k(e==null?void 0:e[Symbol.asyncIterator])}function Jt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Di(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Xt=Di();function Zt(e){return k(e==null?void 0:e[Xt])}function er(e){return ao(this,arguments,function(){var r,o,n,i;return Ut(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,ot(r.read())];case 3:return o=a.sent(),n=o.value,i=o.done,i?[4,ot(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,ot(n)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function tr(e){return k(e==null?void 0:e.getReader)}function N(e){if(e instanceof j)return e;if(e!=null){if(Bt(e))return Ni(e);if(dt(e))return Vi(e);if(Yt(e))return zi(e);if(Gt(e))return Eo(e);if(Zt(e))return qi(e);if(tr(e))return Ki(e)}throw Jt(e)}function Ni(e){return new j(function(t){var r=e[ft]();if(k(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Vi(e){return new j(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?b(function(n,i){return e(n,i,o)}):ce,ye(1),r?Qe(t):jo(function(){return new or}))}}function $r(e){return e<=0?function(){return L}:x(function(t,r){var o=[];t.subscribe(S(r,function(n){o.push(n),e=2,!0))}function le(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new g}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,c=s===void 0?!0:s;return function(p){var l,f,u,h=0,w=!1,A=!1,Z=function(){f==null||f.unsubscribe(),f=void 0},te=function(){Z(),l=u=void 0,w=A=!1},J=function(){var C=l;te(),C==null||C.unsubscribe()};return x(function(C,ct){h++,!A&&!w&&Z();var Ne=u=u!=null?u:r();ct.add(function(){h--,h===0&&!A&&!w&&(f=Pr(J,c))}),Ne.subscribe(ct),!l&&h>0&&(l=new it({next:function(Pe){return Ne.next(Pe)},error:function(Pe){A=!0,Z(),f=Pr(te,n,Pe),Ne.error(Pe)},complete:function(){w=!0,Z(),f=Pr(te,a),Ne.complete()}}),N(C).subscribe(l))})(p)}}function Pr(e,t){for(var r=[],o=2;oe.next(document)),e}function R(e,t=document){return Array.from(t.querySelectorAll(e))}function P(e,t=document){let r=me(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function me(e,t=document){return t.querySelector(e)||void 0}function Re(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var la=T(d(document.body,"focusin"),d(document.body,"focusout")).pipe(be(1),q(void 0),m(()=>Re()||document.body),B(1));function vt(e){return la.pipe(m(t=>e.contains(t)),Y())}function Vo(e,t){return T(d(e,"mouseenter").pipe(m(()=>!0)),d(e,"mouseleave").pipe(m(()=>!1))).pipe(t?be(t):ce,q(!1))}function Ue(e){return{x:e.offsetLeft,y:e.offsetTop}}function zo(e){return T(d(window,"load"),d(window,"resize")).pipe(Me(0,de),m(()=>Ue(e)),q(Ue(e)))}function ir(e){return{x:e.scrollLeft,y:e.scrollTop}}function et(e){return T(d(e,"scroll"),d(window,"resize")).pipe(Me(0,de),m(()=>ir(e)),q(ir(e)))}function qo(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)qo(e,r)}function E(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)qo(o,n);return o}function ar(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function gt(e){let t=E("script",{src:e});return H(()=>(document.head.appendChild(t),T(d(t,"load"),d(t,"error").pipe(v(()=>Ar(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),_(()=>document.head.removeChild(t)),ye(1))))}var Ko=new g,ma=H(()=>typeof ResizeObserver=="undefined"?gt("https://unpkg.com/resize-observer-polyfill"):$(void 0)).pipe(m(()=>new ResizeObserver(e=>{for(let t of e)Ko.next(t)})),v(e=>T(qe,$(e)).pipe(_(()=>e.disconnect()))),B(1));function pe(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Ee(e){return ma.pipe(y(t=>t.observe(e)),v(t=>Ko.pipe(b(({target:r})=>r===e),_(()=>t.unobserve(e)),m(()=>pe(e)))),q(pe(e)))}function xt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function sr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var Qo=new g,fa=H(()=>$(new IntersectionObserver(e=>{for(let t of e)Qo.next(t)},{threshold:0}))).pipe(v(e=>T(qe,$(e)).pipe(_(()=>e.disconnect()))),B(1));function yt(e){return fa.pipe(y(t=>t.observe(e)),v(t=>Qo.pipe(b(({target:r})=>r===e),_(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function Yo(e,t=16){return et(e).pipe(m(({y:r})=>{let o=pe(e),n=xt(e);return r>=n.height-o.height-t}),Y())}var cr={drawer:P("[data-md-toggle=drawer]"),search:P("[data-md-toggle=search]")};function Bo(e){return cr[e].checked}function Be(e,t){cr[e].checked!==t&&cr[e].click()}function We(e){let t=cr[e];return d(t,"change").pipe(m(()=>t.checked),q(t.checked))}function ua(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function da(){return T(d(window,"compositionstart").pipe(m(()=>!0)),d(window,"compositionend").pipe(m(()=>!1))).pipe(q(!1))}function Go(){let e=d(window,"keydown").pipe(b(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:Bo("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),b(({mode:t,type:r})=>{if(t==="global"){let o=Re();if(typeof o!="undefined")return!ua(o,r)}return!0}),le());return da().pipe(v(t=>t?L:e))}function ve(){return new URL(location.href)}function st(e,t=!1){if(G("navigation.instant")&&!t){let r=E("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function Jo(){return new g}function Xo(){return location.hash.slice(1)}function Zo(e){let t=E("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function ha(e){return T(d(window,"hashchange"),e).pipe(m(Xo),q(Xo()),b(t=>t.length>0),B(1))}function en(e){return ha(e).pipe(m(t=>me(`[id="${t}"]`)),b(t=>typeof t!="undefined"))}function At(e){let t=matchMedia(e);return nr(r=>t.addListener(()=>r(t.matches))).pipe(q(t.matches))}function tn(){let e=matchMedia("print");return T(d(window,"beforeprint").pipe(m(()=>!0)),d(window,"afterprint").pipe(m(()=>!1))).pipe(q(e.matches))}function Ur(e,t){return e.pipe(v(r=>r?t():L))}function Wr(e,t){return new j(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let a=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+a*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function De(e,t){return Wr(e,t).pipe(v(r=>r.text()),m(r=>JSON.parse(r)),B(1))}function rn(e,t){let r=new DOMParser;return Wr(e,t).pipe(v(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),B(1))}function on(e,t){let r=new DOMParser;return Wr(e,t).pipe(v(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),B(1))}function nn(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function an(){return T(d(window,"scroll",{passive:!0}),d(window,"resize",{passive:!0})).pipe(m(nn),q(nn()))}function sn(){return{width:innerWidth,height:innerHeight}}function cn(){return d(window,"resize",{passive:!0}).pipe(m(sn),q(sn()))}function pn(){return Q([an(),cn()]).pipe(m(([e,t])=>({offset:e,size:t})),B(1))}function pr(e,{viewport$:t,header$:r}){let o=t.pipe(X("size")),n=Q([o,r]).pipe(m(()=>Ue(e)));return Q([r,t,n]).pipe(m(([{height:i},{offset:a,size:s},{x:c,y:p}])=>({offset:{x:a.x-c,y:a.y-p+i},size:s})))}function ba(e){return d(e,"message",t=>t.data)}function va(e){let t=new g;return t.subscribe(r=>e.postMessage(r)),t}function ln(e,t=new Worker(e)){let r=ba(t),o=va(t),n=new g;n.subscribe(o);let i=o.pipe(ee(),oe(!0));return n.pipe(ee(),$e(r.pipe(U(i))),le())}var ga=P("#__config"),Et=JSON.parse(ga.textContent);Et.base=`${new URL(Et.base,ve())}`;function we(){return Et}function G(e){return Et.features.includes(e)}function ge(e,t){return typeof t!="undefined"?Et.translations[e].replace("#",t.toString()):Et.translations[e]}function Te(e,t=document){return P(`[data-md-component=${e}]`,t)}function ie(e,t=document){return R(`[data-md-component=${e}]`,t)}function xa(e){let t=P(".md-typeset > :first-child",e);return d(t,"click",{once:!0}).pipe(m(()=>P(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function mn(e){if(!G("announce.dismiss")||!e.childElementCount)return L;if(!e.hidden){let t=P(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return H(()=>{let t=new g;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),xa(e).pipe(y(r=>t.next(r)),_(()=>t.complete()),m(r=>F({ref:e},r)))})}function ya(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function fn(e,t){let r=new g;return r.subscribe(({hidden:o})=>{e.hidden=o}),ya(e,t).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))}function Ct(e,t){return t==="inline"?E("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},E("div",{class:"md-tooltip__inner md-typeset"})):E("div",{class:"md-tooltip",id:e,role:"tooltip"},E("div",{class:"md-tooltip__inner md-typeset"}))}function un(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return E("aside",{class:"md-annotation",tabIndex:0},Ct(t),E("a",{href:r,class:"md-annotation__index",tabIndex:-1},E("span",{"data-md-annotation-id":e})))}else return E("aside",{class:"md-annotation",tabIndex:0},Ct(t),E("span",{class:"md-annotation__index",tabIndex:-1},E("span",{"data-md-annotation-id":e})))}function dn(e){return E("button",{class:"md-clipboard md-icon",title:ge("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}function Dr(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(c=>!e.terms[c]).reduce((c,p)=>[...c,E("del",null,p)," "],[]).slice(0,-1),i=we(),a=new URL(e.location,i.base);G("search.highlight")&&a.searchParams.set("h",Object.entries(e.terms).filter(([,c])=>c).reduce((c,[p])=>`${c} ${p}`.trim(),""));let{tags:s}=we();return E("a",{href:`${a}`,class:"md-search-result__link",tabIndex:-1},E("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&E("div",{class:"md-search-result__icon md-icon"}),r>0&&E("h1",null,e.title),r<=0&&E("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(c=>{let p=s?c in s?`md-tag-icon md-tag--${s[c]}`:"md-tag-icon":"";return E("span",{class:`md-tag ${p}`},c)}),o>0&&n.length>0&&E("p",{class:"md-search-result__terms"},ge("search.result.term.missing"),": ",...n)))}function hn(e){let t=e[0].score,r=[...e],o=we(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),a=r.findIndex(l=>l.scoreDr(l,1)),...c.length?[E("details",{class:"md-search-result__more"},E("summary",{tabIndex:-1},E("div",null,c.length>0&&c.length===1?ge("search.result.more.one"):ge("search.result.more.other",c.length))),...c.map(l=>Dr(l,1)))]:[]];return E("li",{class:"md-search-result__item"},p)}function bn(e){return E("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>E("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?ar(r):r)))}function Nr(e){let t=`tabbed-control tabbed-control--${e}`;return E("div",{class:t,hidden:!0},E("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function vn(e){return E("div",{class:"md-typeset__scrollwrap"},E("div",{class:"md-typeset__table"},e))}function Ea(e){let t=we(),r=new URL(`../${e.version}/`,t.base);return E("li",{class:"md-version__item"},E("a",{href:`${r}`,class:"md-version__link"},e.title))}function gn(e,t){return e=e.filter(r=>{var o;return!((o=r.properties)!=null&&o.hidden)}),E("div",{class:"md-version"},E("button",{class:"md-version__current","aria-label":ge("select.version")},t.title),E("ul",{class:"md-version__list"},e.map(Ea)))}var wa=0;function Ta(e,t){document.body.append(e);let{width:r}=pe(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=sr(t),n=typeof o!="undefined"?et(o):$({x:0,y:0}),i=T(vt(t),Vo(t)).pipe(Y());return Q([i,n]).pipe(m(([a,s])=>{let{x:c,y:p}=Ue(t),l=pe(t),f=t.closest("table");return f&&t.parentElement&&(c+=f.offsetLeft+t.parentElement.offsetLeft,p+=f.offsetTop+t.parentElement.offsetTop),{active:a,offset:{x:c-s.x+l.width/2-r/2,y:p-s.y+l.height+8}}}))}function Ge(e){let t=e.title;if(!t.length)return L;let r=`__tooltip_${wa++}`,o=Ct(r,"inline"),n=P(".md-typeset",o);return n.innerHTML=t,H(()=>{let i=new g;return i.subscribe({next({offset:a}){o.style.setProperty("--md-tooltip-x",`${a.x}px`),o.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),T(i.pipe(b(({active:a})=>a)),i.pipe(be(250),b(({active:a})=>!a))).subscribe({next({active:a}){a?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe(Me(16,de)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(_t(125,de),b(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?o.style.setProperty("--md-tooltip-0",`${-a}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),Ta(o,e).pipe(y(a=>i.next(a)),_(()=>i.complete()),m(a=>F({ref:e},a)))}).pipe(ze(ae))}function Sa(e,t){let r=H(()=>Q([zo(e),et(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:a,height:s}=pe(e);return{x:o-i.x+a/2,y:n-i.y+s/2}}));return vt(e).pipe(v(o=>r.pipe(m(n=>({active:o,offset:n})),ye(+!o||1/0))))}function xn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return H(()=>{let i=new g,a=i.pipe(ee(),oe(!0));return i.subscribe({next({offset:s}){e.style.setProperty("--md-tooltip-x",`${s.x}px`),e.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),yt(e).pipe(U(a)).subscribe(s=>{e.toggleAttribute("data-md-visible",s)}),T(i.pipe(b(({active:s})=>s)),i.pipe(be(250),b(({active:s})=>!s))).subscribe({next({active:s}){s?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe(Me(16,de)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(_t(125,de),b(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?e.style.setProperty("--md-tooltip-0",`${-s}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),d(n,"click").pipe(U(a),b(s=>!(s.metaKey||s.ctrlKey))).subscribe(s=>{s.stopPropagation(),s.preventDefault()}),d(n,"mousedown").pipe(U(a),ne(i)).subscribe(([s,{active:c}])=>{var p;if(s.button!==0||s.metaKey||s.ctrlKey)s.preventDefault();else if(c){s.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(p=Re())==null||p.blur()}}),r.pipe(U(a),b(s=>s===o),Ye(125)).subscribe(()=>e.focus()),Sa(e,t).pipe(y(s=>i.next(s)),_(()=>i.complete()),m(s=>F({ref:e},s)))})}function Oa(e){return e.tagName==="CODE"?R(".c, .c1, .cm",e):[e]}function Ma(e){let t=[];for(let r of Oa(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let a;for(;a=/(\(\d+\))(!)?/.exec(i.textContent);){let[,s,c]=a;if(typeof c=="undefined"){let p=i.splitText(a.index);i=p.splitText(s.length),t.push(p)}else{i.textContent=s,t.push(i);break}}}}return t}function yn(e,t){t.append(...Array.from(e.childNodes))}function lr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,a=new Map;for(let s of Ma(t)){let[,c]=s.textContent.match(/\((\d+)\)/);me(`:scope > li:nth-child(${c})`,e)&&(a.set(c,un(c,i)),s.replaceWith(a.get(c)))}return a.size===0?L:H(()=>{let s=new g,c=s.pipe(ee(),oe(!0)),p=[];for(let[l,f]of a)p.push([P(".md-typeset",f),P(`:scope > li:nth-child(${l})`,e)]);return o.pipe(U(c)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of p)l?yn(f,u):yn(u,f)}),T(...[...a].map(([,l])=>xn(l,t,{target$:r}))).pipe(_(()=>s.complete()),le())})}function En(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return En(t)}}function wn(e,t){return H(()=>{let r=En(e);return typeof r!="undefined"?lr(r,e,t):L})}var Tn=jt(zr());var La=0;function Sn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Sn(t)}}function _a(e){return Ee(e).pipe(m(({width:t})=>({scrollable:xt(e).width>t})),X("scrollable"))}function On(e,t){let{matches:r}=matchMedia("(hover)"),o=H(()=>{let n=new g,i=n.pipe($r(1));n.subscribe(({scrollable:c})=>{c&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let a=[];if(Tn.default.isSupported()&&(e.closest(".copy")||G("content.code.copy")&&!e.closest(".no-copy"))){let c=e.closest("pre");c.id=`__code_${La++}`;let p=dn(c.id);c.insertBefore(p,e),G("content.tooltips")&&a.push(Ge(p))}let s=e.closest(".highlight");if(s instanceof HTMLElement){let c=Sn(s);if(typeof c!="undefined"&&(s.classList.contains("annotate")||G("content.code.annotate"))){let p=lr(c,e,t);a.push(Ee(s).pipe(U(i),m(({width:l,height:f})=>l&&f),Y(),v(l=>l?p:L)))}}return _a(e).pipe(y(c=>n.next(c)),_(()=>n.complete()),m(c=>F({ref:e},c)),$e(...a))});return G("content.lazy")?yt(e).pipe(b(n=>n),ye(1),v(()=>o)):o}function Aa(e,{target$:t,print$:r}){let o=!0;return T(t.pipe(m(n=>n.closest("details:not([open])")),b(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(b(n=>n||!o),y(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function Mn(e,t){return H(()=>{let r=new g;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),Aa(e,t).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))})}var Ln=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var qr,ka=0;function Ha(){return typeof mermaid=="undefined"||mermaid instanceof Element?gt("https://unpkg.com/mermaid@10.7.0/dist/mermaid.min.js"):$(void 0)}function _n(e){return e.classList.remove("mermaid"),qr||(qr=Ha().pipe(y(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Ln,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),B(1))),qr.subscribe(()=>ro(this,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${ka++}`,r=E("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),a=r.attachShadow({mode:"closed"});a.innerHTML=n,e.replaceWith(r),i==null||i(a)})),qr.pipe(m(()=>({ref:e})))}var An=E("table");function Cn(e){return e.replaceWith(An),An.replaceWith(vn(e)),$({ref:e})}function $a(e){let t=e.find(r=>r.checked)||e[0];return T(...e.map(r=>d(r,"change").pipe(m(()=>P(`label[for="${r.id}"]`))))).pipe(q(P(`label[for="${t.id}"]`)),m(r=>({active:r})))}function kn(e,{viewport$:t,target$:r}){let o=P(".tabbed-labels",e),n=R(":scope > input",e),i=Nr("prev");e.append(i);let a=Nr("next");return e.append(a),H(()=>{let s=new g,c=s.pipe(ee(),oe(!0));Q([s,Ee(e)]).pipe(U(c),Me(1,de)).subscribe({next([{active:p},l]){let f=Ue(p),{width:u}=pe(p);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let h=ir(o);(f.xh.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),Q([et(o),Ee(o)]).pipe(U(c)).subscribe(([p,l])=>{let f=xt(o);i.hidden=p.x<16,a.hidden=p.x>f.width-l.width-16}),T(d(i,"click").pipe(m(()=>-1)),d(a,"click").pipe(m(()=>1))).pipe(U(c)).subscribe(p=>{let{width:l}=pe(o);o.scrollBy({left:l*p,behavior:"smooth"})}),r.pipe(U(c),b(p=>n.includes(p))).subscribe(p=>p.click()),o.classList.add("tabbed-labels--linked");for(let p of n){let l=P(`label[for="${p.id}"]`);l.replaceChildren(E("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),d(l.firstElementChild,"click").pipe(U(c),b(f=>!(f.metaKey||f.ctrlKey)),y(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return G("content.tabs.link")&&s.pipe(Le(1),ne(t)).subscribe(([{active:p},{offset:l}])=>{let f=p.innerText.trim();if(p.hasAttribute("data-md-switching"))p.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let w of R("[data-tabs]"))for(let A of R(":scope > input",w)){let Z=P(`label[for="${A.id}"]`);if(Z!==p&&Z.innerText.trim()===f){Z.setAttribute("data-md-switching",""),A.click();break}}window.scrollTo({top:e.offsetTop-u});let h=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...h])])}}),s.pipe(U(c)).subscribe(()=>{for(let p of R("audio, video",e))p.pause()}),$a(n).pipe(y(p=>s.next(p)),_(()=>s.complete()),m(p=>F({ref:e},p)))}).pipe(ze(ae))}function Hn(e,{viewport$:t,target$:r,print$:o}){return T(...R(".annotate:not(.highlight)",e).map(n=>wn(n,{target$:r,print$:o})),...R("pre:not(.mermaid) > code",e).map(n=>On(n,{target$:r,print$:o})),...R("pre.mermaid",e).map(n=>_n(n)),...R("table:not([class])",e).map(n=>Cn(n)),...R("details",e).map(n=>Mn(n,{target$:r,print$:o})),...R("[data-tabs]",e).map(n=>kn(n,{viewport$:t,target$:r})),...R("[title]",e).filter(()=>G("content.tooltips")).map(n=>Ge(n)))}function Ra(e,{alert$:t}){return t.pipe(v(r=>T($(!0),$(!1).pipe(Ye(2e3))).pipe(m(o=>({message:r,active:o})))))}function $n(e,t){let r=P(".md-typeset",e);return H(()=>{let o=new g;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),Ra(e,t).pipe(y(n=>o.next(n)),_(()=>o.complete()),m(n=>F({ref:e},n)))})}function Pa({viewport$:e}){if(!G("header.autohide"))return $(!1);let t=e.pipe(m(({offset:{y:n}})=>n),Ke(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),Y()),o=We("search");return Q([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),Y(),v(n=>n?r:$(!1)),q(!1))}function Rn(e,t){return H(()=>Q([Ee(e),Pa(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),Y((r,o)=>r.height===o.height&&r.hidden===o.hidden),B(1))}function Pn(e,{header$:t,main$:r}){return H(()=>{let o=new g,n=o.pipe(ee(),oe(!0));o.pipe(X("active"),je(t)).subscribe(([{active:a},{hidden:s}])=>{e.classList.toggle("md-header--shadow",a&&!s),e.hidden=s});let i=fe(R("[title]",e)).pipe(b(()=>G("content.tooltips")),re(a=>Ge(a)));return r.subscribe(o),t.pipe(U(n),m(a=>F({ref:e},a)),$e(i.pipe(U(n))))})}function Ia(e,{viewport$:t,header$:r}){return pr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=pe(e);return{active:o>=n}}),X("active"))}function In(e,t){return H(()=>{let r=new g;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=me(".md-content h1");return typeof o=="undefined"?L:Ia(o,t).pipe(y(n=>r.next(n)),_(()=>r.complete()),m(n=>F({ref:e},n)))})}function Fn(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),Y()),n=o.pipe(v(()=>Ee(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),X("bottom"))));return Q([o,n,t]).pipe(m(([i,{top:a,bottom:s},{offset:{y:c},size:{height:p}}])=>(p=Math.max(0,p-Math.max(0,a-c,i)-Math.max(0,p+c-s)),{offset:a-i,height:p,active:a-i<=c})),Y((i,a)=>i.offset===a.offset&&i.height===a.height&&i.active===a.active))}function Fa(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return $(...e).pipe(re(o=>d(o,"change").pipe(m(()=>o))),q(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),B(1))}function jn(e){let t=R("input",e),r=E("meta",{name:"theme-color"});document.head.appendChild(r);let o=E("meta",{name:"color-scheme"});document.head.appendChild(o);let n=At("(prefers-color-scheme: light)");return H(()=>{let i=new g;return i.subscribe(a=>{if(document.body.setAttribute("data-md-color-switching",""),a.color.media==="(prefers-color-scheme)"){let s=matchMedia("(prefers-color-scheme: light)"),c=document.querySelector(s.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");a.color.scheme=c.getAttribute("data-md-color-scheme"),a.color.primary=c.getAttribute("data-md-color-primary"),a.color.accent=c.getAttribute("data-md-color-accent")}for(let[s,c]of Object.entries(a.color))document.body.setAttribute(`data-md-color-${s}`,c);for(let s=0;sa.key==="Enter"),ne(i,(a,s)=>s)).subscribe(({index:a})=>{a=(a+1)%t.length,t[a].click(),t[a].focus()}),i.pipe(m(()=>{let a=Te("header"),s=window.getComputedStyle(a);return o.content=s.colorScheme,s.backgroundColor.match(/\d+/g).map(c=>(+c).toString(16).padStart(2,"0")).join("")})).subscribe(a=>r.content=`#${a}`),i.pipe(Oe(ae)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),Fa(t).pipe(U(n.pipe(Le(1))),at(),y(a=>i.next(a)),_(()=>i.complete()),m(a=>F({ref:e},a)))})}function Un(e,{progress$:t}){return H(()=>{let r=new g;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(y(o=>r.next({value:o})),_(()=>r.complete()),m(o=>({ref:e,value:o})))})}var Kr=jt(zr());function ja(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function Wn({alert$:e}){Kr.default.isSupported()&&new j(t=>{new Kr.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||ja(P(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(y(t=>{t.trigger.focus()}),m(()=>ge("clipboard.copied"))).subscribe(e)}function Dn(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function Ua(e,t){let r=new Map;for(let o of R("url",e)){let n=P("loc",o),i=[Dn(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let a of R("[rel=alternate]",o)){let s=a.getAttribute("href");s!=null&&i.push(Dn(new URL(s),t))}}return r}function mr(e){return on(new URL("sitemap.xml",e)).pipe(m(t=>Ua(t,new URL(e))),he(()=>$(new Map)))}function Wa(e,t){if(!(e.target instanceof Element))return L;let r=e.target.closest("a");if(r===null)return L;if(r.target||e.metaKey||e.ctrlKey)return L;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),$(new URL(r.href))):L}function Nn(e){let t=new Map;for(let r of R(":scope > *",e.head))t.set(r.outerHTML,r);return t}function Vn(e){for(let t of R("[href], [src]",e))for(let r of["href","src"]){let o=t.getAttribute(r);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){t[r]=t[r];break}}return $(e)}function Da(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...G("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=me(o),i=me(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=Nn(document);for(let[o,n]of Nn(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values()){let n=o.getAttribute("name");n!=="theme-color"&&n!=="color-scheme"&&o.remove()}let r=Te("container");return Fe(R("script",r)).pipe(v(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new j(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),L}),ee(),oe(document))}function zn({location$:e,viewport$:t,progress$:r}){let o=we();if(location.protocol==="file:")return L;let n=mr(o.base);$(document).subscribe(Vn);let i=d(document.body,"click").pipe(je(n),v(([c,p])=>Wa(c,p)),le()),a=d(window,"popstate").pipe(m(ve),le());i.pipe(ne(t)).subscribe(([c,{offset:p}])=>{history.replaceState(p,""),history.pushState(null,"",c)}),T(i,a).subscribe(e);let s=e.pipe(X("pathname"),v(c=>rn(c,{progress$:r}).pipe(he(()=>(st(c,!0),L)))),v(Vn),v(Da),le());return T(s.pipe(ne(e,(c,p)=>p)),e.pipe(X("pathname"),v(()=>e),X("hash")),e.pipe(Y((c,p)=>c.pathname===p.pathname&&c.hash===p.hash),v(()=>i),y(()=>history.back()))).subscribe(c=>{var p,l;history.state!==null||!c.hash?window.scrollTo(0,(l=(p=history.state)==null?void 0:p.y)!=null?l:0):(history.scrollRestoration="auto",Zo(c.hash),history.scrollRestoration="manual")}),e.subscribe(()=>{history.scrollRestoration="manual"}),d(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),t.pipe(X("offset"),be(100)).subscribe(({offset:c})=>{history.replaceState(c,"")}),s}var Qn=jt(Kn());function Yn(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,a)=>`${i}${a}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return a=>(0,Qn.default)(a).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function Ht(e){return e.type===1}function fr(e){return e.type===3}function Bn(e,t){let r=ln(e);return T($(location.protocol!=="file:"),We("search")).pipe(He(o=>o),v(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:G("search.suggest")}}})),r}function Gn({document$:e}){let t=we(),r=De(new URL("../versions.json",t.base)).pipe(he(()=>L)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:a,aliases:s})=>a===i||s.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),v(n=>d(document.body,"click").pipe(b(i=>!i.metaKey&&!i.ctrlKey),ne(o),v(([i,a])=>{if(i.target instanceof Element){let s=i.target.closest("a");if(s&&!s.target&&n.has(s.href)){let c=s.href;return!i.target.closest(".md-version")&&n.get(c)===a?L:(i.preventDefault(),$(c))}}return L}),v(i=>{let{version:a}=n.get(i);return mr(new URL(i)).pipe(m(s=>{let p=ve().href.replace(t.base,"");return s.has(p.split("#")[0])?new URL(`../${a}/${p}`,t.base):new URL(i)}))})))).subscribe(n=>st(n,!0)),Q([r,o]).subscribe(([n,i])=>{P(".md-header__topic").appendChild(gn(n,i))}),e.pipe(v(()=>o)).subscribe(n=>{var a;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let s=((a=t.version)==null?void 0:a.default)||"latest";Array.isArray(s)||(s=[s]);e:for(let c of s)for(let p of n.aliases.concat(n.version))if(new RegExp(c,"i").test(p)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let s of ie("outdated"))s.hidden=!1})}function Ka(e,{worker$:t}){let{searchParams:r}=ve();r.has("q")&&(Be("search",!0),e.value=r.get("q"),e.focus(),We("search").pipe(He(i=>!i)).subscribe(()=>{let i=ve();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=vt(e),n=T(t.pipe(He(Ht)),d(e,"keyup"),o).pipe(m(()=>e.value),Y());return Q([n,o]).pipe(m(([i,a])=>({value:i,focus:a})),B(1))}function Jn(e,{worker$:t}){let r=new g,o=r.pipe(ee(),oe(!0));Q([t.pipe(He(Ht)),r],(i,a)=>a).pipe(X("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(X("focus")).subscribe(({focus:i})=>{i&&Be("search",i)}),d(e.form,"reset").pipe(U(o)).subscribe(()=>e.focus());let n=P("header [for=__search]");return d(n,"click").subscribe(()=>e.focus()),Ka(e,{worker$:t}).pipe(y(i=>r.next(i)),_(()=>r.complete()),m(i=>F({ref:e},i)),B(1))}function Xn(e,{worker$:t,query$:r}){let o=new g,n=Yo(e.parentElement).pipe(b(Boolean)),i=e.parentElement,a=P(":scope > :first-child",e),s=P(":scope > :last-child",e);We("search").subscribe(l=>s.setAttribute("role",l?"list":"presentation")),o.pipe(ne(r),Ir(t.pipe(He(Ht)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:a.textContent=f.length?ge("search.result.none"):ge("search.result.placeholder");break;case 1:a.textContent=ge("search.result.one");break;default:let u=ar(l.length);a.textContent=ge("search.result.other",u)}});let c=o.pipe(y(()=>s.innerHTML=""),v(({items:l})=>T($(...l.slice(0,10)),$(...l.slice(10)).pipe(Ke(4),jr(n),v(([f])=>f)))),m(hn),le());return c.subscribe(l=>s.appendChild(l)),c.pipe(re(l=>{let f=me("details",l);return typeof f=="undefined"?L:d(f,"toggle").pipe(U(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(b(fr),m(({data:l})=>l)).pipe(y(l=>o.next(l)),_(()=>o.complete()),m(l=>F({ref:e},l)))}function Qa(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=ve();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function Zn(e,t){let r=new g,o=r.pipe(ee(),oe(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),d(e,"click").pipe(U(o)).subscribe(n=>n.preventDefault()),Qa(e,t).pipe(y(n=>r.next(n)),_(()=>r.complete()),m(n=>F({ref:e},n)))}function ei(e,{worker$:t,keyboard$:r}){let o=new g,n=Te("search-query"),i=T(d(n,"keydown"),d(n,"focus")).pipe(Oe(ae),m(()=>n.value),Y());return o.pipe(je(i),m(([{suggest:s},c])=>{let p=c.split(/([\s-]+)/);if(s!=null&&s.length&&p[p.length-1]){let l=s[s.length-1];l.startsWith(p[p.length-1])&&(p[p.length-1]=l)}else p.length=0;return p})).subscribe(s=>e.innerHTML=s.join("").replace(/\s/g," ")),r.pipe(b(({mode:s})=>s==="search")).subscribe(s=>{switch(s.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(b(fr),m(({data:s})=>s)).pipe(y(s=>o.next(s)),_(()=>o.complete()),m(()=>({ref:e})))}function ti(e,{index$:t,keyboard$:r}){let o=we();try{let n=Bn(o.search,t),i=Te("search-query",e),a=Te("search-result",e);d(e,"click").pipe(b(({target:c})=>c instanceof Element&&!!c.closest("a"))).subscribe(()=>Be("search",!1)),r.pipe(b(({mode:c})=>c==="search")).subscribe(c=>{let p=Re();switch(c.type){case"Enter":if(p===i){let l=new Map;for(let f of R(":first-child [href]",a)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,h])=>h-u);f.click()}c.claim()}break;case"Escape":case"Tab":Be("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof p=="undefined")i.focus();else{let l=[i,...R(":not(details) > [href], summary, details[open] [href]",a)],f=Math.max(0,(Math.max(0,l.indexOf(p))+l.length+(c.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}c.claim();break;default:i!==Re()&&i.focus()}}),r.pipe(b(({mode:c})=>c==="global")).subscribe(c=>{switch(c.type){case"f":case"s":case"/":i.focus(),i.select(),c.claim();break}});let s=Jn(i,{worker$:n});return T(s,Xn(a,{worker$:n,query$:s})).pipe($e(...ie("search-share",e).map(c=>Zn(c,{query$:s})),...ie("search-suggest",e).map(c=>ei(c,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,qe}}function ri(e,{index$:t,location$:r}){return Q([t,r.pipe(q(ve()),b(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>Yn(o.config)(n.searchParams.get("h"))),m(o=>{var a;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let s=i.nextNode();s;s=i.nextNode())if((a=s.parentElement)!=null&&a.offsetHeight){let c=s.textContent,p=o(c);p.length>c.length&&n.set(s,p)}for(let[s,c]of n){let{childNodes:p}=E("span",null,c);s.replaceWith(...Array.from(p))}return{ref:e,nodes:n}}))}function Ya(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return Q([r,t]).pipe(m(([{offset:i,height:a},{offset:{y:s}}])=>(a=a+Math.min(n,Math.max(0,s-i))-n,{height:a,locked:s>=i+n})),Y((i,a)=>i.height===a.height&&i.locked===a.locked))}function Qr(e,o){var n=o,{header$:t}=n,r=to(n,["header$"]);let i=P(".md-sidebar__scrollwrap",e),{y:a}=Ue(i);return H(()=>{let s=new g,c=s.pipe(ee(),oe(!0)),p=s.pipe(Me(0,de));return p.pipe(ne(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*a}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),p.pipe(He()).subscribe(()=>{for(let l of R(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=pe(f);f.scrollTo({top:u-h/2})}}}),fe(R("label[tabindex]",e)).pipe(re(l=>d(l,"click").pipe(Oe(ae),m(()=>l),U(c)))).subscribe(l=>{let f=P(`[id="${l.htmlFor}"]`);P(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),Ya(e,r).pipe(y(l=>s.next(l)),_(()=>s.complete()),m(l=>F({ref:e},l)))})}function oi(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return Lt(De(`${r}/releases/latest`).pipe(he(()=>L),m(o=>({version:o.tag_name})),Qe({})),De(r).pipe(he(()=>L),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),Qe({}))).pipe(m(([o,n])=>F(F({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return De(r).pipe(m(o=>({repositories:o.public_repos})),Qe({}))}}function ni(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return De(r).pipe(he(()=>L),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),Qe({}))}function ii(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return oi(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return ni(r,o)}return L}var Ba;function Ga(e){return Ba||(Ba=H(()=>{let t=__md_get("__source",sessionStorage);if(t)return $(t);if(ie("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return L}return ii(e.href).pipe(y(o=>__md_set("__source",o,sessionStorage)))}).pipe(he(()=>L),b(t=>Object.keys(t).length>0),m(t=>({facts:t})),B(1)))}function ai(e){let t=P(":scope > :last-child",e);return H(()=>{let r=new g;return r.subscribe(({facts:o})=>{t.appendChild(bn(o)),t.classList.add("md-source__repository--active")}),Ga(e).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))})}function Ja(e,{viewport$:t,header$:r}){return Ee(document.body).pipe(v(()=>pr(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),X("hidden"))}function si(e,t){return H(()=>{let r=new g;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(G("navigation.tabs.sticky")?$({hidden:!1}):Ja(e,t)).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))})}function Xa(e,{viewport$:t,header$:r}){let o=new Map,n=R(".md-nav__link",e);for(let s of n){let c=decodeURIComponent(s.hash.substring(1)),p=me(`[id="${c}"]`);typeof p!="undefined"&&o.set(s,p)}let i=r.pipe(X("height"),m(({height:s})=>{let c=Te("main"),p=P(":scope > :first-child",c);return s+.8*(p.offsetTop-c.offsetTop)}),le());return Ee(document.body).pipe(X("height"),v(s=>H(()=>{let c=[];return $([...o].reduce((p,[l,f])=>{for(;c.length&&o.get(c[c.length-1]).tagName>=f.tagName;)c.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let h=f.offsetParent;for(;h;h=h.offsetParent)u+=h.offsetTop;return p.set([...c=[...c,l]].reverse(),u)},new Map))}).pipe(m(c=>new Map([...c].sort(([,p],[,l])=>p-l))),je(i),v(([c,p])=>t.pipe(Rr(([l,f],{offset:{y:u},size:h})=>{let w=u+h.height>=Math.floor(s.height);for(;f.length;){let[,A]=f[0];if(A-p=u&&!w)f=[l.pop(),...f];else break}return[l,f]},[[],[...c]]),Y((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([s,c])=>({prev:s.map(([p])=>p),next:c.map(([p])=>p)})),q({prev:[],next:[]}),Ke(2,1),m(([s,c])=>s.prev.length{let i=new g,a=i.pipe(ee(),oe(!0));if(i.subscribe(({prev:s,next:c})=>{for(let[p]of c)p.classList.remove("md-nav__link--passed"),p.classList.remove("md-nav__link--active");for(let[p,[l]]of s.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",p===s.length-1)}),G("toc.follow")){let s=T(t.pipe(be(1),m(()=>{})),t.pipe(be(250),m(()=>"smooth")));i.pipe(b(({prev:c})=>c.length>0),je(o.pipe(Oe(ae))),ne(s)).subscribe(([[{prev:c}],p])=>{let[l]=c[c.length-1];if(l.offsetHeight){let f=sr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=pe(f);f.scrollTo({top:u-h/2,behavior:p})}}})}return G("navigation.tracking")&&t.pipe(U(a),X("offset"),be(250),Le(1),U(n.pipe(Le(1))),at({delay:250}),ne(i)).subscribe(([,{prev:s}])=>{let c=ve(),p=s[s.length-1];if(p&&p.length){let[l]=p,{hash:f}=new URL(l.href);c.hash!==f&&(c.hash=f,history.replaceState({},"",`${c}`))}else c.hash="",history.replaceState({},"",`${c}`)}),Xa(e,{viewport$:t,header$:r}).pipe(y(s=>i.next(s)),_(()=>i.complete()),m(s=>F({ref:e},s)))})}function Za(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:a}})=>a),Ke(2,1),m(([a,s])=>a>s&&s>0),Y()),i=r.pipe(m(({active:a})=>a));return Q([i,n]).pipe(m(([a,s])=>!(a&&s)),Y(),U(o.pipe(Le(1))),oe(!0),at({delay:250}),m(a=>({hidden:a})))}function pi(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new g,a=i.pipe(ee(),oe(!0));return i.subscribe({next({hidden:s}){e.hidden=s,s?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(U(a),X("height")).subscribe(({height:s})=>{e.style.top=`${s+16}px`}),d(e,"click").subscribe(s=>{s.preventDefault(),window.scrollTo({top:0})}),Za(e,{viewport$:t,main$:o,target$:n}).pipe(y(s=>i.next(s)),_(()=>i.complete()),m(s=>F({ref:e},s)))}function li({document$:e}){e.pipe(v(()=>R(".md-ellipsis")),re(t=>yt(t).pipe(U(e.pipe(Le(1))),b(r=>r),m(()=>t),ye(1))),b(t=>t.offsetWidth{let r=t.innerText,o=t.closest("a")||t;return o.title=r,Ge(o).pipe(U(e.pipe(Le(1))),_(()=>o.removeAttribute("title")))})).subscribe(),e.pipe(v(()=>R(".md-status")),re(t=>Ge(t))).subscribe()}function mi({document$:e,tablet$:t}){e.pipe(v(()=>R(".md-toggle--indeterminate")),y(r=>{r.indeterminate=!0,r.checked=!1}),re(r=>d(r,"change").pipe(Fr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),ne(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function es(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function fi({document$:e}){e.pipe(v(()=>R("[data-md-scrollfix]")),y(t=>t.removeAttribute("data-md-scrollfix")),b(es),re(t=>d(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function ui({viewport$:e,tablet$:t}){Q([We("search"),t]).pipe(m(([r,o])=>r&&!o),v(r=>$(r).pipe(Ye(r?400:100))),ne(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function ts(){return location.protocol==="file:"?gt(`${new URL("search/search_index.js",Yr.base)}`).pipe(m(()=>__index),B(1)):De(new URL("search/search_index.json",Yr.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var rt=No(),Rt=Jo(),wt=en(Rt),Br=Go(),_e=pn(),ur=At("(min-width: 960px)"),hi=At("(min-width: 1220px)"),bi=tn(),Yr=we(),vi=document.forms.namedItem("search")?ts():qe,Gr=new g;Wn({alert$:Gr});var Jr=new g;G("navigation.instant")&&zn({location$:Rt,viewport$:_e,progress$:Jr}).subscribe(rt);var di;((di=Yr.version)==null?void 0:di.provider)==="mike"&&Gn({document$:rt});T(Rt,wt).pipe(Ye(125)).subscribe(()=>{Be("drawer",!1),Be("search",!1)});Br.pipe(b(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=me("link[rel=prev]");typeof t!="undefined"&&st(t);break;case"n":case".":let r=me("link[rel=next]");typeof r!="undefined"&&st(r);break;case"Enter":let o=Re();o instanceof HTMLLabelElement&&o.click()}});li({document$:rt});mi({document$:rt,tablet$:ur});fi({document$:rt});ui({viewport$:_e,tablet$:ur});var tt=Rn(Te("header"),{viewport$:_e}),$t=rt.pipe(m(()=>Te("main")),v(e=>Fn(e,{viewport$:_e,header$:tt})),B(1)),rs=T(...ie("consent").map(e=>fn(e,{target$:wt})),...ie("dialog").map(e=>$n(e,{alert$:Gr})),...ie("header").map(e=>Pn(e,{viewport$:_e,header$:tt,main$:$t})),...ie("palette").map(e=>jn(e)),...ie("progress").map(e=>Un(e,{progress$:Jr})),...ie("search").map(e=>ti(e,{index$:vi,keyboard$:Br})),...ie("source").map(e=>ai(e))),os=H(()=>T(...ie("announce").map(e=>mn(e)),...ie("content").map(e=>Hn(e,{viewport$:_e,target$:wt,print$:bi})),...ie("content").map(e=>G("search.highlight")?ri(e,{index$:vi,location$:Rt}):L),...ie("header-title").map(e=>In(e,{viewport$:_e,header$:tt})),...ie("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Ur(hi,()=>Qr(e,{viewport$:_e,header$:tt,main$:$t})):Ur(ur,()=>Qr(e,{viewport$:_e,header$:tt,main$:$t}))),...ie("tabs").map(e=>si(e,{viewport$:_e,header$:tt})),...ie("toc").map(e=>ci(e,{viewport$:_e,header$:tt,main$:$t,target$:wt})),...ie("top").map(e=>pi(e,{viewport$:_e,header$:tt,main$:$t,target$:wt})))),gi=rt.pipe(v(()=>os),$e(rs),B(1));gi.subscribe();window.document$=rt;window.location$=Rt;window.target$=wt;window.keyboard$=Br;window.viewport$=_e;window.tablet$=ur;window.screen$=hi;window.print$=bi;window.alert$=Gr;window.progress$=Jr;window.component$=gi;})(); +//# sourceMappingURL=bundle.1e8ae164.min.js.map + diff --git a/assets/javascripts/bundle.1e8ae164.min.js.map b/assets/javascripts/bundle.1e8ae164.min.js.map new file mode 100644 index 0000000..6c33b8e --- /dev/null +++ b/assets/javascripts/bundle.1e8ae164.min.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/clipboard/dist/clipboard.js", "node_modules/escape-html/index.js", "src/templates/assets/javascripts/bundle.ts", "node_modules/rxjs/node_modules/tslib/tslib.es6.js", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/EmptyError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/throwIfEmpty.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/first.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/templates/assets/javascripts/browser/document/index.ts", "src/templates/assets/javascripts/browser/element/_/index.ts", "src/templates/assets/javascripts/browser/element/focus/index.ts", "src/templates/assets/javascripts/browser/element/hover/index.ts", "src/templates/assets/javascripts/browser/element/offset/_/index.ts", "src/templates/assets/javascripts/browser/element/offset/content/index.ts", "src/templates/assets/javascripts/utilities/h/index.ts", "src/templates/assets/javascripts/utilities/round/index.ts", "src/templates/assets/javascripts/browser/script/index.ts", "src/templates/assets/javascripts/browser/element/size/_/index.ts", "src/templates/assets/javascripts/browser/element/size/content/index.ts", "src/templates/assets/javascripts/browser/element/visibility/index.ts", "src/templates/assets/javascripts/browser/toggle/index.ts", "src/templates/assets/javascripts/browser/keyboard/index.ts", "src/templates/assets/javascripts/browser/location/_/index.ts", "src/templates/assets/javascripts/browser/location/hash/index.ts", "src/templates/assets/javascripts/browser/media/index.ts", "src/templates/assets/javascripts/browser/request/index.ts", "src/templates/assets/javascripts/browser/viewport/offset/index.ts", "src/templates/assets/javascripts/browser/viewport/size/index.ts", "src/templates/assets/javascripts/browser/viewport/_/index.ts", "src/templates/assets/javascripts/browser/viewport/at/index.ts", "src/templates/assets/javascripts/browser/worker/index.ts", "src/templates/assets/javascripts/_/index.ts", "src/templates/assets/javascripts/components/_/index.ts", "src/templates/assets/javascripts/components/announce/index.ts", "src/templates/assets/javascripts/components/consent/index.ts", "src/templates/assets/javascripts/templates/tooltip/index.tsx", "src/templates/assets/javascripts/templates/annotation/index.tsx", "src/templates/assets/javascripts/templates/clipboard/index.tsx", "src/templates/assets/javascripts/templates/search/index.tsx", "src/templates/assets/javascripts/templates/source/index.tsx", "src/templates/assets/javascripts/templates/tabbed/index.tsx", "src/templates/assets/javascripts/templates/table/index.tsx", "src/templates/assets/javascripts/templates/version/index.tsx", "src/templates/assets/javascripts/components/tooltip/index.ts", "src/templates/assets/javascripts/components/content/annotation/_/index.ts", "src/templates/assets/javascripts/components/content/annotation/list/index.ts", "src/templates/assets/javascripts/components/content/annotation/block/index.ts", "src/templates/assets/javascripts/components/content/code/_/index.ts", "src/templates/assets/javascripts/components/content/details/index.ts", "src/templates/assets/javascripts/components/content/mermaid/index.css", "src/templates/assets/javascripts/components/content/mermaid/index.ts", "src/templates/assets/javascripts/components/content/table/index.ts", "src/templates/assets/javascripts/components/content/tabs/index.ts", "src/templates/assets/javascripts/components/content/_/index.ts", "src/templates/assets/javascripts/components/dialog/index.ts", "src/templates/assets/javascripts/components/header/_/index.ts", "src/templates/assets/javascripts/components/header/title/index.ts", "src/templates/assets/javascripts/components/main/index.ts", "src/templates/assets/javascripts/components/palette/index.ts", "src/templates/assets/javascripts/components/progress/index.ts", "src/templates/assets/javascripts/integrations/clipboard/index.ts", "src/templates/assets/javascripts/integrations/sitemap/index.ts", "src/templates/assets/javascripts/integrations/instant/index.ts", "src/templates/assets/javascripts/integrations/search/highlighter/index.ts", "src/templates/assets/javascripts/integrations/search/worker/message/index.ts", "src/templates/assets/javascripts/integrations/search/worker/_/index.ts", "src/templates/assets/javascripts/integrations/version/index.ts", "src/templates/assets/javascripts/components/search/query/index.ts", "src/templates/assets/javascripts/components/search/result/index.ts", "src/templates/assets/javascripts/components/search/share/index.ts", "src/templates/assets/javascripts/components/search/suggest/index.ts", "src/templates/assets/javascripts/components/search/_/index.ts", "src/templates/assets/javascripts/components/search/highlight/index.ts", "src/templates/assets/javascripts/components/sidebar/index.ts", "src/templates/assets/javascripts/components/source/facts/github/index.ts", "src/templates/assets/javascripts/components/source/facts/gitlab/index.ts", "src/templates/assets/javascripts/components/source/facts/_/index.ts", "src/templates/assets/javascripts/components/source/_/index.ts", "src/templates/assets/javascripts/components/tabs/index.ts", "src/templates/assets/javascripts/components/toc/index.ts", "src/templates/assets/javascripts/components/top/index.ts", "src/templates/assets/javascripts/patches/ellipsis/index.ts", "src/templates/assets/javascripts/patches/indeterminate/index.ts", "src/templates/assets/javascripts/patches/scrollfix/index.ts", "src/templates/assets/javascripts/patches/scrolllock/index.ts", "src/templates/assets/javascripts/polyfills/index.ts"], + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "/*!\n * clipboard.js v2.0.11\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Create fake copy action wrapper using a fake element.\n * @param {String} target\n * @param {Object} options\n * @return {String}\n */\n\nvar fakeCopyAction = function fakeCopyAction(value, options) {\n var fakeElement = createFakeElement(value);\n options.container.appendChild(fakeElement);\n var selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n return selectedText;\n};\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n selectedText = fakeCopyAction(target, options);\n } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {\n // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n selectedText = fakeCopyAction(target.value, options);\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*\n * Copyright (c) 2016-2024 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"focus-visible\"\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getActiveElement,\n getOptionalElement,\n requestJSON,\n setLocation,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchScript,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountAnnounce,\n mountBackToTop,\n mountConsent,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountProgress,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantNavigation,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchEllipsis,\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Functions - @todo refactor\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch search index\n *\n * @returns Search index observable\n */\nfunction fetchSearchIndex(): Observable {\n if (location.protocol === \"file:\") {\n return watchScript(\n `${new URL(\"search/search_index.js\", config.base)}`\n )\n .pipe(\n // @ts-ignore - @todo fix typings\n map(() => __index),\n shareReplay(1)\n )\n } else {\n return requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget(location$)\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? fetchSearchIndex()\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up progress indicator */\nconst progress$ = new Subject()\n\n/* Set up instant navigation, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantNavigation({ location$, viewport$, progress$ })\n .subscribe(document$)\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"link[rel=prev]\")\n if (typeof prev !== \"undefined\")\n setLocation(prev)\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"link[rel=next]\")\n if (typeof next !== \"undefined\")\n setLocation(next)\n break\n\n /* Expand navigation, see https://bit.ly/3ZjG5io */\n case \"Enter\":\n const active = getActiveElement()\n if (active instanceof HTMLLabelElement)\n active.click()\n }\n })\n\n/* Set up patches */\npatchEllipsis({ document$ })\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Consent */\n ...getComponentElements(\"consent\")\n .map(el => mountConsent(el, { target$ })),\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Progress bar */\n ...getComponentElements(\"progress\")\n .map(el => mountProgress(el, { progress$ })),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Announcement bar */\n ...getComponentElements(\"announce\")\n .map(el => mountAnnounce(el)),\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { viewport$, target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, {\n viewport$, header$, main$, target$\n })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.progress$ = progress$ /* Progress indicator subject */\nwindow.component$ = component$ /* Component observable */\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n", "/**\n * Returns true if the object is a function.\n * @param value The value to check\n */\nexport function isFunction(value: any): value is (...args: any[]) => any {\n return typeof value === 'function';\n}\n", "/**\n * Used to create Error subclasses until the community moves away from ES5.\n *\n * This is because compiling from TypeScript down to ES5 has issues with subclassing Errors\n * as well as other built-in types: https://github.com/Microsoft/TypeScript/issues/12123\n *\n * @param createImpl A factory function to create the actual constructor implementation. The returned\n * function should be a named function that calls `_super` internally.\n */\nexport function createErrorClass(createImpl: (_super: any) => any): T {\n const _super = (instance: any) => {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n\n const ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface UnsubscriptionError extends Error {\n readonly errors: any[];\n}\n\nexport interface UnsubscriptionErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (errors: any[]): UnsubscriptionError;\n}\n\n/**\n * An error thrown when one or more errors have occurred during the\n * `unsubscribe` of a {@link Subscription}.\n */\nexport const UnsubscriptionError: UnsubscriptionErrorCtor = createErrorClass(\n (_super) =>\n function UnsubscriptionErrorImpl(this: any, errors: (Error | string)[]) {\n _super(this);\n this.message = errors\n ? `${errors.length} errors occurred during unsubscription:\n${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\\n ')}`\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n }\n);\n", "/**\n * Removes an item from an array, mutating it.\n * @param arr The array to remove the item from\n * @param item The item to remove\n */\nexport function arrRemove(arr: T[] | undefined | null, item: T) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { SubscriptionLike, TeardownLogic, Unsubscribable } from './types';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * Represents a disposable resource, such as the execution of an Observable. A\n * Subscription has one important method, `unsubscribe`, that takes no argument\n * and just disposes the resource held by the subscription.\n *\n * Additionally, subscriptions may be grouped together through the `add()`\n * method, which will attach a child Subscription to the current Subscription.\n * When a Subscription is unsubscribed, all its children (and its grandchildren)\n * will be unsubscribed as well.\n *\n * @class Subscription\n */\nexport class Subscription implements SubscriptionLike {\n /** @nocollapse */\n public static EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n })();\n\n /**\n * A flag to indicate whether this Subscription has already been unsubscribed.\n */\n public closed = false;\n\n private _parentage: Subscription[] | Subscription | null = null;\n\n /**\n * The list of registered finalizers to execute upon unsubscription. Adding and removing from this\n * list occurs in the {@link #add} and {@link #remove} methods.\n */\n private _finalizers: Exclude[] | null = null;\n\n /**\n * @param initialTeardown A function executed first as part of the finalization\n * process that is kicked off when {@link #unsubscribe} is called.\n */\n constructor(private initialTeardown?: () => void) {}\n\n /**\n * Disposes the resources held by the subscription. May, for instance, cancel\n * an ongoing Observable execution or cancel any other type of work that\n * started when the Subscription was created.\n * @return {void}\n */\n unsubscribe(): void {\n let errors: any[] | undefined;\n\n if (!this.closed) {\n this.closed = true;\n\n // Remove this from it's parents.\n const { _parentage } = this;\n if (_parentage) {\n this._parentage = null;\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n } else {\n _parentage.remove(this);\n }\n }\n\n const { initialTeardown: initialFinalizer } = this;\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n } catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n\n const { _finalizers } = this;\n if (_finalizers) {\n this._finalizers = null;\n for (const finalizer of _finalizers) {\n try {\n execFinalizer(finalizer);\n } catch (err) {\n errors = errors ?? [];\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n } else {\n errors.push(err);\n }\n }\n }\n }\n\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n\n /**\n * Adds a finalizer to this subscription, so that finalization will be unsubscribed/called\n * when this subscription is unsubscribed. If this subscription is already {@link #closed},\n * because it has already been unsubscribed, then whatever finalizer is passed to it\n * will automatically be executed (unless the finalizer itself is also a closed subscription).\n *\n * Closed Subscriptions cannot be added as finalizers to any subscription. Adding a closed\n * subscription to a any subscription will result in no operation. (A noop).\n *\n * Adding a subscription to itself, or adding `null` or `undefined` will not perform any\n * operation at all. (A noop).\n *\n * `Subscription` instances that are added to this instance will automatically remove themselves\n * if they are unsubscribed. Functions and {@link Unsubscribable} objects that you wish to remove\n * will need to be removed manually with {@link #remove}\n *\n * @param teardown The finalization logic to add to this subscription.\n */\n add(teardown: TeardownLogic): void {\n // Only add the finalizer if it's not undefined\n // and don't add a subscription to itself.\n if (teardown && teardown !== this) {\n if (this.closed) {\n // If this subscription is already closed,\n // execute whatever finalizer is handed to it automatically.\n execFinalizer(teardown);\n } else {\n if (teardown instanceof Subscription) {\n // We don't add closed subscriptions, and we don't add the same subscription\n // twice. Subscription unsubscribe is idempotent.\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._finalizers = this._finalizers ?? []).push(teardown);\n }\n }\n }\n\n /**\n * Checks to see if a this subscription already has a particular parent.\n * This will signal that this subscription has already been added to the parent in question.\n * @param parent the parent to check for\n */\n private _hasParent(parent: Subscription) {\n const { _parentage } = this;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n }\n\n /**\n * Adds a parent to this subscription so it can be removed from the parent if it\n * unsubscribes on it's own.\n *\n * NOTE: THIS ASSUMES THAT {@link _hasParent} HAS ALREADY BEEN CHECKED.\n * @param parent The parent subscription to add\n */\n private _addParent(parent: Subscription) {\n const { _parentage } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n\n /**\n * Called on a child when it is removed via {@link #remove}.\n * @param parent The parent to remove\n */\n private _removeParent(parent: Subscription) {\n const { _parentage } = this;\n if (_parentage === parent) {\n this._parentage = null;\n } else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n\n /**\n * Removes a finalizer from this subscription that was previously added with the {@link #add} method.\n *\n * Note that `Subscription` instances, when unsubscribed, will automatically remove themselves\n * from every other `Subscription` they have been added to. This means that using the `remove` method\n * is not a common thing and should be used thoughtfully.\n *\n * If you add the same finalizer instance of a function or an unsubscribable object to a `Subscription` instance\n * more than once, you will need to call `remove` the same number of times to remove all instances.\n *\n * All finalizer instances are removed to free up memory upon unsubscription.\n *\n * @param teardown The finalizer to remove from this subscription\n */\n remove(teardown: Exclude): void {\n const { _finalizers } = this;\n _finalizers && arrRemove(_finalizers, teardown);\n\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n}\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\n\nexport function isSubscription(value: any): value is Subscription {\n return (\n value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe))\n );\n}\n\nfunction execFinalizer(finalizer: Unsubscribable | (() => void)) {\n if (isFunction(finalizer)) {\n finalizer();\n } else {\n finalizer.unsubscribe();\n }\n}\n", "import { Subscriber } from './Subscriber';\nimport { ObservableNotification } from './types';\n\n/**\n * The {@link GlobalConfig} object for RxJS. It is used to configure things\n * like how to react on unhandled errors.\n */\nexport const config: GlobalConfig = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n\n/**\n * The global configuration object for RxJS, used to configure things\n * like how to react on unhandled errors. Accessible via {@link config}\n * object.\n */\nexport interface GlobalConfig {\n /**\n * A registration point for unhandled errors from RxJS. These are errors that\n * cannot were not handled by consuming code in the usual subscription path. For\n * example, if you have this configured, and you subscribe to an observable without\n * providing an error handler, errors from that subscription will end up here. This\n * will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onUnhandledError: ((err: any) => void) | null;\n\n /**\n * A registration point for notifications that cannot be sent to subscribers because they\n * have completed, errored or have been explicitly unsubscribed. By default, next, complete\n * and error notifications sent to stopped subscribers are noops. However, sometimes callers\n * might want a different behavior. For example, with sources that attempt to report errors\n * to stopped subscribers, a caller can configure RxJS to throw an unhandled error instead.\n * This will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onStoppedNotification: ((notification: ObservableNotification, subscriber: Subscriber) => void) | null;\n\n /**\n * The promise constructor used by default for {@link Observable#toPromise toPromise} and {@link Observable#forEach forEach}\n * methods.\n *\n * @deprecated As of version 8, RxJS will no longer support this sort of injection of a\n * Promise constructor. If you need a Promise implementation other than native promises,\n * please polyfill/patch Promise as you see appropriate. Will be removed in v8.\n */\n Promise?: PromiseConstructorLike;\n\n /**\n * If true, turns on synchronous error rethrowing, which is a deprecated behavior\n * in v6 and higher. This behavior enables bad patterns like wrapping a subscribe\n * call in a try/catch block. It also enables producer interference, a nasty bug\n * where a multicast can be broken for all observers by a downstream consumer with\n * an unhandled error. DO NOT USE THIS FLAG UNLESS IT'S NEEDED TO BUY TIME\n * FOR MIGRATION REASONS.\n *\n * @deprecated As of version 8, RxJS will no longer support synchronous throwing\n * of unhandled errors. All errors will be thrown on a separate call stack to prevent bad\n * behaviors described above. Will be removed in v8.\n */\n useDeprecatedSynchronousErrorHandling: boolean;\n\n /**\n * If true, enables an as-of-yet undocumented feature from v5: The ability to access\n * `unsubscribe()` via `this` context in `next` functions created in observers passed\n * to `subscribe`.\n *\n * This is being removed because the performance was severely problematic, and it could also cause\n * issues when types other than POJOs are passed to subscribe as subscribers, as they will likely have\n * their `this` context overwritten.\n *\n * @deprecated As of version 8, RxJS will no longer support altering the\n * context of next functions provided as part of an observer to Subscribe. Instead,\n * you will have access to a subscription or a signal or token that will allow you to do things like\n * unsubscribe and test closed status. Will be removed in v8.\n */\n useDeprecatedNextContext: boolean;\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearTimeoutFunction = (handle: TimerHandle) => void;\n\ninterface TimeoutProvider {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n delegate:\n | {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n }\n | undefined;\n}\n\nexport const timeoutProvider: TimeoutProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setTimeout(handler: () => void, timeout?: number, ...args) {\n const { delegate } = timeoutProvider;\n if (delegate?.setTimeout) {\n return delegate.setTimeout(handler, timeout, ...args);\n }\n return setTimeout(handler, timeout, ...args);\n },\n clearTimeout(handle) {\n const { delegate } = timeoutProvider;\n return (delegate?.clearTimeout || clearTimeout)(handle as any);\n },\n delegate: undefined,\n};\n", "import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\n\n/**\n * Handles an error on another job either with the user-configured {@link onUnhandledError},\n * or by throwing it on that new job so it can be picked up by `window.onerror`, `process.on('error')`, etc.\n *\n * This should be called whenever there is an error that is out-of-band with the subscription\n * or when an error hits a terminal boundary of the subscription and no error handler was provided.\n *\n * @param err the error to report\n */\nexport function reportUnhandledError(err: any) {\n timeoutProvider.setTimeout(() => {\n const { onUnhandledError } = config;\n if (onUnhandledError) {\n // Execute the user-configured error handler.\n onUnhandledError(err);\n } else {\n // Throw so it is picked up by the runtime's uncaught error mechanism.\n throw err;\n }\n });\n}\n", "/* tslint:disable:no-empty */\nexport function noop() { }\n", "import { CompleteNotification, NextNotification, ErrorNotification } from './types';\n\n/**\n * A completion object optimized for memory use and created to be the\n * same \"shape\" as other notifications in v8.\n * @internal\n */\nexport const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined) as CompleteNotification)();\n\n/**\n * Internal use only. Creates an optimized error notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function errorNotification(error: any): ErrorNotification {\n return createNotification('E', undefined, error) as any;\n}\n\n/**\n * Internal use only. Creates an optimized next notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function nextNotification(value: T) {\n return createNotification('N', value, undefined) as NextNotification;\n}\n\n/**\n * Ensures that all notifications created internally have the same \"shape\" in v8.\n *\n * TODO: This is only exported to support a crazy legacy test in `groupBy`.\n * @internal\n */\nexport function createNotification(kind: 'N' | 'E' | 'C', value: any, error: any) {\n return {\n kind,\n value,\n error,\n };\n}\n", "import { config } from '../config';\n\nlet context: { errorThrown: boolean; error: any } | null = null;\n\n/**\n * Handles dealing with errors for super-gross mode. Creates a context, in which\n * any synchronously thrown errors will be passed to {@link captureError}. Which\n * will record the error such that it will be rethrown after the call back is complete.\n * TODO: Remove in v8\n * @param cb An immediately executed function.\n */\nexport function errorContext(cb: () => void) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n const isRoot = !context;\n if (isRoot) {\n context = { errorThrown: false, error: null };\n }\n cb();\n if (isRoot) {\n const { errorThrown, error } = context!;\n context = null;\n if (errorThrown) {\n throw error;\n }\n }\n } else {\n // This is the general non-deprecated path for everyone that\n // isn't crazy enough to use super-gross mode (useDeprecatedSynchronousErrorHandling)\n cb();\n }\n}\n\n/**\n * Captures errors only in super-gross mode.\n * @param err the error to capture\n */\nexport function captureError(err: any) {\n if (config.useDeprecatedSynchronousErrorHandling && context) {\n context.errorThrown = true;\n context.error = err;\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { Observer, ObservableNotification } from './types';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\n\n/**\n * Implements the {@link Observer} interface and extends the\n * {@link Subscription} class. While the {@link Observer} is the public API for\n * consuming the values of an {@link Observable}, all Observers get converted to\n * a Subscriber, in order to provide Subscription-like capabilities such as\n * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for\n * implementing operators, but it is rarely used as a public API.\n *\n * @class Subscriber\n */\nexport class Subscriber extends Subscription implements Observer {\n /**\n * A static factory for a Subscriber, given a (potentially partial) definition\n * of an Observer.\n * @param next The `next` callback of an Observer.\n * @param error The `error` callback of an\n * Observer.\n * @param complete The `complete` callback of an\n * Observer.\n * @return A Subscriber wrapping the (partially defined)\n * Observer represented by the given arguments.\n * @nocollapse\n * @deprecated Do not use. Will be removed in v8. There is no replacement for this\n * method, and there is no reason to be creating instances of `Subscriber` directly.\n * If you have a specific use case, please file an issue.\n */\n static create(next?: (x?: T) => void, error?: (e?: any) => void, complete?: () => void): Subscriber {\n return new SafeSubscriber(next, error, complete);\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected isStopped: boolean = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected destination: Subscriber | Observer; // this `any` is the escape hatch to erase extra type param (e.g. R)\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * There is no reason to directly create an instance of Subscriber. This type is exported for typings reasons.\n */\n constructor(destination?: Subscriber | Observer) {\n super();\n if (destination) {\n this.destination = destination;\n // Automatically chain subscriptions together here.\n // if destination is a Subscription, then it is a Subscriber.\n if (isSubscription(destination)) {\n destination.add(this);\n }\n } else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `next` from\n * the Observable, with a value. The Observable may call this method 0 or more\n * times.\n * @param {T} [value] The `next` value.\n * @return {void}\n */\n next(value?: T): void {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n } else {\n this._next(value!);\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `error` from\n * the Observable, with an attached `Error`. Notifies the Observer that\n * the Observable has experienced an error condition.\n * @param {any} [err] The `error` exception.\n * @return {void}\n */\n error(err?: any): void {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n } else {\n this.isStopped = true;\n this._error(err);\n }\n }\n\n /**\n * The {@link Observer} callback to receive a valueless notification of type\n * `complete` from the Observable. Notifies the Observer that the Observable\n * has finished sending push-based notifications.\n * @return {void}\n */\n complete(): void {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n } else {\n this.isStopped = true;\n this._complete();\n }\n }\n\n unsubscribe(): void {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n this.destination = null!;\n }\n }\n\n protected _next(value: T): void {\n this.destination.next(value);\n }\n\n protected _error(err: any): void {\n try {\n this.destination.error(err);\n } finally {\n this.unsubscribe();\n }\n }\n\n protected _complete(): void {\n try {\n this.destination.complete();\n } finally {\n this.unsubscribe();\n }\n }\n}\n\n/**\n * This bind is captured here because we want to be able to have\n * compatibility with monoid libraries that tend to use a method named\n * `bind`. In particular, a library called Monio requires this.\n */\nconst _bind = Function.prototype.bind;\n\nfunction bind any>(fn: Fn, thisArg: any): Fn {\n return _bind.call(fn, thisArg);\n}\n\n/**\n * Internal optimization only, DO NOT EXPOSE.\n * @internal\n */\nclass ConsumerObserver implements Observer {\n constructor(private partialObserver: Partial>) {}\n\n next(value: T): void {\n const { partialObserver } = this;\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n error(err: any): void {\n const { partialObserver } = this;\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n } catch (error) {\n handleUnhandledError(error);\n }\n } else {\n handleUnhandledError(err);\n }\n }\n\n complete(): void {\n const { partialObserver } = this;\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n}\n\nexport class SafeSubscriber extends Subscriber {\n constructor(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((e?: any) => void) | null,\n complete?: (() => void) | null\n ) {\n super();\n\n let partialObserver: Partial>;\n if (isFunction(observerOrNext) || !observerOrNext) {\n // The first argument is a function, not an observer. The next\n // two arguments *could* be observers, or they could be empty.\n partialObserver = {\n next: (observerOrNext ?? undefined) as (((value: T) => void) | undefined),\n error: error ?? undefined,\n complete: complete ?? undefined,\n };\n } else {\n // The first argument is a partial observer.\n let context: any;\n if (this && config.useDeprecatedNextContext) {\n // This is a deprecated path that made `this.unsubscribe()` available in\n // next handler functions passed to subscribe. This only exists behind a flag\n // now, as it is *very* slow.\n context = Object.create(observerOrNext);\n context.unsubscribe = () => this.unsubscribe();\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context),\n error: observerOrNext.error && bind(observerOrNext.error, context),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context),\n };\n } else {\n // The \"normal\" path. Just use the partial observer directly.\n partialObserver = observerOrNext;\n }\n }\n\n // Wrap the partial observer to ensure it's a full observer, and\n // make sure proper error handling is accounted for.\n this.destination = new ConsumerObserver(partialObserver);\n }\n}\n\nfunction handleUnhandledError(error: any) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n } else {\n // Ideal path, we report this as an unhandled error,\n // which is thrown on a new call stack.\n reportUnhandledError(error);\n }\n}\n\n/**\n * An error handler used when no error handler was supplied\n * to the SafeSubscriber -- meaning no error handler was supplied\n * do the `subscribe` call on our observable.\n * @param err The error to handle\n */\nfunction defaultErrorHandler(err: any) {\n throw err;\n}\n\n/**\n * A handler for notifications that cannot be sent to a stopped subscriber.\n * @param notification The notification being sent\n * @param subscriber The stopped subscriber\n */\nfunction handleStoppedNotification(notification: ObservableNotification, subscriber: Subscriber) {\n const { onStoppedNotification } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\n/**\n * The observer used as a stub for subscriptions where the user did not\n * pass any arguments to `subscribe`. Comes with the default error handling\n * behavior.\n */\nexport const EMPTY_OBSERVER: Readonly> & { closed: true } = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n", "/**\n * Symbol.observable or a string \"@@observable\". Used for interop\n *\n * @deprecated We will no longer be exporting this symbol in upcoming versions of RxJS.\n * Instead polyfill and use Symbol.observable directly *or* use https://www.npmjs.com/package/symbol-observable\n */\nexport const observable: string | symbol = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();\n", "/**\n * This function takes one parameter and just returns it. Simply put,\n * this is like `(x: T): T => x`.\n *\n * ## Examples\n *\n * This is useful in some cases when using things like `mergeMap`\n *\n * ```ts\n * import { interval, take, map, range, mergeMap, identity } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(5));\n *\n * const result$ = source$.pipe(\n * map(i => range(i)),\n * mergeMap(identity) // same as mergeMap(x => x)\n * );\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * Or when you want to selectively apply an operator\n *\n * ```ts\n * import { interval, take, identity } from 'rxjs';\n *\n * const shouldLimit = () => Math.random() < 0.5;\n *\n * const source$ = interval(1000);\n *\n * const result$ = source$.pipe(shouldLimit() ? take(5) : identity);\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * @param x Any value that is returned by this function\n * @returns The value passed as the first parameter to this function\n */\nexport function identity(x: T): T {\n return x;\n}\n", "import { identity } from './identity';\nimport { UnaryFunction } from '../types';\n\nexport function pipe(): typeof identity;\nexport function pipe(fn1: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction, fn3: UnaryFunction): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction,\n ...fns: UnaryFunction[]\n): UnaryFunction;\n\n/**\n * pipe() can be called on one or more functions, each of which can take one argument (\"UnaryFunction\")\n * and uses it to return a value.\n * It returns a function that takes one argument, passes it to the first UnaryFunction, and then\n * passes the result to the next one, passes that result to the next one, and so on. \n */\nexport function pipe(...fns: Array>): UnaryFunction {\n return pipeFromArray(fns);\n}\n\n/** @internal */\nexport function pipeFromArray(fns: Array>): UnaryFunction {\n if (fns.length === 0) {\n return identity as UnaryFunction;\n }\n\n if (fns.length === 1) {\n return fns[0];\n }\n\n return function piped(input: T): R {\n return fns.reduce((prev: any, fn: UnaryFunction) => fn(prev), input as any);\n };\n}\n", "import { Operator } from './Operator';\nimport { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription, Subscription } from './Subscription';\nimport { TeardownLogic, OperatorFunction, Subscribable, Observer } from './types';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A representation of any set of values over any amount of time. This is the most basic building block\n * of RxJS.\n *\n * @class Observable\n */\nexport class Observable implements Subscribable {\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n source: Observable | undefined;\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n operator: Operator | undefined;\n\n /**\n * @constructor\n * @param {Function} subscribe the function that is called when the Observable is\n * initially subscribed to. This function is given a Subscriber, to which new values\n * can be `next`ed, or an `error` method can be called to raise an error, or\n * `complete` can be called to notify of a successful completion.\n */\n constructor(subscribe?: (this: Observable, subscriber: Subscriber) => TeardownLogic) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n\n // HACK: Since TypeScript inherits static properties too, we have to\n // fight against TypeScript here so Subject can have a different static create signature\n /**\n * Creates a new Observable by calling the Observable constructor\n * @owner Observable\n * @method create\n * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor\n * @return {Observable} a new observable\n * @nocollapse\n * @deprecated Use `new Observable()` instead. Will be removed in v8.\n */\n static create: (...args: any[]) => any = (subscribe?: (subscriber: Subscriber) => TeardownLogic) => {\n return new Observable(subscribe);\n };\n\n /**\n * Creates a new Observable, with this Observable instance as the source, and the passed\n * operator defined as the new observable's operator.\n * @method lift\n * @param operator the operator defining the operation to take on the observable\n * @return a new observable with the Operator applied\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * If you have implemented an operator using `lift`, it is recommended that you create an\n * operator by simply returning `new Observable()` directly. See \"Creating new operators from\n * scratch\" section here: https://rxjs.dev/guide/operators\n */\n lift(operator?: Operator): Observable {\n const observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n }\n\n subscribe(observerOrNext?: Partial> | ((value: T) => void)): Subscription;\n /** @deprecated Instead of passing separate callback arguments, use an observer argument. Signatures taking separate callback arguments will be removed in v8. Details: https://rxjs.dev/deprecations/subscribe-arguments */\n subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;\n /**\n * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.\n *\n * Use it when you have all these Observables, but still nothing is happening.\n *\n * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It\n * might be for example a function that you passed to Observable's constructor, but most of the time it is\n * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means\n * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often\n * the thought.\n *\n * Apart from starting the execution of an Observable, this method allows you to listen for values\n * that an Observable emits, as well as for when it completes or errors. You can achieve this in two\n * of the following ways.\n *\n * The first way is creating an object that implements {@link Observer} interface. It should have methods\n * defined by that interface, but note that it should be just a regular JavaScript object, which you can create\n * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular, do\n * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also\n * that your object does not have to implement all methods. If you find yourself creating a method that doesn't\n * do anything, you can simply omit it. Note however, if the `error` method is not provided and an error happens,\n * it will be thrown asynchronously. Errors thrown asynchronously cannot be caught using `try`/`catch`. Instead,\n * use the {@link onUnhandledError} configuration option or use a runtime handler (like `window.onerror` or\n * `process.on('error)`) to be notified of unhandled errors. Because of this, it's recommended that you provide\n * an `error` method to avoid missing thrown errors.\n *\n * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.\n * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent\n * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of an Observer,\n * if you do not need to listen for something, you can omit a function by passing `undefined` or `null`,\n * since `subscribe` recognizes these functions by where they were placed in function call. When it comes\n * to the `error` function, as with an Observer, if not provided, errors emitted by an Observable will be thrown asynchronously.\n *\n * You can, however, subscribe with no parameters at all. This may be the case where you're not interested in terminal events\n * and you also handled emissions internally by using operators (e.g. using `tap`).\n *\n * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.\n * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean\n * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback\n * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.\n *\n * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.\n * It is an Observable itself that decides when these functions will be called. For example {@link of}\n * by default emits all its values synchronously. Always check documentation for how given Observable\n * will behave when subscribed and if its default behavior can be modified with a `scheduler`.\n *\n * #### Examples\n *\n * Subscribe with an {@link guide/observer Observer}\n *\n * ```ts\n * import { of } from 'rxjs';\n *\n * const sumObserver = {\n * sum: 0,\n * next(value) {\n * console.log('Adding: ' + value);\n * this.sum = this.sum + value;\n * },\n * error() {\n * // We actually could just remove this method,\n * // since we do not really care about errors right now.\n * },\n * complete() {\n * console.log('Sum equals: ' + this.sum);\n * }\n * };\n *\n * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.\n * .subscribe(sumObserver);\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Subscribe with functions ({@link deprecations/subscribe-arguments deprecated})\n *\n * ```ts\n * import { of } from 'rxjs'\n *\n * let sum = 0;\n *\n * of(1, 2, 3).subscribe(\n * value => {\n * console.log('Adding: ' + value);\n * sum = sum + value;\n * },\n * undefined,\n * () => console.log('Sum equals: ' + sum)\n * );\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Cancel a subscription\n *\n * ```ts\n * import { interval } from 'rxjs';\n *\n * const subscription = interval(1000).subscribe({\n * next(num) {\n * console.log(num)\n * },\n * complete() {\n * // Will not be called, even when cancelling subscription.\n * console.log('completed!');\n * }\n * });\n *\n * setTimeout(() => {\n * subscription.unsubscribe();\n * console.log('unsubscribed!');\n * }, 2500);\n *\n * // Logs:\n * // 0 after 1s\n * // 1 after 2s\n * // 'unsubscribed!' after 2.5s\n * ```\n *\n * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,\n * or the first of three possible handlers, which is the handler for each value emitted from the subscribed\n * Observable.\n * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,\n * the error will be thrown asynchronously as unhandled.\n * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.\n * @return {Subscription} a subscription reference to the registered handlers\n * @method subscribe\n */\n subscribe(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((error: any) => void) | null,\n complete?: (() => void) | null\n ): Subscription {\n const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n\n errorContext(() => {\n const { operator, source } = this;\n subscriber.add(\n operator\n ? // We're dealing with a subscription in the\n // operator chain to one of our lifted operators.\n operator.call(subscriber, source)\n : source\n ? // If `source` has a value, but `operator` does not, something that\n // had intimate knowledge of our API, like our `Subject`, must have\n // set it. We're going to just call `_subscribe` directly.\n this._subscribe(subscriber)\n : // In all other cases, we're likely wrapping a user-provided initializer\n // function, so we need to catch errors and handle them appropriately.\n this._trySubscribe(subscriber)\n );\n });\n\n return subscriber;\n }\n\n /** @internal */\n protected _trySubscribe(sink: Subscriber): TeardownLogic {\n try {\n return this._subscribe(sink);\n } catch (err) {\n // We don't need to return anything in this case,\n // because it's just going to try to `add()` to a subscription\n // above.\n sink.error(err);\n }\n }\n\n /**\n * Used as a NON-CANCELLABLE means of subscribing to an observable, for use with\n * APIs that expect promises, like `async/await`. You cannot unsubscribe from this.\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * #### Example\n *\n * ```ts\n * import { interval, take } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(4));\n *\n * async function getTotal() {\n * let total = 0;\n *\n * await source$.forEach(value => {\n * total += value;\n * console.log('observable -> ' + value);\n * });\n *\n * return total;\n * }\n *\n * getTotal().then(\n * total => console.log('Total: ' + total)\n * );\n *\n * // Expected:\n * // 'observable -> 0'\n * // 'observable -> 1'\n * // 'observable -> 2'\n * // 'observable -> 3'\n * // 'Total: 6'\n * ```\n *\n * @param next a handler for each value emitted by the observable\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n */\n forEach(next: (value: T) => void): Promise;\n\n /**\n * @param next a handler for each value emitted by the observable\n * @param promiseCtor a constructor function used to instantiate the Promise\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n * @deprecated Passing a Promise constructor will no longer be available\n * in upcoming versions of RxJS. This is because it adds weight to the library, for very\n * little benefit. If you need this functionality, it is recommended that you either\n * polyfill Promise, or you create an adapter to convert the returned native promise\n * to whatever promise implementation you wanted. Will be removed in v8.\n */\n forEach(next: (value: T) => void, promiseCtor: PromiseConstructorLike): Promise;\n\n forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n const subscriber = new SafeSubscriber({\n next: (value) => {\n try {\n next(value);\n } catch (err) {\n reject(err);\n subscriber.unsubscribe();\n }\n },\n error: reject,\n complete: resolve,\n });\n this.subscribe(subscriber);\n }) as Promise;\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): TeardownLogic {\n return this.source?.subscribe(subscriber);\n }\n\n /**\n * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable\n * @method Symbol.observable\n * @return {Observable} this instance of the observable\n */\n [Symbol_observable]() {\n return this;\n }\n\n /* tslint:disable:max-line-length */\n pipe(): Observable;\n pipe(op1: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction,\n ...operations: OperatorFunction[]\n ): Observable;\n /* tslint:enable:max-line-length */\n\n /**\n * Used to stitch together functional operators into a chain.\n * @method pipe\n * @return {Observable} the Observable result of all of the operators having\n * been called in the order they were passed in.\n *\n * ## Example\n *\n * ```ts\n * import { interval, filter, map, scan } from 'rxjs';\n *\n * interval(1000)\n * .pipe(\n * filter(x => x % 2 === 0),\n * map(x => x + x),\n * scan((acc, x) => acc + x)\n * )\n * .subscribe(x => console.log(x));\n * ```\n */\n pipe(...operations: OperatorFunction[]): Observable {\n return pipeFromArray(operations)(this);\n }\n\n /* tslint:disable:max-line-length */\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: typeof Promise): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: PromiseConstructorLike): Promise;\n /* tslint:enable:max-line-length */\n\n /**\n * Subscribe to this Observable and get a Promise resolving on\n * `complete` with the last emission (if any).\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * @method toPromise\n * @param [promiseCtor] a constructor function used to instantiate\n * the Promise\n * @return A Promise that resolves with the last value emit, or\n * rejects on an error. If there were no emissions, Promise\n * resolves with undefined.\n * @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise\n */\n toPromise(promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n let value: T | undefined;\n this.subscribe(\n (x: T) => (value = x),\n (err: any) => reject(err),\n () => resolve(value)\n );\n }) as Promise;\n }\n}\n\n/**\n * Decides between a passed promise constructor from consuming code,\n * A default configured promise constructor, and the native promise\n * constructor and returns it. If nothing can be found, it will throw\n * an error.\n * @param promiseCtor The optional promise constructor to passed by consuming code\n */\nfunction getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {\n return promiseCtor ?? config.Promise ?? Promise;\n}\n\nfunction isObserver(value: any): value is Observer {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\n\nfunction isSubscriber(value: any): value is Subscriber {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n", "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { OperatorFunction } from '../types';\nimport { isFunction } from './isFunction';\n\n/**\n * Used to determine if an object is an Observable with a lift function.\n */\nexport function hasLift(source: any): source is { lift: InstanceType['lift'] } {\n return isFunction(source?.lift);\n}\n\n/**\n * Creates an `OperatorFunction`. Used to define operators throughout the library in a concise way.\n * @param init The logic to connect the liftedSource to the subscriber at the moment of subscription.\n */\nexport function operate(\n init: (liftedSource: Observable, subscriber: Subscriber) => (() => void) | void\n): OperatorFunction {\n return (source: Observable) => {\n if (hasLift(source)) {\n return source.lift(function (this: Subscriber, liftedSource: Observable) {\n try {\n return init(liftedSource, this);\n } catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n", "import { Subscriber } from '../Subscriber';\n\n/**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional teardown logic here. This will only be called on teardown if the\n * subscriber itself is not already closed. This is called after all other teardown logic is executed.\n */\nexport function createOperatorSubscriber(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n onFinalize?: () => void\n): Subscriber {\n return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\n\n/**\n * A generic helper for allowing operators to be created with a Subscriber and\n * use closures to capture necessary state from the operator function itself.\n */\nexport class OperatorSubscriber extends Subscriber {\n /**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional finalization logic here. This will only be called on finalization if the\n * subscriber itself is not already closed. This is called after all other finalization logic is executed.\n * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe.\n * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription\n * to the resulting observable does not actually disconnect from the source if there are active subscriptions\n * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!)\n */\n constructor(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n private onFinalize?: () => void,\n private shouldUnsubscribe?: () => boolean\n ) {\n // It's important - for performance reasons - that all of this class's\n // members are initialized and that they are always initialized in the same\n // order. This will ensure that all OperatorSubscriber instances have the\n // same hidden class in V8. This, in turn, will help keep the number of\n // hidden classes involved in property accesses within the base class as\n // low as possible. If the number of hidden classes involved exceeds four,\n // the property accesses will become megamorphic and performance penalties\n // will be incurred - i.e. inline caches won't be used.\n //\n // The reasons for ensuring all instances have the same hidden class are\n // further discussed in this blog post from Benedikt Meurer:\n // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/\n super(destination);\n this._next = onNext\n ? function (this: OperatorSubscriber, value: T) {\n try {\n onNext(value);\n } catch (err) {\n destination.error(err);\n }\n }\n : super._next;\n this._error = onError\n ? function (this: OperatorSubscriber, err: any) {\n try {\n onError(err);\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._error;\n this._complete = onComplete\n ? function (this: OperatorSubscriber) {\n try {\n onComplete();\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._complete;\n }\n\n unsubscribe() {\n if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n const { closed } = this;\n super.unsubscribe();\n // Execute additional teardown if we have any and we didn't already do so.\n !closed && this.onFinalize?.();\n }\n }\n}\n", "import { Subscription } from '../Subscription';\n\ninterface AnimationFrameProvider {\n schedule(callback: FrameRequestCallback): Subscription;\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n delegate:\n | {\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n }\n | undefined;\n}\n\nexport const animationFrameProvider: AnimationFrameProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n schedule(callback) {\n let request = requestAnimationFrame;\n let cancel: typeof cancelAnimationFrame | undefined = cancelAnimationFrame;\n const { delegate } = animationFrameProvider;\n if (delegate) {\n request = delegate.requestAnimationFrame;\n cancel = delegate.cancelAnimationFrame;\n }\n const handle = request((timestamp) => {\n // Clear the cancel function. The request has been fulfilled, so\n // attempting to cancel the request upon unsubscription would be\n // pointless.\n cancel = undefined;\n callback(timestamp);\n });\n return new Subscription(() => cancel?.(handle));\n },\n requestAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.requestAnimationFrame || requestAnimationFrame)(...args);\n },\n cancelAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.cancelAnimationFrame || cancelAnimationFrame)(...args);\n },\n delegate: undefined,\n};\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface ObjectUnsubscribedError extends Error {}\n\nexport interface ObjectUnsubscribedErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (): ObjectUnsubscribedError;\n}\n\n/**\n * An error thrown when an action is invalid because the object has been\n * unsubscribed.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n *\n * @class ObjectUnsubscribedError\n */\nexport const ObjectUnsubscribedError: ObjectUnsubscribedErrorCtor = createErrorClass(\n (_super) =>\n function ObjectUnsubscribedErrorImpl(this: any) {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n }\n);\n", "import { Operator } from './Operator';\nimport { Observable } from './Observable';\nimport { Subscriber } from './Subscriber';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { Observer, SubscriptionLike, TeardownLogic } from './types';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A Subject is a special type of Observable that allows values to be\n * multicasted to many Observers. Subjects are like EventEmitters.\n *\n * Every Subject is an Observable and an Observer. You can subscribe to a\n * Subject, and you can call next to feed values as well as error and complete.\n */\nexport class Subject extends Observable implements SubscriptionLike {\n closed = false;\n\n private currentObservers: Observer[] | null = null;\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n observers: Observer[] = [];\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n isStopped = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n hasError = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n thrownError: any = null;\n\n /**\n * Creates a \"subject\" by basically gluing an observer to an observable.\n *\n * @nocollapse\n * @deprecated Recommended you do not use. Will be removed at some point in the future. Plans for replacement still under discussion.\n */\n static create: (...args: any[]) => any = (destination: Observer, source: Observable): AnonymousSubject => {\n return new AnonymousSubject(destination, source);\n };\n\n constructor() {\n // NOTE: This must be here to obscure Observable's constructor.\n super();\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n lift(operator: Operator): Observable {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator as any;\n return subject as any;\n }\n\n /** @internal */\n protected _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n\n next(value: T) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n if (!this.currentObservers) {\n this.currentObservers = Array.from(this.observers);\n }\n for (const observer of this.currentObservers) {\n observer.next(value);\n }\n }\n });\n }\n\n error(err: any) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.error(err);\n }\n }\n });\n }\n\n complete() {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.isStopped = true;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.complete();\n }\n }\n });\n }\n\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null!;\n }\n\n get observed() {\n return this.observers?.length > 0;\n }\n\n /** @internal */\n protected _trySubscribe(subscriber: Subscriber): TeardownLogic {\n this._throwIfClosed();\n return super._trySubscribe(subscriber);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n }\n\n /** @internal */\n protected _innerSubscribe(subscriber: Subscriber) {\n const { hasError, isStopped, observers } = this;\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(() => {\n this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n }\n\n /** @internal */\n protected _checkFinalizedStatuses(subscriber: Subscriber) {\n const { hasError, thrownError, isStopped } = this;\n if (hasError) {\n subscriber.error(thrownError);\n } else if (isStopped) {\n subscriber.complete();\n }\n }\n\n /**\n * Creates a new Observable with this Subject as the source. You can do this\n * to create custom Observer-side logic of the Subject and conceal it from\n * code that uses the Observable.\n * @return {Observable} Observable that the Subject casts to\n */\n asObservable(): Observable {\n const observable: any = new Observable();\n observable.source = this;\n return observable;\n }\n}\n\n/**\n * @class AnonymousSubject\n */\nexport class AnonymousSubject extends Subject {\n constructor(\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n public destination?: Observer,\n source?: Observable\n ) {\n super();\n this.source = source;\n }\n\n next(value: T) {\n this.destination?.next?.(value);\n }\n\n error(err: any) {\n this.destination?.error?.(err);\n }\n\n complete() {\n this.destination?.complete?.();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n return this.source?.subscribe(subscriber) ?? EMPTY_SUBSCRIPTION;\n }\n}\n", "import { TimestampProvider } from '../types';\n\ninterface DateTimestampProvider extends TimestampProvider {\n delegate: TimestampProvider | undefined;\n}\n\nexport const dateTimestampProvider: DateTimestampProvider = {\n now() {\n // Use the variable rather than `this` so that the function can be called\n // without being bound to the provider.\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n", "import { Subject } from './Subject';\nimport { TimestampProvider } from './types';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * A variant of {@link Subject} that \"replays\" old values to new subscribers by emitting them when they first subscribe.\n *\n * `ReplaySubject` has an internal buffer that will store a specified number of values that it has observed. Like `Subject`,\n * `ReplaySubject` \"observes\" values by having them passed to its `next` method. When it observes a value, it will store that\n * value for a time determined by the configuration of the `ReplaySubject`, as passed to its constructor.\n *\n * When a new subscriber subscribes to the `ReplaySubject` instance, it will synchronously emit all values in its buffer in\n * a First-In-First-Out (FIFO) manner. The `ReplaySubject` will also complete, if it has observed completion; and it will\n * error if it has observed an error.\n *\n * There are two main configuration items to be concerned with:\n *\n * 1. `bufferSize` - This will determine how many items are stored in the buffer, defaults to infinite.\n * 2. `windowTime` - The amount of time to hold a value in the buffer before removing it from the buffer.\n *\n * Both configurations may exist simultaneously. So if you would like to buffer a maximum of 3 values, as long as the values\n * are less than 2 seconds old, you could do so with a `new ReplaySubject(3, 2000)`.\n *\n * ### Differences with BehaviorSubject\n *\n * `BehaviorSubject` is similar to `new ReplaySubject(1)`, with a couple of exceptions:\n *\n * 1. `BehaviorSubject` comes \"primed\" with a single value upon construction.\n * 2. `ReplaySubject` will replay values, even after observing an error, where `BehaviorSubject` will not.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n * @see {@link shareReplay}\n */\nexport class ReplaySubject extends Subject {\n private _buffer: (T | number)[] = [];\n private _infiniteTimeWindow = true;\n\n /**\n * @param bufferSize The size of the buffer to replay on subscription\n * @param windowTime The amount of time the buffered items will stay buffered\n * @param timestampProvider An object with a `now()` method that provides the current timestamp. This is used to\n * calculate the amount of time something has been buffered.\n */\n constructor(\n private _bufferSize = Infinity,\n private _windowTime = Infinity,\n private _timestampProvider: TimestampProvider = dateTimestampProvider\n ) {\n super();\n this._infiniteTimeWindow = _windowTime === Infinity;\n this._bufferSize = Math.max(1, _bufferSize);\n this._windowTime = Math.max(1, _windowTime);\n }\n\n next(value: T): void {\n const { isStopped, _buffer, _infiniteTimeWindow, _timestampProvider, _windowTime } = this;\n if (!isStopped) {\n _buffer.push(value);\n !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n }\n this._trimBuffer();\n super.next(value);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._trimBuffer();\n\n const subscription = this._innerSubscribe(subscriber);\n\n const { _infiniteTimeWindow, _buffer } = this;\n // We use a copy here, so reentrant code does not mutate our array while we're\n // emitting it to a new subscriber.\n const copy = _buffer.slice();\n for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i] as T);\n }\n\n this._checkFinalizedStatuses(subscriber);\n\n return subscription;\n }\n\n private _trimBuffer() {\n const { _bufferSize, _timestampProvider, _buffer, _infiniteTimeWindow } = this;\n // If we don't have an infinite buffer size, and we're over the length,\n // use splice to truncate the old buffer values off. Note that we have to\n // double the size for instances where we're not using an infinite time window\n // because we're storing the values and the timestamps in the same array.\n const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n\n // Now, if we're not in an infinite time window, remove all values where the time is\n // older than what is allowed.\n if (!_infiniteTimeWindow) {\n const now = _timestampProvider.now();\n let last = 0;\n // Search the array for the first timestamp that isn't expired and\n // truncate the buffer up to that point.\n for (let i = 1; i < _buffer.length && (_buffer[i] as number) <= now; i += 2) {\n last = i;\n }\n last && _buffer.splice(0, last + 1);\n }\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Subscription } from '../Subscription';\nimport { SchedulerAction } from '../types';\n\n/**\n * A unit of work to be executed in a `scheduler`. An action is typically\n * created from within a {@link SchedulerLike} and an RxJS user does not need to concern\n * themselves about creating and manipulating an Action.\n *\n * ```ts\n * class Action extends Subscription {\n * new (scheduler: Scheduler, work: (state?: T) => void);\n * schedule(state?: T, delay: number = 0): Subscription;\n * }\n * ```\n *\n * @class Action\n */\nexport class Action extends Subscription {\n constructor(scheduler: Scheduler, work: (this: SchedulerAction, state?: T) => void) {\n super();\n }\n /**\n * Schedules this action on its parent {@link SchedulerLike} for execution. May be passed\n * some context object, `state`. May happen at some point in the future,\n * according to the `delay` parameter, if specified.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler.\n * @return {void}\n */\n public schedule(state?: T, delay: number = 0): Subscription {\n return this;\n }\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearIntervalFunction = (handle: TimerHandle) => void;\n\ninterface IntervalProvider {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n delegate:\n | {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n }\n | undefined;\n}\n\nexport const intervalProvider: IntervalProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setInterval(handler: () => void, timeout?: number, ...args) {\n const { delegate } = intervalProvider;\n if (delegate?.setInterval) {\n return delegate.setInterval(handler, timeout, ...args);\n }\n return setInterval(handler, timeout, ...args);\n },\n clearInterval(handle) {\n const { delegate } = intervalProvider;\n return (delegate?.clearInterval || clearInterval)(handle as any);\n },\n delegate: undefined,\n};\n", "import { Action } from './Action';\nimport { SchedulerAction } from '../types';\nimport { Subscription } from '../Subscription';\nimport { AsyncScheduler } from './AsyncScheduler';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncAction extends Action {\n public id: TimerHandle | undefined;\n public state?: T;\n // @ts-ignore: Property has no initializer and is not definitely assigned\n public delay: number;\n protected pending: boolean = false;\n\n constructor(protected scheduler: AsyncScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (this.closed) {\n return this;\n }\n\n // Always replace the current state with the new state.\n this.state = state;\n\n const id = this.id;\n const scheduler = this.scheduler;\n\n //\n // Important implementation note:\n //\n // Actions only execute once by default, unless rescheduled from within the\n // scheduled callback. This allows us to implement single and repeat\n // actions via the same code path, without adding API surface area, as well\n // as mimic traditional recursion but across asynchronous boundaries.\n //\n // However, JS runtimes and timers distinguish between intervals achieved by\n // serial `setTimeout` calls vs. a single `setInterval` call. An interval of\n // serial `setTimeout` calls can be individually delayed, which delays\n // scheduling the next `setTimeout`, and so on. `setInterval` attempts to\n // guarantee the interval callback will be invoked more precisely to the\n // interval period, regardless of load.\n //\n // Therefore, we use `setInterval` to schedule single and repeat actions.\n // If the action reschedules itself with the same delay, the interval is not\n // canceled. If the action doesn't reschedule, or reschedules with a\n // different delay, the interval will be canceled after scheduled callback\n // execution.\n //\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n\n // Set the pending flag indicating that this action has been scheduled, or\n // has recursively rescheduled itself.\n this.pending = true;\n\n this.delay = delay;\n // If this action has already an async Id, don't request a new one.\n this.id = this.id ?? this.requestAsyncId(scheduler, this.id, delay);\n\n return this;\n }\n\n protected requestAsyncId(scheduler: AsyncScheduler, _id?: TimerHandle, delay: number = 0): TimerHandle {\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n }\n\n protected recycleAsyncId(_scheduler: AsyncScheduler, id?: TimerHandle, delay: number | null = 0): TimerHandle | undefined {\n // If this action is rescheduled with the same delay time, don't clear the interval id.\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n // Otherwise, if the action's delay time is different from the current delay,\n // or the action has been rescheduled before it's executed, clear the interval id\n if (id != null) {\n intervalProvider.clearInterval(id);\n }\n\n return undefined;\n }\n\n /**\n * Immediately executes this action and the `work` it contains.\n * @return {any}\n */\n public execute(state: T, delay: number): any {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n\n this.pending = false;\n const error = this._execute(state, delay);\n if (error) {\n return error;\n } else if (this.pending === false && this.id != null) {\n // Dequeue if the action didn't reschedule itself. Don't call\n // unsubscribe(), because the action could reschedule later.\n // For example:\n // ```\n // scheduler.schedule(function doWork(counter) {\n // /* ... I'm a busy worker bee ... */\n // var originalAction = this;\n // /* wait 100ms before rescheduling the action */\n // setTimeout(function () {\n // originalAction.schedule(counter + 1);\n // }, 100);\n // }, 1000);\n // ```\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n }\n\n protected _execute(state: T, _delay: number): any {\n let errored: boolean = false;\n let errorValue: any;\n try {\n this.work(state);\n } catch (e) {\n errored = true;\n // HACK: Since code elsewhere is relying on the \"truthiness\" of the\n // return here, we can't have it return \"\" or 0 or false.\n // TODO: Clean this up when we refactor schedulers mid-version-8 or so.\n errorValue = e ? e : new Error('Scheduled action threw falsy error');\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n }\n\n unsubscribe() {\n if (!this.closed) {\n const { id, scheduler } = this;\n const { actions } = scheduler;\n\n this.work = this.state = this.scheduler = null!;\n this.pending = false;\n\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n\n this.delay = null!;\n super.unsubscribe();\n }\n }\n}\n", "import { Action } from './scheduler/Action';\nimport { Subscription } from './Subscription';\nimport { SchedulerLike, SchedulerAction } from './types';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * An execution context and a data structure to order tasks and schedule their\n * execution. Provides a notion of (potentially virtual) time, through the\n * `now()` getter method.\n *\n * Each unit of work in a Scheduler is called an `Action`.\n *\n * ```ts\n * class Scheduler {\n * now(): number;\n * schedule(work, delay?, state?): Subscription;\n * }\n * ```\n *\n * @class Scheduler\n * @deprecated Scheduler is an internal implementation detail of RxJS, and\n * should not be used directly. Rather, create your own class and implement\n * {@link SchedulerLike}. Will be made internal in v8.\n */\nexport class Scheduler implements SchedulerLike {\n public static now: () => number = dateTimestampProvider.now;\n\n constructor(private schedulerActionCtor: typeof Action, now: () => number = Scheduler.now) {\n this.now = now;\n }\n\n /**\n * A getter method that returns a number representing the current time\n * (at the time this function was called) according to the scheduler's own\n * internal clock.\n * @return {number} A number that represents the current time. May or may not\n * have a relation to wall-clock time. May or may not refer to a time unit\n * (e.g. milliseconds).\n */\n public now: () => number;\n\n /**\n * Schedules a function, `work`, for execution. May happen at some point in\n * the future, according to the `delay` parameter, if specified. May be passed\n * some context object, `state`, which will be passed to the `work` function.\n *\n * The given arguments will be processed an stored as an Action object in a\n * queue of actions.\n *\n * @param {function(state: ?T): ?Subscription} work A function representing a\n * task, or some unit of work to be executed by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler itself.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @return {Subscription} A subscription in order to be able to unsubscribe\n * the scheduled work.\n */\n public schedule(work: (this: SchedulerAction, state?: T) => void, delay: number = 0, state?: T): Subscription {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Action } from './Action';\nimport { AsyncAction } from './AsyncAction';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncScheduler extends Scheduler {\n public actions: Array> = [];\n /**\n * A flag to indicate whether the Scheduler is currently executing a batch of\n * queued actions.\n * @type {boolean}\n * @internal\n */\n public _active: boolean = false;\n /**\n * An internal ID used to track the latest asynchronous task such as those\n * coming from `setTimeout`, `setInterval`, `requestAnimationFrame`, and\n * others.\n * @type {any}\n * @internal\n */\n public _scheduled: TimerHandle | undefined;\n\n constructor(SchedulerAction: typeof Action, now: () => number = Scheduler.now) {\n super(SchedulerAction, now);\n }\n\n public flush(action: AsyncAction): void {\n const { actions } = this;\n\n if (this._active) {\n actions.push(action);\n return;\n }\n\n let error: any;\n this._active = true;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions.shift()!)); // exhaust the scheduler queue\n\n this._active = false;\n\n if (error) {\n while ((action = actions.shift()!)) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\n/**\n *\n * Async Scheduler\n *\n * Schedule task as if you used setTimeout(task, duration)\n *\n * `async` scheduler schedules tasks asynchronously, by putting them on the JavaScript\n * event loop queue. It is best used to delay tasks in time or to schedule tasks repeating\n * in intervals.\n *\n * If you just want to \"defer\" task, that is to perform it right after currently\n * executing synchronous code ends (commonly achieved by `setTimeout(deferredTask, 0)`),\n * better choice will be the {@link asapScheduler} scheduler.\n *\n * ## Examples\n * Use async scheduler to delay task\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * const task = () => console.log('it works!');\n *\n * asyncScheduler.schedule(task, 2000);\n *\n * // After 2 seconds logs:\n * // \"it works!\"\n * ```\n *\n * Use async scheduler to repeat task in intervals\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * function task(state) {\n * console.log(state);\n * this.schedule(state + 1, 1000); // `this` references currently executing Action,\n * // which we reschedule with new state and delay\n * }\n *\n * asyncScheduler.schedule(task, 3000, 0);\n *\n * // Logs:\n * // 0 after 3s\n * // 1 after 4s\n * // 2 after 5s\n * // 3 after 6s\n * ```\n */\n\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\n\n/**\n * @deprecated Renamed to {@link asyncScheduler}. Will be removed in v8.\n */\nexport const async = asyncScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\nimport { SchedulerAction } from '../types';\nimport { animationFrameProvider } from './animationFrameProvider';\nimport { TimerHandle } from './timerHandle';\n\nexport class AnimationFrameAction extends AsyncAction {\n constructor(protected scheduler: AnimationFrameScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n protected requestAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay is greater than 0, request as an async action.\n if (delay !== null && delay > 0) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n // Push the action to the end of the scheduler queue.\n scheduler.actions.push(this);\n // If an animation frame has already been requested, don't request another\n // one. If an animation frame hasn't been requested yet, request one. Return\n // the current animation frame request id.\n return scheduler._scheduled || (scheduler._scheduled = animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));\n }\n\n protected recycleAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle | undefined {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n if (delay != null ? delay > 0 : this.delay > 0) {\n return super.recycleAsyncId(scheduler, id, delay);\n }\n // If the scheduler queue has no remaining actions with the same async id,\n // cancel the requested animation frame and set the scheduled flag to\n // undefined so the next AnimationFrameAction will request its own.\n const { actions } = scheduler;\n if (id != null && actions[actions.length - 1]?.id !== id) {\n animationFrameProvider.cancelAnimationFrame(id as number);\n scheduler._scheduled = undefined;\n }\n // Return undefined so the action knows to request a new async id if it's rescheduled.\n return undefined;\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\nexport class AnimationFrameScheduler extends AsyncScheduler {\n public flush(action?: AsyncAction): void {\n this._active = true;\n // The async id that effects a call to flush is stored in _scheduled.\n // Before executing an action, it's necessary to check the action's async\n // id to determine whether it's supposed to be executed in the current\n // flush.\n // Previous implementations of this method used a count to determine this,\n // but that was unsound, as actions that are unsubscribed - i.e. cancelled -\n // are removed from the actions array and that can shift actions that are\n // scheduled to be executed in a subsequent flush into positions at which\n // they are executed within the current flush.\n const flushId = this._scheduled;\n this._scheduled = undefined;\n\n const { actions } = this;\n let error: any;\n action = action || actions.shift()!;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions[0]) && action.id === flushId && actions.shift());\n\n this._active = false;\n\n if (error) {\n while ((action = actions[0]) && action.id === flushId && actions.shift()) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AnimationFrameAction } from './AnimationFrameAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\n\n/**\n *\n * Animation Frame Scheduler\n *\n * Perform task when `window.requestAnimationFrame` would fire\n *\n * When `animationFrame` scheduler is used with delay, it will fall back to {@link asyncScheduler} scheduler\n * behaviour.\n *\n * Without delay, `animationFrame` scheduler can be used to create smooth browser animations.\n * It makes sure scheduled task will happen just before next browser content repaint,\n * thus performing animations as efficiently as possible.\n *\n * ## Example\n * Schedule div height animation\n * ```ts\n * // html:
\n * import { animationFrameScheduler } from 'rxjs';\n *\n * const div = document.querySelector('div');\n *\n * animationFrameScheduler.schedule(function(height) {\n * div.style.height = height + \"px\";\n *\n * this.schedule(height + 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * }, 0, 0);\n *\n * // You will see a div element growing in height\n * ```\n */\n\nexport const animationFrameScheduler = new AnimationFrameScheduler(AnimationFrameAction);\n\n/**\n * @deprecated Renamed to {@link animationFrameScheduler}. Will be removed in v8.\n */\nexport const animationFrame = animationFrameScheduler;\n", "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\n\n/**\n * A simple Observable that emits no items to the Observer and immediately\n * emits a complete notification.\n *\n * Just emits 'complete', and nothing else.\n *\n * ![](empty.png)\n *\n * A simple Observable that only emits the complete notification. It can be used\n * for composing with other Observables, such as in a {@link mergeMap}.\n *\n * ## Examples\n *\n * Log complete notification\n *\n * ```ts\n * import { EMPTY } from 'rxjs';\n *\n * EMPTY.subscribe({\n * next: () => console.log('Next'),\n * complete: () => console.log('Complete!')\n * });\n *\n * // Outputs\n * // Complete!\n * ```\n *\n * Emit the number 7, then complete\n *\n * ```ts\n * import { EMPTY, startWith } from 'rxjs';\n *\n * const result = EMPTY.pipe(startWith(7));\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // 7\n * ```\n *\n * Map and flatten only odd numbers to the sequence `'a'`, `'b'`, `'c'`\n *\n * ```ts\n * import { interval, mergeMap, of, EMPTY } from 'rxjs';\n *\n * const interval$ = interval(1000);\n * const result = interval$.pipe(\n * mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : EMPTY),\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following to the console:\n * // x is equal to the count on the interval, e.g. (0, 1, 2, 3, ...)\n * // x will occur every 1000ms\n * // if x % 2 is equal to 1, print a, b, c (each on its own)\n * // if x % 2 is not equal to 1, nothing will be output\n * ```\n *\n * @see {@link Observable}\n * @see {@link NEVER}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const EMPTY = new Observable((subscriber) => subscriber.complete());\n\n/**\n * @param scheduler A {@link SchedulerLike} to use for scheduling\n * the emission of the complete notification.\n * @deprecated Replaced with the {@link EMPTY} constant or {@link scheduled} (e.g. `scheduled([], scheduler)`). Will be removed in v8.\n */\nexport function empty(scheduler?: SchedulerLike) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\n\nfunction emptyScheduled(scheduler: SchedulerLike) {\n return new Observable((subscriber) => scheduler.schedule(() => subscriber.complete()));\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport function isScheduler(value: any): value is SchedulerLike {\n return value && isFunction(value.schedule);\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\n\nfunction last(arr: T[]): T | undefined {\n return arr[arr.length - 1];\n}\n\nexport function popResultSelector(args: any[]): ((...args: unknown[]) => unknown) | undefined {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\n\nexport function popScheduler(args: any[]): SchedulerLike | undefined {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\n\nexport function popNumber(args: any[], defaultValue: number): number {\n return typeof last(args) === 'number' ? args.pop()! : defaultValue;\n}\n", "export const isArrayLike = ((x: any): x is ArrayLike => x && typeof x.length === 'number' && typeof x !== 'function');", "import { isFunction } from \"./isFunction\";\n\n/**\n * Tests to see if the object is \"thennable\".\n * @param value the object to test\n */\nexport function isPromise(value: any): value is PromiseLike {\n return isFunction(value?.then);\n}\n", "import { InteropObservable } from '../types';\nimport { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being Observable (but not necessary an Rx Observable) */\nexport function isInteropObservable(input: any): input is InteropObservable {\n return isFunction(input[Symbol_observable]);\n}\n", "import { isFunction } from './isFunction';\n\nexport function isAsyncIterable(obj: any): obj is AsyncIterable {\n return Symbol.asyncIterator && isFunction(obj?.[Symbol.asyncIterator]);\n}\n", "/**\n * Creates the TypeError to throw if an invalid object is passed to `from` or `scheduled`.\n * @param input The object that was passed.\n */\nexport function createInvalidObservableTypeError(input: any) {\n // TODO: We should create error codes that can be looked up, so this can be less verbose.\n return new TypeError(\n `You provided ${\n input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`\n } where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`\n );\n}\n", "export function getSymbolIterator(): symbol {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator' as any;\n }\n\n return Symbol.iterator;\n}\n\nexport const iterator = getSymbolIterator();\n", "import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being an Iterable */\nexport function isIterable(input: any): input is Iterable {\n return isFunction(input?.[Symbol_iterator]);\n}\n", "import { ReadableStreamLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport async function* readableStreamLikeToAsyncGenerator(readableStream: ReadableStreamLike): AsyncGenerator {\n const reader = readableStream.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n return;\n }\n yield value!;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function isReadableStreamLike(obj: any): obj is ReadableStreamLike {\n // We don't want to use instanceof checks because they would return\n // false for instances from another Realm, like an

+
+

+

29.2.3 Tutorial 3

+

+

29.2.4 Tutorial 4

+

+

29.2.5 Tutorial 5

+

+

29.2.6 Tutorial 6

+

+ + + + + + + + + + +
+
+
+ + + + + + \ No newline at end of file diff --git a/user/guide/panels/index.html b/user/guide/panels/index.html new file mode 100644 index 0000000..1f85d03 --- /dev/null +++ b/user/guide/panels/index.html @@ -0,0 +1,1241 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + + +
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

16. Overview panels

+

The overview panels - visible on the side of the map - are used for quick visualisation / summaries of single taxon, single-site and multi-site search results.

+

16.1 Single taxon overview panel

+

The single taxon overview panel provides an at-a-glance overview of records for the taxon, and the taxon’s origin, endemism and conservation status. It also includes an outbound link to the IUCN status page for that taxon, and fetches specimen images from GBIF if available.

+

By clicking Open Dashboard, the user can then open the Dashboard to see further information on the taxon.

+

Single taxon overview panel:

+

Single Taxon 1

+

16.2 Single-site overview panel

+

For single-sites, we display summary data, including useful context information (GeoContext-derived data) such as the Geomorphological Zone and Ecoregions (Figure 13). The number of occurrences for each module (fish, invertebrates, algae, odonate adults and anura), pie charts showing the proportion of taxa in each Origin (see section 10.1.8), Endemism (see section 10.1.9) and Conservation Status (see section 10.1.10) category, as well as number of taxa is shown for each group.

+

The “dashboards and forms” on the overview panel provides onward links to available fish, invertebrate, algal and SASS dashboards (see Section 10) and forms for uploading data (see Section 11). Temperature and rainfall charts (data for which is also harvested from GeoContext) can be found at the bottom of the panel. See below which illustrates the bottom section of the overview panel.

+

Single-site overview panel - top:

+

Single Site 1

+

Single Site 2

+

Single-site overview panel - Bottom:

+

Single Site 3

+

Single Site 4

+

16.3 Multi-site overview panel

+

For multiple sites, ‘multi-sites’, we display the filter history for selecting records, but not the detailed contextual site information found in the single-site overview panel because these data will not be the same across all the sites in a multi-site. The number of occurrences and number of sites for each module (fish, invertebrates and algae), pie charts showing the proportion of taxa in each Origin (see section 10.1.8), Endemism (see section 10.1.9) and Conservation Status (see section 10.1.10) category, as well as number of taxa is shown for each group.

+

The “dashboards” on the overview panel provide onward links to available biodiversity and abiotic (see Section 10), where you are able to also drill down to the detailed multi-site dashboards for each module.

+

Multi-site overview panel:

+

 Multi-site 1

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/user/guide/references/index.html b/user/guide/references/index.html new file mode 100644 index 0000000..f8e397e --- /dev/null +++ b/user/guide/references/index.html @@ -0,0 +1,1168 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + + +
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

28. References

+

Dallas HF, Janssens MP & Day JA. 1999. An aquatic macroinvertebrate and chemical database for riverine ecosystems. Water SA 25 (1): 1-8.

+ +

Dallas HF and Rivers-Moore NA. 2019. Dallas HF and Rivers-Moore NA. 2019. Environmental water temperature guidelines for perennial rivers in South Africa. Volume 2: A technical manual for setting water temperature targets. Water Research Commission Report no. TT 799/2/19. Water Research Commission, Pretoria, South Africa.

+ +

Dallas HF and Rivers-Moore NA. 2022. A protocol and tools for setting environmental water temperature guidelines for perennial rivers in South Africa. African Journal of Aquatic Science. DOI: 10.2989/16085914.2021.1982673

+ +

River Health Programme. 2007. Rivers Database. Department of Water Affairs and Forestry, Pretoria, South Africa.

+ +

Rivers-Moore NA, Dallas HF & Morris C. 2013a. Towards setting environmental water temperature guidelines: A South African example. Journal of Environmental Management 128: 380-392.

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/user/guide/registering/index.html b/user/guide/registering/index.html new file mode 100644 index 0000000..f85fd7e --- /dev/null +++ b/user/guide/registering/index.html @@ -0,0 +1,1216 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + + +
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

10. Registering and logging in

+

10.1 Signing up

+

Visit freshwaterbiodiversity.org to login, sign up and explore. Complete the Sign Up to register to use FBIS, including details of your organisation and role in the freshwater community.

+

Sign Up 1

+

Sign Up 2

+

10.2 Logging in

+

Navigate to freshwaterbiodiversity.org, and then on the landing page click on Log In in the top navigation bar.

+

Logging In 1

+

You will be redirected to the Login Page. Fill in your email address and password and then click on Login

+

Logging In 2

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/user/guide/search/index.html b/user/guide/search/index.html new file mode 100644 index 0000000..e073f90 --- /dev/null +++ b/user/guide/search/index.html @@ -0,0 +1,1167 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + + +
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

12. Search

+

FBIS supports search auto-completion based on FBIS site code, taxon name (scientific) and river name. With this implementation it is very easy to, for example, quickly extract all of the sites along a given river as per the example shown below (Figure 2).

+

Accessed by: Clicking on the magnifying glass search icon and then entering a taxon name, FBIS site code or river name into the search box. A user can search using Taxon Rank (species, genus, family or order) as well as Taxon, which is the lowest taxon provided in a study reference (Figure 3).

+

To clear search criteria use "Reset".

+

Search 1

+

Search based on river name:

+

Search 2

+

Search based on Taxon Name and Rank, showing Order Ephemeroptera, Family Teloganodidae, Genus Lestagella and Species Lestagella penicillata:

+

Search 3

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/user/index.html b/user/index.html new file mode 100644 index 0000000..1cfbdd5 --- /dev/null +++ b/user/index.html @@ -0,0 +1,3371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + BIMS Documentation - BIMS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

User documentation

+

This is the homepage for all user related documentation.

+

The user content is divided into three sections:

+
    +
  • The quickstart tutorial, which aims to get you familiar with the basics of platform in around 5 minutes.
  • +
  • The user guide, which describes common workflows in a tutorial format.
  • +
  • The user manual, which describes each page of the user interface and what the various options on that page do.
  • +
+ + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/user/manual/img/naming-convention.README b/user/manual/img/naming-convention.README new file mode 100644 index 0000000..74a045a --- /dev/null +++ b/user/manual/img/naming-convention.README @@ -0,0 +1,7 @@ +# Image naming convention + +Images should be named according to reference doc, sub-section and order in the document. +e.g. + +- The 1st image in instructions regarding zooming will be something like zooming-1, the 2nd image will be zooming-2, etc. +- The 1st image in quickstart regarding logging in will be login-1, etc diff --git a/user/manual/index.html b/user/manual/index.html new file mode 100644 index 0000000..02afcde --- /dev/null +++ b/user/manual/index.html @@ -0,0 +1,1162 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + + +
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

30. User manual

+

This section of the documentation describes every page in the application and +what the various components of that page do. The manual is intended to function +as a reference for the application. For narrative / workflow based tutorials, +you may prefer to work through our user guide.

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/user/quickstart/img/key-concepts-1.png b/user/quickstart/img/key-concepts-1.png new file mode 100644 index 0000000..e81d59e Binary files /dev/null and b/user/quickstart/img/key-concepts-1.png differ diff --git a/user/quickstart/img/key-concepts-2.png b/user/quickstart/img/key-concepts-2.png new file mode 100644 index 0000000..a7bfba1 Binary files /dev/null and b/user/quickstart/img/key-concepts-2.png differ diff --git a/user/quickstart/img/key-concepts-3.png b/user/quickstart/img/key-concepts-3.png new file mode 100644 index 0000000..08d167e Binary files /dev/null and b/user/quickstart/img/key-concepts-3.png differ diff --git a/user/quickstart/img/key-concepts-4.png b/user/quickstart/img/key-concepts-4.png new file mode 100644 index 0000000..9aeaf06 Binary files /dev/null and b/user/quickstart/img/key-concepts-4.png differ diff --git a/user/quickstart/img/key-concepts-5.png b/user/quickstart/img/key-concepts-5.png new file mode 100644 index 0000000..616ad9c Binary files /dev/null and b/user/quickstart/img/key-concepts-5.png differ diff --git a/user/quickstart/img/key-concepts-6.png b/user/quickstart/img/key-concepts-6.png new file mode 100644 index 0000000..8450b77 Binary files /dev/null and b/user/quickstart/img/key-concepts-6.png differ diff --git a/user/quickstart/img/key-concepts-7.png b/user/quickstart/img/key-concepts-7.png new file mode 100644 index 0000000..0e2f2ef Binary files /dev/null and b/user/quickstart/img/key-concepts-7.png differ diff --git a/user/quickstart/img/logging-in-1.png b/user/quickstart/img/logging-in-1.png new file mode 100644 index 0000000..40dc3b3 Binary files /dev/null and b/user/quickstart/img/logging-in-1.png differ diff --git a/user/quickstart/img/logging-in-2.png b/user/quickstart/img/logging-in-2.png new file mode 100644 index 0000000..6e3f0a5 Binary files /dev/null and b/user/quickstart/img/logging-in-2.png differ diff --git a/user/quickstart/img/naming-convention.README b/user/quickstart/img/naming-convention.README new file mode 100644 index 0000000..74a045a --- /dev/null +++ b/user/quickstart/img/naming-convention.README @@ -0,0 +1,7 @@ +# Image naming convention + +Images should be named according to reference doc, sub-section and order in the document. +e.g. + +- The 1st image in instructions regarding zooming will be something like zooming-1, the 2nd image will be zooming-2, etc. +- The 1st image in quickstart regarding logging in will be login-1, etc diff --git a/user/quickstart/img/sign-up-1.png b/user/quickstart/img/sign-up-1.png new file mode 100644 index 0000000..f1fc7f6 Binary files /dev/null and b/user/quickstart/img/sign-up-1.png differ diff --git a/user/quickstart/img/sign-up-2.png b/user/quickstart/img/sign-up-2.png new file mode 100644 index 0000000..de3c1ba Binary files /dev/null and b/user/quickstart/img/sign-up-2.png differ diff --git a/user/quickstart/index.html b/user/quickstart/index.html new file mode 100644 index 0000000..4b06386 --- /dev/null +++ b/user/quickstart/index.html @@ -0,0 +1,1217 @@ + + + + + + + + + + + + + +BIMS Documentation - BIMS + + + + + + + + + + + + + + +
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

7. Quickstart

+

7.1 Key concepts

+

Site: A specific location along a river course where sampling or assessments take place.

+

Key Concepts 1

+

FBIS Site-code: A unique name given to each site made up of:

+
    +
  • Two characters representing the secondary catchment code e.g. G1
  • +
  • Four characters representing the river name e.g. JONK. This is currently derived from the 1:500 000 DWS rivers layer. If the river does not have a name on this layer, then the nearest river name is taken. For this reason it is important for a user to add the Original river name on the Site form if the river is unnamed (e.g. a small tributary).
  • +
  • A hyphen i.e. –
  • +
  • Five characters representing the nearest place name e.g. SIMONS. In many cases these five characters are replaced by a numeric value where a place name has not been identified. The Original Site Code and Original River Name from the original study are also provided.
  • +
  • The site code is generated automatically unless the user as a standard name.
  • +
+

Key Concepts 2

+

River: This is currently derived from the 1:500 000 DWS rivers layer. If the river does not have a name on this layer, then the nearest river name is taken. For this reason it is important for a user to add the Original river name on the Site form if the river is unnamed (e.g. a small tributary). (See section 11.1 Create a site).

+

Occurrence record: One collection record for a taxon at a given site. This record may optionally include abundance data.

+

Key Concepts 3

+

Search: The process whereby free-form text is entered into the search box and the matching records are shown on the map.

+

Key Concepts 4

+

Filters: Often used in conjunction with search, filtering allows you to narrow down the result set based on predefined spatial, temporal and biological criteria, such as province, date, species, etc.

+

Key Concepts 5

+

Biodiversity Module: A higher taxonomic grouping of taxa (and thus their related collection records). Modules can have their own dashboard implementations and data capture forms to capture information specific to the kind of taxa in the module grouping.

+

Key Concepts 6

+

Abiotic Module: A module serving abiotic data including water temperature time series data and physico-chemical data.

+

Key Concepts 7

+

7.2 Signing up

+

Visit freshwaterbiodiversity.org to login, sign up and explore. Complete the Sign Up to register to use FBIS, including details of your organisation and role in the freshwater community.

+

Sign Up 1

+

Sign Up 2

+

7.3 Logging in

+

Navigate to freshwaterbiodiversity.org, and then on the landing page click on Log In in the top navigation bar.

+

Logging In 1

+

You will be redirected to the Login Page. Fill in your email address and password and then click on Login

+

Logging In 2

+ +
+
+ + +
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file

29.2.2 Tutorial 2