diff --git a/.Rbuildignore b/.Rbuildignore
index 3f223e5e5f3a6194498f89dba4ab6079fa295265..3bfc38f990a6b22b5991fe239b52c80b5bea0175 100644
--- a/.Rbuildignore
+++ b/.Rbuildignore
@@ -1,3 +1,5 @@
+^renv$
+^renv\.lock$
 ^README\.Rmd$
 ^README-.*\.png$
 ^README\.md$
@@ -27,4 +29,8 @@ tests/testhat/\~import_coe20092015\.csv
 ^public
 ^ci
 ^Scripts
+^cache
+^_pkgdown\.yml$
+^docs$
+^pkgdown$
 ^CRAN-SUBMISSION$
diff --git a/.gitignore b/.gitignore
index 39bebefde363b1d151c5a2176bcb872eff37d94b..479a553f65bf500f3d59ab52846bf076daeec9ea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,5 @@ stacomir.Rproj
 /doc/
 /Meta/
 /~import_coe20092015.csv
+.dbeaver/project-settings.json
+docs
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cbd3dd48a698b0f585fd1b84e5a4213e012c92df..fddc64af5f5a40414611a79c49551cbbe4bba8eb 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -7,100 +7,55 @@
 # public
 # For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages
 
-image: rocker/tidyverse
-
-services:
-    - name:  registry.forgemia.inra.fr/stacomi/stacomi_db/$imagedb_name:$db_version-pg$postgres_version-ps$postgis_version
-      alias: host_db
-      
 stages:          # List of stages for jobs, and their order of execution
   - testdb
   - build  
-  #- document
+  - document
   - check
   - test
   - codecoverage
   - deploy
   
 variables:
-  tag_dev: "dev"
-  imagedb_name: "stacomi_db"
+  POSTGRES_USER: "postgres"
+  POSTGRES_PASSWORD: "postgres"
+  POSTGRES_HOSTNAME: "host_db"
+  stacomi_db_path: "registry.forgemia.inra.fr/stacomi/stacomi_db"
+  db_image_name: "stacomi_db"
   db_version: "0.6.1"
   postgres_version: "14"
   postgis_version: "3.2"
-  _R_CHECK_CRAN_INCOMING_: "false"
-  _R_CHECK_FORCE_SUGGESTS_: "true"
-  CODECOV_TOKEN: "CODECOV_TOKEN_STRING"
-  POSTGRES_PASSWORD: postgres
-  REPO_NAME: "{repo_name}"
-  R_LIBS: "ci/lib"
+  db_image_tagdev: "$db_version-pg$postgres_version-ps$postgis_version"
   R_LIBS_USER: "ci/lib"
-  postgres_version: "14"
-  
+  RENV_PATHS_CACHE: "cache"
+  RENV_PATHS_LIBRARY: "renv/library"
+  R_LIBS: "ci/lib"
+  CHECK_DIR: "$CI_PROJECT_DIR/ci/logs"
+  BUILD_DIR: "$CI_PROJECT_DIR/ci/build"
+  BUILD_LOGS_DIR: "$CI_PROJECT_DIR/ci/logs/$CI_PROJECT_NAME.Rcheck"
 
-#key for caching per branch    
+#key for caching per branch
 cache:
   key: $CI_COMMIT_REF_SLUG
   paths:
+    - ${RENV_PATHS_CACHE}
+    - ${RENV_PATHS_LIBRARY}
     - ${R_LIBS_USER}
-    
-
-
-test_db:
-  before_script:
-    - sleep 120 # waiting postgresql
-    - psql --version
-    - export PGPASSWORD=$POSTGRES_PASSWORD
-  image: postgres:${postgres_version}        
-  stage: testdb
-  script:
-    - psql -U postgres -h host_db  -c "SELECT * FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema';"
-    - psql -U postgres -h host_db -c "select * from test.t_dispositifcomptage_dic" bd_contmig_nat
-    - export PGPASSWORD=test && psql -U test -h host_db -c "select * from test.t_dispositifcomptage_dic" bd_contmig_nat # test avec l'utilisateur iav pour vérfier les droits
-  
- 
-buildpackage:
-  stage: build 
-  only:
-    - main
-    - master
-    - 0.6.0.7
-  needs: []
-  script:
-      - mkdir -p $R_LIBS_USER
-      - mkdir -p public
-      # from https://www.algorist.co.uk/post/building-a-ci-pipeline-for-r-packages-in-gitlab/
-      - echo 'R_LIBS=$R_LIBS_USER' > .Renviron
-      - echo 'R_LIBS_USER=$R_LIBS_USER' >> .Renviron
-      - echo 'R_LIBS_SITE=$R_LIBS_USER' >> .Renviron
-      #- echo 'PGPASSWORD=$POSTGRES_PASSWORD' >> .Renviron # I need to pass the variable to use later in test
-      # d --deps dependencies, r 
-      - apt-get update -y
-      - apt-get install -y libpq-dev
-      - apt-get install -y r-cran-rodbc
-      #- install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled  RODBC
-      - install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled  stacomirtools RPostgres xtable magrittr intervals RColorBrewer
-      # these are for code coverage
-      - install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled covr DT
-      - install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled reshape2 graphics utils stats lattice grDevices Hmisc lubridate mgcv withr XML
-      - rm -rf /tmp/downloaded_packages
-      #- r -e 'install.packages(c("stacomirtools","RPostgres","xtable","magrittr","intervals","RColorBrewer"), lib= "ci/lib", dependencies = TRUE, repos =)'> public/logr
-      #- r -e 'install.packages(c(), lib= "ci/lib", repos= "https://pbil.univ-lyon1.fr/CRAN/", dependencies = TRUE)'>> public/logr  
-      #- r -e 'install.packages(c("xml2"), repos= "https://pbil.univ-lyon1.fr/CRAN/", lib= "ci/lib", dependencies = TRUE)'>> public/logr # this one is for test with JUNIT reporter 
-      #- if [[ $CI_DEFAULT_BRANCH == "master" || $CI_DEFAULT_BRANCH = "main" || $CI_DEFAULT_BRANCH = "0.6.0.7"]]; then echo "OK - default branch is master or main or 0.6.0.7"; else echo "default branch is not master or main or 0.6.0.7, please add yours ($CI_0.6.0.7_BRANCH) where needed, as well as in the present line of code" ; exit 1; fi
-      - r -e 'devtools::build(binary = TRUE, path="public", vignettes=TRUE, manual=TRUE)' 
-      - r -e 'devtools::build(binary = FALSE, path="public", vignettes=TRUE)' 
-  artifacts:
-    when: always
-    paths:
-      - public
-      - ci/lib
-      - "$(ls -rt *.zip |tail -1)" 
-      - "$(ls -rt *.tar.gz |tail -1)" 
 
+include:
+  - local: '/gitlab-ci/rules.gitlab-ci.yml'
+  - local: '/gitlab-ci/image.gitlab-ci.yml'
+  - local: '/gitlab-ci/service.gitlab-ci.yml'
+  - local: '/gitlab-ci/testdb.gitlab-ci.yml'
+  - local: '/gitlab-ci/buildpackage.gitlab-ci.yml'
+  - local: '/gitlab-ci/check.gitlab-ci.yml'
+  - local: '/gitlab-ci/update_check.gitlab-ci.yml'
+  - local: '/gitlab-ci/unittests.gitlab-ci.yml'
+  - local: '/gitlab-ci/codecov.gitlab-ci.yml'
+  - local: '/gitlab-ci/integration.gitlab-ci.yml'
+  - local: '/gitlab-ci/pkgdown.gitlab-ci.yml'
+  - local: '/gitlab-ci/publication.gitlab-ci.yml'
 
-                           
-                                    
 # pour lancer celui là il faudrait avoir un accès à un runner.... pour l'instant j'ai pas....
 #https://guillaumebriday.fr/installer-et-utiliser-les-gitlab-runners
 #https://forgemia.inra.fr/gaev/usecases/macosr
@@ -133,110 +88,6 @@ buildpackage:
 #    - r -e 'devtools::load_all()'   
 #    - r -e 'devtools::document()'
 
-# https://cran.r-project.org/web/packages/littler/vignettes/littler-examples.html        
-checkerrors:
-  before_script:
-  - apt-get update
-  - apt-get install -y qpdf  
-  stage: check
-  needs: ["buildpackage"]
-  only:
-    - main
-    - master
-    - 0.6.0.7
-  script:
-    - mkdir -p public/check
-    - echo 'R_LIBS=$R_LIBS_USER' > .Renviron
-    - echo 'R_LIBS_USER=$R_LIBS_USER' >> .Renviron
-    - echo 'R_LIBS_SITE=$R_LIBS_USER' >> .Renviron
-    - r -e 'devtools::load_all();devtools::check(document = FALSE, args = "--no-tests", check_dir="public/check")' 
-    #- check.r --repo "https://pbil.univ-lyon1.fr/CRAN/" --install-deps --library "ci/lib" 
-  artifacts:
-    when: always  
-    paths:
-      - public/check
-    expire_in: 30 days 
-    
-# https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html
-unittests:
-  stage: test
-  needs: ["buildpackage"]
-  only:
-    - main
-    - master
-    - 0.6.0.7  
-  script:
-  
-    - export PGPASSWORD=$POSTGRES_PASSWORD
-    - echo 'R_LIBS=$R_LIBS_USER' > .Renviron
-    - echo 'R_LIBS_USER=$R_LIBS_USER' >> .Renviron
-    - echo 'R_LIBS_SITE=$R_LIBS_USER' >> .Renviron
-    - echo 'PGPASSWORD=$POSTGRES_PASSWORD' >> .Renviron
-    - r -e 'devtools::load_all();options(stacomiR.dbname = "bd_contmig_nat",stacomiR.host ="db",	stacomiR.port = "5432",	stacomiR.user = "postgres",	stacomiR.password = "postgres"); test <- capture.output(devtools::test(reporter="junit")) ; XML::saveXML(XML::xmlParse(test[grep("?xml version",test):length(test)]), file="public/test.xml")'
-    - r -e 'a<-1'
-    - r -e 'print(a)'
-    - r -e 'devtools::test'
-  artifacts:
-    when: always
-    # You should set the job that uploads the screenshot to
-    #artifacts:when: always so that it still uploads a screenshot
-    #when a test fails.
-    paths:
-      - public/test.xml
-    reports:
-      junit: public/test.xml
-    expire_in: 30 days 
-    
-# here covr:codecov publishes the report on codecov, this function writes  
-# the coverage.html  in public  
-codecov:
-  stage: codecoverage  
-  needs: ["buildpackage"]
-  only:
-    - main
-    - master
-    - 0.6.0.7
-  script:
-    - echo 'R_LIBS=$R_LIBS_USER' > .Renviron
-    - echo 'R_LIBS_USER=$R_LIBS_USER' >> .Renviron
-    - echo 'R_LIBS_SITE=$R_LIBS_USER' >> .Renviron
-    #- echo 'PGPASSWORD=$POSTGRES_PASSWORD' >> .Renviron
-    - r -e 'Sys.setenv("NOT_CRAN"= "true"); devtools::load_all(); options(stacomiR.dbname = "bd_contmig_nat",stacomiR.host ="db",	stacomiR.port = "5432",	stacomiR.user = "postgres",	stacomiR.password = "postgres");co <- covr::package_coverage(type="all", quiet=FALSE, clean=FALSE);print(co);covr:::print.coverage(co);covr::report(co, file.path("dev/codecoverage_report", paste0("stacomiR-report.html")))' 
-    # the following should be used when pages is set
-    #- r -e 'covr::gitlab(file = "public/coverage.html", type = c("all"), quiet = FALSE)'
-  #A line like Code coverage: 67.89% of lines covered would match.
-  coverage: '/Coverage: \d+\.\d+/' 
-  artifacts:
-    when: always
-    paths:
-      - dev/codecoverage_report/stacomiR-report.html
-    expire_in: 30 days 
-    
-
-# adapted from
-# https://github.com/statnmap/gitlabr/blob/main/inst/gitlab-ci/check-coverage-pkgdown-renv.yml
-# https://gist.github.com/artemklevtsov/785ed0472c167246e947a75216852e10#file-gitlab-ci-yml-L15
-# ? need to create CI_JOB_TOKEN
-
-integration:
-  stage: deploy
-  allow_failure: true
-  only:
-    - main
-    - master
-    - 0.6.0.7
-  script: 
-    - echo "copy package to public"    
-    - cp -r "$(ls -rt *_*.zip |tail -1)" public
-    - cp -r "$(ls -rt *_*.tar.gz |tail -1)" public
-    - mkdir -p public/check
-    - cp -r check public/check
-  artifacts:
-    when: on_success
-    paths:
-      - public
-    expire_in: 30 days
-    
 # https://about.gitlab.com/blog/2016/11/03/publish-code-coverage-report-with-gitlab-pages/
 # A job that is meant to publish your code coverage report with GitLab Pages has to be placed in the separate stage.
 # Stages test, build and deploy are specified by 0.6.0.7, but you can change that if needed. 
@@ -259,8 +110,4 @@ integration:
 #    - echo "deployment with cache"
 #  artifacts:
 #    paths:
-#      - public
-
-    
-    
-    
+#      - public
\ No newline at end of file
diff --git a/_pkgdown.yml b/_pkgdown.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d71acfb90c81b09bc8b25aad2115925afcd1ff7d
--- /dev/null
+++ b/_pkgdown.yml
@@ -0,0 +1,4 @@
+url: ~
+template:
+  bootstrap: 5
+
diff --git a/gitlab-ci/buildpackage.gitlab-ci.yml b/gitlab-ci/buildpackage.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..248b5bc6695f25197857ca6a768d2818bb6be839
--- /dev/null
+++ b/gitlab-ci/buildpackage.gitlab-ci.yml
@@ -0,0 +1,35 @@
+.buildpackage:
+  stage: build
+  needs: []
+  script:
+      - mkdir -p $R_LIBS_USER
+      - mkdir -p $RENV_PATHS_CACHE
+      - mkdir -p public
+      - Rscript -e 'source("renv/activate.R")'
+      - Rscript -e 'if(!requireNamespace("pak", quietly = TRUE)) {install.packages("pak")}'
+      - Rscript -e 'pak::pkg_install(pkg = c("rcmdcheck", "renv"), upgrade = FALSE)'
+      - Rscript -e 'renv::restore()'    
+      - r -e 'devtools::build(binary = TRUE, path="public", vignettes=TRUE, manual=TRUE)' 
+      - r -e 'devtools::build(binary = FALSE, path="public", vignettes=TRUE)' 
+
+  artifacts:
+    when: always
+    paths:
+      - public
+      - ${R_LIBS_USER}
+
+# en dev
+buildpackage-dev:
+  extends:
+    - .rules_other
+    - .buildpackage
+    - .image-dev
+    - .service-dev
+
+# en prod
+buildpackage-prod:
+  extends:
+    - .rules_main
+    - .buildpackage
+    - .image-prod
+    - .service-prod
\ No newline at end of file
diff --git a/gitlab-ci/check.gitlab-ci.yml b/gitlab-ci/check.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3714e3e1c49b6658d40c55038d39f7b3fcdab4b0
--- /dev/null
+++ b/gitlab-ci/check.gitlab-ci.yml
@@ -0,0 +1,32 @@
+# https://cran.r-project.org/web/packages/littler/vignettes/littler-examples.html        
+.checkerrors:
+  before_script:
+  - apt-get update
+  - apt-get install -y qpdf  
+  stage: check
+  script:
+    - mkdir -p public/check
+    - r -e 'devtools::load_all();devtools::check(document = FALSE, args = "--no-tests", check_dir="public/check")'
+  artifacts:
+    when: always  
+    paths:
+      - public/check
+    expire_in: 30 days
+
+# en dev
+checkerrors-dev:
+  extends:
+    - .rules_other
+    - .checkerrors
+    - .image-dev
+    - .service-dev
+  needs: ["buildpackage-dev"]
+
+# en prod
+checkerrors-prod:
+  extends:
+    - .rules_main
+    - .checkerrors
+    - .image-prod
+    - .service-prod
+  needs: ["buildpackage-prod"]
diff --git a/gitlab-ci/codecov.gitlab-ci.yml b/gitlab-ci/codecov.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..599977e28a914b0a46bff392ad75537b5f6fcce0
--- /dev/null
+++ b/gitlab-ci/codecov.gitlab-ci.yml
@@ -0,0 +1,32 @@
+# here covr:codecov publishes the report on codecov, this function writes  
+# the coverage.html  in public  
+.codecov:
+  stage: codecoverage
+  script:
+    - Rscript -e 'pak::pkg_install(pkg = c("covr", "DT"), upgrade = FALSE)'
+    - Rscript -e 'pak::pak(pkg = ".", upgrade = FALSE)'
+    - Rscript -e 'Sys.setenv("NOT_CRAN"= "true"); devtools::load_all(); options(stacomiR.dbname = "bd_contmig_nat",stacomiR.host = "${POSTGRES_HOSTNAME}",	stacomiR.port = "5432",	stacomiR.user = "${POSTGRES_USER}",	stacomiR.password ="${POSTGRES_PASSWORD}");covr::gitlab(quiet = FALSE)'
+  coverage: '/Coverage: \d+\.\d+/' 
+  artifacts:
+    when: always
+    paths:
+      - public
+    expire_in: 30 days
+
+# en dev
+codecov-dev:
+  extends:
+    - .rules_other
+    - .codecov
+    - .image-dev
+    - .service-dev
+  needs: ["buildpackage-dev"]
+
+# en prod
+codecov-prod:
+  extends:
+    - .rules_main
+    - .codecov
+    - .image-prod
+    - .service-prod
+  needs: ["buildpackage-prod"]
\ No newline at end of file
diff --git a/gitlab-ci/image.gitlab-ci.yml b/gitlab-ci/image.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d483c19f22ad0ab6c0e4765d35fe5fd4ea52cd36
--- /dev/null
+++ b/gitlab-ci/image.gitlab-ci.yml
@@ -0,0 +1,11 @@
+# to use the right docker db image
+
+#######################
+# for any branch, but main
+.image-dev:   
+  image: rocker/tidyverse:latest
+      
+#######################
+# for main branch only
+.image-prod:   
+  image: rocker/tidyverse:latest
\ No newline at end of file
diff --git a/gitlab-ci/integration.gitlab-ci.yml b/gitlab-ci/integration.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..fa3899272d55c99dfb42e6419d8d325baafcfb9a
--- /dev/null
+++ b/gitlab-ci/integration.gitlab-ci.yml
@@ -0,0 +1,31 @@
+.integration:
+  stage: deploy
+  allow_failure: true
+  script: 
+    - echo "copy package to public"
+    - cp -r "$(ls -rt *_*.tar.gz |tail -1)" public
+    - mkdir -p public/check
+    - cp -r check public/check
+  artifacts:
+    when: on_success
+    paths:
+      - public
+    expire_in: 30 days
+
+# en dev
+integration-dev:
+  extends:
+    - .rules_other
+    - .integration
+    - .image-dev
+    - .service-dev
+  needs: ["buildpackage-dev"]
+
+# en prod
+integration-prod:
+  extends:
+    - .rules_main
+    - .integration
+    - .image-prod
+    - .service-prod
+  needs: ["buildpackage-prod"]
\ No newline at end of file
diff --git a/gitlab-ci/pkgdown.gitlab-ci.yml b/gitlab-ci/pkgdown.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c9c252d0f3e70810702a0e5655846c2641fa3352
--- /dev/null
+++ b/gitlab-ci/pkgdown.gitlab-ci.yml
@@ -0,0 +1,32 @@
+.pkgdown:
+    stage: document
+    allow_failure: true
+    when: on_success
+    script:
+      - mkdir -p public/documentation
+      - Rscript -e 'pak::pkg_install(pkg = c("pkgdown"), upgrade = FALSE)'
+      - Rscript -e 'pak::pak(pkg = ".", upgrade = FALSE)'
+      - Rscript -e 'pkgdown::build_site()'
+      - cp -r docs/* public
+    artifacts:
+      paths:
+        - public
+      expire_in: 30 days
+
+# en dev
+pkgdown-dev:
+  extends:
+    - .rules_other
+    - .pkgdown
+    - .image-dev
+    - .service-dev
+  needs: ["buildpackage-dev"]
+
+# en prod
+pkgdown-prod:
+  extends:
+    - .rules_main
+    - .pkgdown
+    - .image-prod
+    - .service-prod
+  needs: ["buildpackage-prod"]
\ No newline at end of file
diff --git a/gitlab-ci/publication.gitlab-ci.yml b/gitlab-ci/publication.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..14621dcf45f3a3a3b410b0a8fd4f8f6ccf441a1c
--- /dev/null
+++ b/gitlab-ci/publication.gitlab-ci.yml
@@ -0,0 +1,45 @@
+.publication:
+    stage: deploy
+    allow_failure: true
+    when: on_success
+    script:
+      - echo "publication"
+    artifacts:
+      paths:
+        - public
+      expire_in: 30 days
+
+# en dev
+publication-dev:
+  extends:
+    - .rules_other
+    - .publication
+    - .image-dev
+  needs: ["pkgdown-dev"]
+  environment:
+    name: $CI_COMMIT_REF_SLUG
+    url: https://$CI_PROJECT_NAMESPACE.$CI_PAGES_DOMAIN/-/$CI_PROJECT_NAME/-/jobs/$CI_JOB_ID/artifacts/public/index.html
+    on_stop: stop-pkgdown-dev
+
+stop-pkgdown-dev:
+  stage: deploy
+  extends:
+    - .rules_other
+  script:
+    - echo "Supprime l'environnement de test"
+  environment:
+    name:  $CI_COMMIT_REF_SLUG
+    action: stop
+  when: manual
+
+# en prod
+pages:
+  extends:
+    - .rules_main
+  stage: deploy
+  script:
+      - echo "deployment"
+  artifacts:
+      paths:
+          - public
+  needs: ["pkgdown-prod"]
\ No newline at end of file
diff --git a/gitlab-ci/rules.gitlab-ci.yml b/gitlab-ci/rules.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1294670549d96221d49fdd834b85f621ef27f67d
--- /dev/null
+++ b/gitlab-ci/rules.gitlab-ci.yml
@@ -0,0 +1,19 @@
+# generic rules to be used for main branch or others
+
+#######################
+# for any branch, but main
+.rules_other:
+  rules:
+    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_COMMIT_BRANCH != "main" && $CI_COMMIT_REF_PROTECTED  != "true"	# only if there is changes in branch other than main
+
+#######################            
+# for main banch only
+.rules_main:
+  rules:
+    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_REF_PROTECTED  == "true" # only if there is changes in the main branch
+
+#######################            
+# for shutting down the job
+.rules_shut_down:
+  rules:
+    - when: never
\ No newline at end of file
diff --git a/gitlab-ci/service.gitlab-ci.yml b/gitlab-ci/service.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9cca718938965b277963723dd13bce6e9aaeaeb8
--- /dev/null
+++ b/gitlab-ci/service.gitlab-ci.yml
@@ -0,0 +1,10 @@
+.service-dev:
+  services:
+    - name:  ${stacomi_db_path}/${db_image_name}:${db_image_tagdev}
+      alias: ${POSTGRES_HOSTNAME}
+
+
+.service-prod:
+  services:
+    - name:  ${stacomi_db_path}/${db_image_name}:latest
+      alias: ${POSTGRES_HOSTNAME}
diff --git a/gitlab-ci/testdb.gitlab-ci.yml b/gitlab-ci/testdb.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d53a0465807f00eb9e676c7f645fdd73be9f528c
--- /dev/null
+++ b/gitlab-ci/testdb.gitlab-ci.yml
@@ -0,0 +1,25 @@
+.test_db:
+  stage: testdb
+  image: postgres:${postgres_version} 
+  before_script:
+    - sleep 120 # waiting postgresql
+    - psql --version
+    - export PGPASSWORD=$POSTGRES_PASSWORD
+    - psql -U ${POSTGRES_USER} -h ${POSTGRES_HOSTNAME} -c "SELECT * FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema';"
+  script:
+    - psql -U ${POSTGRES_USER} -h ${POSTGRES_HOSTNAME} -c "select * from test.t_dispositifcomptage_dic" bd_contmig_nat
+    - export PGPASSWORD=test && psql -U test -h ${POSTGRES_HOSTNAME} -c "select * from test.t_dispositifcomptage_dic" bd_contmig_nat # test avec l'utilisateur
+
+# en dev
+test_db-dev:
+  extends:
+    - .rules_other
+    - .test_db
+    - .service-dev
+
+# en prod
+test_db-prod:
+  extends:
+    - .rules_main
+    - .test_db
+    - .service-prod
\ No newline at end of file
diff --git a/gitlab-ci/unittests.gitlab-ci.yml b/gitlab-ci/unittests.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1170a9abfd45391d55aa0474f2b84f1a34f057b1
--- /dev/null
+++ b/gitlab-ci/unittests.gitlab-ci.yml
@@ -0,0 +1,37 @@
+# https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html
+.unittests:
+  stage: test
+  script:
+    - Rscript -e 'pak::pkg_install(pkg = c("XML"), upgrade = FALSE)'
+    - r -e "devtools::load_all();
+      options(stacomiR.dbname = 'bd_contmig_nat', stacomiR.host = '${POSTGRES_HOSTNAME}',	stacomiR.port = '5432',	stacomiR.user = '${POSTGRES_USER}',	stacomiR.password = '${POSTGRES_PASSWORD}'); 
+      test <- capture.output(devtools::test(reporter='junit')) ; 
+      XML::saveXML(XML::xmlParse(test[grep('?xml version', test):length(test)]), file = 'public/test.xml')"
+  artifacts:
+    when: always
+    # You should set the job that uploads the screenshot to
+    #artifacts:when: always so that it still uploads a screenshot
+    #when a test fails.
+    paths:
+      - public/test.xml
+    reports:
+      junit: public/test.xml
+    expire_in: 30 days
+
+# en dev
+unittests-dev:
+  extends:
+    - .rules_other
+    - .unittests
+    - .image-dev
+    - .service-dev
+  needs: ["buildpackage-dev"]
+
+# en prod
+unittests-prod:
+  extends:
+    - .rules_main
+    - .unittests
+    - .image-prod
+    - .service-prod
+  needs: ["buildpackage-prod"]
\ No newline at end of file
diff --git a/gitlab-ci/update_check.gitlab-ci.yml b/gitlab-ci/update_check.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2e32a7572e54787f2e648d450e6f88f67638299d
--- /dev/null
+++ b/gitlab-ci/update_check.gitlab-ci.yml
@@ -0,0 +1,33 @@
+# https://cran.r-project.org/web/packages/littler/vignettes/littler-examples.html        
+.checkerrors_update:
+  before_script:
+  - apt-get update
+  - apt-get install -y qpdf  
+  stage: check
+  script:
+    - mkdir -p public/check
+    - Rscript -e 'renv::update()'
+    - r -e 'devtools::load_all();devtools::check(document = FALSE, args = "--no-tests", check_dir="public/check")'
+  artifacts:
+    when: always  
+    paths:
+      - public/check
+    expire_in: 30 days
+
+# en dev
+checkerrors_update-dev:
+  extends:
+    - .rules_other
+    - .checkerrors_update
+    - .image-dev
+    - .service-dev
+  needs: ["buildpackage-dev"]
+
+# en prod
+checkerrors_update-prod:
+  extends:
+    - .rules_main
+    - .checkerrors_update
+    - .image-prod
+    - .service-prod
+  needs: ["buildpackage-prod"]
diff --git a/pkgdown/favicon/apple-touch-icon-120x120.png b/pkgdown/favicon/apple-touch-icon-120x120.png
new file mode 100644
index 0000000000000000000000000000000000000000..92e8e41c614a687a80e66433a24583ad9f37259c
Binary files /dev/null and b/pkgdown/favicon/apple-touch-icon-120x120.png differ
diff --git a/pkgdown/favicon/apple-touch-icon-152x152.png b/pkgdown/favicon/apple-touch-icon-152x152.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe3a66b2791c19d39068498789339c213401f436
Binary files /dev/null and b/pkgdown/favicon/apple-touch-icon-152x152.png differ
diff --git a/pkgdown/favicon/apple-touch-icon-180x180.png b/pkgdown/favicon/apple-touch-icon-180x180.png
new file mode 100644
index 0000000000000000000000000000000000000000..5923b662fa09a4c87f9af71fbab7bfa83a263146
Binary files /dev/null and b/pkgdown/favicon/apple-touch-icon-180x180.png differ
diff --git a/pkgdown/favicon/apple-touch-icon-60x60.png b/pkgdown/favicon/apple-touch-icon-60x60.png
new file mode 100644
index 0000000000000000000000000000000000000000..9296ab1ac490dc94e382c21fedc7362276da4f2f
Binary files /dev/null and b/pkgdown/favicon/apple-touch-icon-60x60.png differ
diff --git a/pkgdown/favicon/apple-touch-icon-76x76.png b/pkgdown/favicon/apple-touch-icon-76x76.png
new file mode 100644
index 0000000000000000000000000000000000000000..b723790eb8c0cb72d0f9e9274253c31da8c80d1b
Binary files /dev/null and b/pkgdown/favicon/apple-touch-icon-76x76.png differ
diff --git a/pkgdown/favicon/apple-touch-icon.png b/pkgdown/favicon/apple-touch-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..153b2a698ce32cdc373b9d002eeaa26c029a57d6
Binary files /dev/null and b/pkgdown/favicon/apple-touch-icon.png differ
diff --git a/pkgdown/favicon/favicon-16x16.png b/pkgdown/favicon/favicon-16x16.png
new file mode 100644
index 0000000000000000000000000000000000000000..40b94fba0820535e33780c8fae4c03ec4a95d015
Binary files /dev/null and b/pkgdown/favicon/favicon-16x16.png differ
diff --git a/pkgdown/favicon/favicon-32x32.png b/pkgdown/favicon/favicon-32x32.png
new file mode 100644
index 0000000000000000000000000000000000000000..0972b62110ed2d7358ab87a204c1d0d59e53585a
Binary files /dev/null and b/pkgdown/favicon/favicon-32x32.png differ
diff --git a/pkgdown/favicon/favicon.ico b/pkgdown/favicon/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..ca9586c1046cc24483827aa15ace307660e34601
Binary files /dev/null and b/pkgdown/favicon/favicon.ico differ
diff --git a/renv.lock b/renv.lock
new file mode 100644
index 0000000000000000000000000000000000000000..b518bbca9b5fa3d4cdfdde71604fe0170cb679ac
--- /dev/null
+++ b/renv.lock
@@ -0,0 +1,1155 @@
+{
+  "R": {
+    "Version": "4.4.1",
+    "Repositories": [
+      {
+        "Name": "CRAN",
+        "URL": "https://cloud.r-project.org"
+      }
+    ]
+  },
+  "Packages": {
+    "DBI": {
+      "Package": "DBI",
+      "Version": "1.2.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "methods"
+      ],
+      "Hash": "065ae649b05f1ff66bb0c793107508f5"
+    },
+    "Formula": {
+      "Package": "Formula",
+      "Version": "1.2-5",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "stats"
+      ],
+      "Hash": "7a29697b75e027767a53fde6c903eca7"
+    },
+    "Hmisc": {
+      "Package": "Hmisc",
+      "Version": "5.1-3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "Formula",
+        "R",
+        "base64enc",
+        "cluster",
+        "colorspace",
+        "data.table",
+        "foreign",
+        "ggplot2",
+        "grid",
+        "gridExtra",
+        "gtable",
+        "htmlTable",
+        "htmltools",
+        "knitr",
+        "methods",
+        "nnet",
+        "rmarkdown",
+        "rpart",
+        "viridis"
+      ],
+      "Hash": "9a446aea30bff7e8ee20f4c0973e8851"
+    },
+    "MASS": {
+      "Package": "MASS",
+      "Version": "7.3-61",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics",
+        "methods",
+        "stats",
+        "utils"
+      ],
+      "Hash": "0cafd6f0500e5deba33be22c46bf6055"
+    },
+    "Matrix": {
+      "Package": "Matrix",
+      "Version": "1.7-0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics",
+        "grid",
+        "lattice",
+        "methods",
+        "stats",
+        "utils"
+      ],
+      "Hash": "1920b2f11133b12350024297d8a4ff4a"
+    },
+    "R6": {
+      "Package": "R6",
+      "Version": "2.5.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "470851b6d5d0ac559e9d01bb352b4021"
+    },
+    "RColorBrewer": {
+      "Package": "RColorBrewer",
+      "Version": "1.1-3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "45f0398006e83a5b10b72a90663d8d8c"
+    },
+    "RODBC": {
+      "Package": "RODBC",
+      "Version": "1.3-23",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "stats"
+      ],
+      "Hash": "544fd4ca5c8fa534604c3c0336f1a9e4"
+    },
+    "RPostgres": {
+      "Package": "RPostgres",
+      "Version": "1.4.7",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "DBI",
+        "R",
+        "bit64",
+        "blob",
+        "cpp11",
+        "hms",
+        "lubridate",
+        "methods",
+        "plogr",
+        "withr"
+      ],
+      "Hash": "beb7e18bf3f9e096f716a52a77ec793c"
+    },
+    "Rcpp": {
+      "Package": "Rcpp",
+      "Version": "1.0.13",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "methods",
+        "utils"
+      ],
+      "Hash": "f27411eb6d9c3dada5edd444b8416675"
+    },
+    "backports": {
+      "Package": "backports",
+      "Version": "1.5.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "e1e1b9d75c37401117b636b7ae50827a"
+    },
+    "base64enc": {
+      "Package": "base64enc",
+      "Version": "0.1-3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "543776ae6848fde2f48ff3816d0628bc"
+    },
+    "bit": {
+      "Package": "bit",
+      "Version": "4.5.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "5dc7b2677d65d0e874fc4aaf0e879987"
+    },
+    "bit64": {
+      "Package": "bit64",
+      "Version": "4.5.2",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "bit",
+        "methods",
+        "stats",
+        "utils"
+      ],
+      "Hash": "e84984bf5f12a18628d9a02322128dfd"
+    },
+    "blob": {
+      "Package": "blob",
+      "Version": "1.2.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "methods",
+        "rlang",
+        "vctrs"
+      ],
+      "Hash": "40415719b5a479b87949f3aa0aee737c"
+    },
+    "bslib": {
+      "Package": "bslib",
+      "Version": "0.8.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "base64enc",
+        "cachem",
+        "fastmap",
+        "grDevices",
+        "htmltools",
+        "jquerylib",
+        "jsonlite",
+        "lifecycle",
+        "memoise",
+        "mime",
+        "rlang",
+        "sass"
+      ],
+      "Hash": "b299c6741ca9746fb227debcb0f9fb6c"
+    },
+    "cachem": {
+      "Package": "cachem",
+      "Version": "1.1.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "fastmap",
+        "rlang"
+      ],
+      "Hash": "cd9a672193789068eb5a2aad65a0dedf"
+    },
+    "checkmate": {
+      "Package": "checkmate",
+      "Version": "2.3.2",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "backports",
+        "utils"
+      ],
+      "Hash": "0e14e01ce07e7c88fd25de6d4260d26b"
+    },
+    "cli": {
+      "Package": "cli",
+      "Version": "3.6.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "utils"
+      ],
+      "Hash": "b21916dd77a27642b447374a5d30ecf3"
+    },
+    "cluster": {
+      "Package": "cluster",
+      "Version": "2.1.6",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics",
+        "stats",
+        "utils"
+      ],
+      "Hash": "0aaa05204035dc43ea0004b9c76611dd"
+    },
+    "colorspace": {
+      "Package": "colorspace",
+      "Version": "2.1-1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics",
+        "methods",
+        "stats"
+      ],
+      "Hash": "d954cb1c57e8d8b756165d7ba18aa55a"
+    },
+    "cpp11": {
+      "Package": "cpp11",
+      "Version": "0.5.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "91570bba75d0c9d3f1040c835cee8fba"
+    },
+    "data.table": {
+      "Package": "data.table",
+      "Version": "1.16.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "methods"
+      ],
+      "Hash": "fb24e05d4a91d8b1c7ff8e284bde834a"
+    },
+    "digest": {
+      "Package": "digest",
+      "Version": "0.6.37",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "utils"
+      ],
+      "Hash": "33698c4b3127fc9f506654607fb73676"
+    },
+    "dplyr": {
+      "Package": "dplyr",
+      "Version": "1.1.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "R6",
+        "cli",
+        "generics",
+        "glue",
+        "lifecycle",
+        "magrittr",
+        "methods",
+        "pillar",
+        "rlang",
+        "tibble",
+        "tidyselect",
+        "utils",
+        "vctrs"
+      ],
+      "Hash": "fedd9d00c2944ff00a0e2696ccf048ec"
+    },
+    "evaluate": {
+      "Package": "evaluate",
+      "Version": "1.0.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "6b567375113ceb7d9f800de4dd42218e"
+    },
+    "fansi": {
+      "Package": "fansi",
+      "Version": "1.0.6",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "utils"
+      ],
+      "Hash": "962174cf2aeb5b9eea581522286a911f"
+    },
+    "farver": {
+      "Package": "farver",
+      "Version": "2.1.2",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Hash": "680887028577f3fa2a81e410ed0d6e42"
+    },
+    "fastmap": {
+      "Package": "fastmap",
+      "Version": "1.2.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Hash": "aa5e1cd11c2d15497494c5292d7ffcc8"
+    },
+    "fontawesome": {
+      "Package": "fontawesome",
+      "Version": "0.5.2",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "htmltools",
+        "rlang"
+      ],
+      "Hash": "c2efdd5f0bcd1ea861c2d4e2a883a67d"
+    },
+    "foreign": {
+      "Package": "foreign",
+      "Version": "0.8-87",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "methods",
+        "stats",
+        "utils"
+      ],
+      "Hash": "81fc09bdeab0077a73927ed1243404b6"
+    },
+    "fs": {
+      "Package": "fs",
+      "Version": "1.6.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "methods"
+      ],
+      "Hash": "15aeb8c27f5ea5161f9f6a641fafd93a"
+    },
+    "generics": {
+      "Package": "generics",
+      "Version": "0.1.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "methods"
+      ],
+      "Hash": "15e9634c0fcd294799e9b2e929ed1b86"
+    },
+    "ggplot2": {
+      "Package": "ggplot2",
+      "Version": "3.5.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "MASS",
+        "R",
+        "cli",
+        "glue",
+        "grDevices",
+        "grid",
+        "gtable",
+        "isoband",
+        "lifecycle",
+        "mgcv",
+        "rlang",
+        "scales",
+        "stats",
+        "tibble",
+        "vctrs",
+        "withr"
+      ],
+      "Hash": "44c6a2f8202d5b7e878ea274b1092426"
+    },
+    "glue": {
+      "Package": "glue",
+      "Version": "1.8.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "methods"
+      ],
+      "Hash": "5899f1eaa825580172bb56c08266f37c"
+    },
+    "gridExtra": {
+      "Package": "gridExtra",
+      "Version": "2.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "grDevices",
+        "graphics",
+        "grid",
+        "gtable",
+        "utils"
+      ],
+      "Hash": "7d7f283939f563670a697165b2cf5560"
+    },
+    "gtable": {
+      "Package": "gtable",
+      "Version": "0.3.5",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "cli",
+        "glue",
+        "grid",
+        "lifecycle",
+        "rlang"
+      ],
+      "Hash": "e18861963cbc65a27736e02b3cd3c4a0"
+    },
+    "highr": {
+      "Package": "highr",
+      "Version": "0.11",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "xfun"
+      ],
+      "Hash": "d65ba49117ca223614f71b60d85b8ab7"
+    },
+    "hms": {
+      "Package": "hms",
+      "Version": "1.1.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "lifecycle",
+        "methods",
+        "pkgconfig",
+        "rlang",
+        "vctrs"
+      ],
+      "Hash": "b59377caa7ed00fa41808342002138f9"
+    },
+    "htmlTable": {
+      "Package": "htmlTable",
+      "Version": "2.4.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "checkmate",
+        "htmltools",
+        "htmlwidgets",
+        "knitr",
+        "magrittr",
+        "methods",
+        "rstudioapi",
+        "stringr"
+      ],
+      "Hash": "ca027d8771f2c039aed82f00a81e725b"
+    },
+    "htmltools": {
+      "Package": "htmltools",
+      "Version": "0.5.8.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "base64enc",
+        "digest",
+        "fastmap",
+        "grDevices",
+        "rlang",
+        "utils"
+      ],
+      "Hash": "81d371a9cc60640e74e4ab6ac46dcedc"
+    },
+    "htmlwidgets": {
+      "Package": "htmlwidgets",
+      "Version": "1.6.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "grDevices",
+        "htmltools",
+        "jsonlite",
+        "knitr",
+        "rmarkdown",
+        "yaml"
+      ],
+      "Hash": "04291cc45198225444a397606810ac37"
+    },
+    "intervals": {
+      "Package": "intervals",
+      "Version": "0.15.5",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "graphics",
+        "methods",
+        "utils"
+      ],
+      "Hash": "da1fd6a5634e370ad0ef99a1aa2b17cb"
+    },
+    "isoband": {
+      "Package": "isoband",
+      "Version": "0.2.7",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "grid",
+        "utils"
+      ],
+      "Hash": "0080607b4a1a7b28979aecef976d8bc2"
+    },
+    "jquerylib": {
+      "Package": "jquerylib",
+      "Version": "0.1.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "htmltools"
+      ],
+      "Hash": "5aab57a3bd297eee1c1d862735972182"
+    },
+    "jsonlite": {
+      "Package": "jsonlite",
+      "Version": "1.8.9",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "methods"
+      ],
+      "Hash": "4e993b65c2c3ffbffce7bb3e2c6f832b"
+    },
+    "knitr": {
+      "Package": "knitr",
+      "Version": "1.48",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "evaluate",
+        "highr",
+        "methods",
+        "tools",
+        "xfun",
+        "yaml"
+      ],
+      "Hash": "acf380f300c721da9fde7df115a5f86f"
+    },
+    "labeling": {
+      "Package": "labeling",
+      "Version": "0.4.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "graphics",
+        "stats"
+      ],
+      "Hash": "b64ec208ac5bc1852b285f665d6368b3"
+    },
+    "later": {
+      "Package": "later",
+      "Version": "1.3.2",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "Rcpp",
+        "rlang"
+      ],
+      "Hash": "a3e051d405326b8b0012377434c62b37"
+    },
+    "lattice": {
+      "Package": "lattice",
+      "Version": "0.22-6",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics",
+        "grid",
+        "stats",
+        "utils"
+      ],
+      "Hash": "cc5ac1ba4c238c7ca9fa6a87ca11a7e2"
+    },
+    "lifecycle": {
+      "Package": "lifecycle",
+      "Version": "1.0.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "cli",
+        "glue",
+        "rlang"
+      ],
+      "Hash": "b8552d117e1b808b09a832f589b79035"
+    },
+    "lubridate": {
+      "Package": "lubridate",
+      "Version": "1.9.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "generics",
+        "methods",
+        "timechange"
+      ],
+      "Hash": "680ad542fbcf801442c83a6ac5a2126c"
+    },
+    "magrittr": {
+      "Package": "magrittr",
+      "Version": "2.0.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "7ce2733a9826b3aeb1775d56fd305472"
+    },
+    "memoise": {
+      "Package": "memoise",
+      "Version": "2.0.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "cachem",
+        "rlang"
+      ],
+      "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c"
+    },
+    "mgcv": {
+      "Package": "mgcv",
+      "Version": "1.9-1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "Matrix",
+        "R",
+        "graphics",
+        "methods",
+        "nlme",
+        "splines",
+        "stats",
+        "utils"
+      ],
+      "Hash": "110ee9d83b496279960e162ac97764ce"
+    },
+    "mime": {
+      "Package": "mime",
+      "Version": "0.12",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "tools"
+      ],
+      "Hash": "18e9c28c1d3ca1560ce30658b22ce104"
+    },
+    "munsell": {
+      "Package": "munsell",
+      "Version": "0.5.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "colorspace",
+        "methods"
+      ],
+      "Hash": "4fd8900853b746af55b81fda99da7695"
+    },
+    "nlme": {
+      "Package": "nlme",
+      "Version": "3.1-166",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "graphics",
+        "lattice",
+        "stats",
+        "utils"
+      ],
+      "Hash": "ccbb8846be320b627e6aa2b4616a2ded"
+    },
+    "nnet": {
+      "Package": "nnet",
+      "Version": "7.3-19",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "stats",
+        "utils"
+      ],
+      "Hash": "2c797b46eea7fb58ede195bc0b1f1138"
+    },
+    "pillar": {
+      "Package": "pillar",
+      "Version": "1.9.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "cli",
+        "fansi",
+        "glue",
+        "lifecycle",
+        "rlang",
+        "utf8",
+        "utils",
+        "vctrs"
+      ],
+      "Hash": "15da5a8412f317beeee6175fbc76f4bb"
+    },
+    "pkgconfig": {
+      "Package": "pkgconfig",
+      "Version": "2.0.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "utils"
+      ],
+      "Hash": "01f28d4278f15c76cddbea05899c5d6f"
+    },
+    "plogr": {
+      "Package": "plogr",
+      "Version": "0.2.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Hash": "09eb987710984fc2905c7129c7d85e65"
+    },
+    "plyr": {
+      "Package": "plyr",
+      "Version": "1.8.9",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "Rcpp"
+      ],
+      "Hash": "6b8177fd19982f0020743fadbfdbd933"
+    },
+    "pool": {
+      "Package": "pool",
+      "Version": "1.0.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "DBI",
+        "R",
+        "R6",
+        "later",
+        "methods",
+        "rlang"
+      ],
+      "Hash": "b336b9f1b3cc72033258c70dc17edbf1"
+    },
+    "rappdirs": {
+      "Package": "rappdirs",
+      "Version": "0.3.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "5e3c5dc0b071b21fa128676560dbe94d"
+    },
+    "renv": {
+      "Package": "renv",
+      "Version": "1.0.9",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "utils"
+      ],
+      "Hash": "ef233f0e9064fc88c898b340c9add5c2"
+    },
+    "reshape2": {
+      "Package": "reshape2",
+      "Version": "1.4.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "Rcpp",
+        "plyr",
+        "stringr"
+      ],
+      "Hash": "bb5996d0bd962d214a11140d77589917"
+    },
+    "rlang": {
+      "Package": "rlang",
+      "Version": "1.1.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "utils"
+      ],
+      "Hash": "3eec01f8b1dee337674b2e34ab1f9bc1"
+    },
+    "rmarkdown": {
+      "Package": "rmarkdown",
+      "Version": "2.28",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "bslib",
+        "evaluate",
+        "fontawesome",
+        "htmltools",
+        "jquerylib",
+        "jsonlite",
+        "knitr",
+        "methods",
+        "tinytex",
+        "tools",
+        "utils",
+        "xfun",
+        "yaml"
+      ],
+      "Hash": "062470668513dcda416927085ee9bdc7"
+    },
+    "rpart": {
+      "Package": "rpart",
+      "Version": "4.1.23",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics",
+        "stats"
+      ],
+      "Hash": "b3d390424f41d04174cccf84d49676c2"
+    },
+    "rstudioapi": {
+      "Package": "rstudioapi",
+      "Version": "0.16.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Hash": "96710351d642b70e8f02ddeb237c46a7"
+    },
+    "sass": {
+      "Package": "sass",
+      "Version": "0.4.9",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R6",
+        "fs",
+        "htmltools",
+        "rappdirs",
+        "rlang"
+      ],
+      "Hash": "d53dbfddf695303ea4ad66f86e99b95d"
+    },
+    "scales": {
+      "Package": "scales",
+      "Version": "1.3.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "R6",
+        "RColorBrewer",
+        "cli",
+        "farver",
+        "glue",
+        "labeling",
+        "lifecycle",
+        "munsell",
+        "rlang",
+        "viridisLite"
+      ],
+      "Hash": "c19df082ba346b0ffa6f833e92de34d1"
+    },
+    "stacomirtools": {
+      "Package": "stacomirtools",
+      "Version": "0.6.0.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "DBI",
+        "RODBC",
+        "RPostgres",
+        "methods",
+        "pool",
+        "utils",
+        "xtable"
+      ],
+      "Hash": "2b32e7d7b518bc46946e3b020e682d7d"
+    },
+    "stringi": {
+      "Package": "stringi",
+      "Version": "1.8.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "stats",
+        "tools",
+        "utils"
+      ],
+      "Hash": "39e1144fd75428983dc3f63aa53dfa91"
+    },
+    "stringr": {
+      "Package": "stringr",
+      "Version": "1.5.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "cli",
+        "glue",
+        "lifecycle",
+        "magrittr",
+        "rlang",
+        "stringi",
+        "vctrs"
+      ],
+      "Hash": "960e2ae9e09656611e0b8214ad543207"
+    },
+    "tibble": {
+      "Package": "tibble",
+      "Version": "3.2.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "fansi",
+        "lifecycle",
+        "magrittr",
+        "methods",
+        "pillar",
+        "pkgconfig",
+        "rlang",
+        "utils",
+        "vctrs"
+      ],
+      "Hash": "a84e2cc86d07289b3b6f5069df7a004c"
+    },
+    "tidyselect": {
+      "Package": "tidyselect",
+      "Version": "1.2.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "cli",
+        "glue",
+        "lifecycle",
+        "rlang",
+        "vctrs",
+        "withr"
+      ],
+      "Hash": "829f27b9c4919c16b593794a6344d6c0"
+    },
+    "timechange": {
+      "Package": "timechange",
+      "Version": "0.3.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "cpp11"
+      ],
+      "Hash": "c5f3c201b931cd6474d17d8700ccb1c8"
+    },
+    "tinytex": {
+      "Package": "tinytex",
+      "Version": "0.53",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "xfun"
+      ],
+      "Hash": "9db859e8aabbb474293dde3097839420"
+    },
+    "utf8": {
+      "Package": "utf8",
+      "Version": "1.2.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "62b65c52671e6665f803ff02954446e9"
+    },
+    "vctrs": {
+      "Package": "vctrs",
+      "Version": "0.6.5",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "cli",
+        "glue",
+        "lifecycle",
+        "rlang"
+      ],
+      "Hash": "c03fa420630029418f7e6da3667aac4a"
+    },
+    "viridis": {
+      "Package": "viridis",
+      "Version": "0.6.5",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "ggplot2",
+        "gridExtra",
+        "viridisLite"
+      ],
+      "Hash": "acd96d9fa70adeea4a5a1150609b9745"
+    },
+    "viridisLite": {
+      "Package": "viridisLite",
+      "Version": "0.4.2",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "c826c7c4241b6fc89ff55aaea3fa7491"
+    },
+    "withr": {
+      "Package": "withr",
+      "Version": "3.0.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics"
+      ],
+      "Hash": "07909200e8bbe90426fbfeb73e1e27aa"
+    },
+    "xfun": {
+      "Package": "xfun",
+      "Version": "0.47",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "stats",
+        "tools"
+      ],
+      "Hash": "36ab21660e2d095fef0d83f689e0477c"
+    },
+    "xtable": {
+      "Package": "xtable",
+      "Version": "1.8-4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "stats",
+        "utils"
+      ],
+      "Hash": "b8acdf8af494d9ec19ccb2481a9b11c2"
+    },
+    "yaml": {
+      "Package": "yaml",
+      "Version": "2.3.10",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Hash": "51dab85c6c98e50a18d7551e9d49f76c"
+    }
+  }
+}
diff --git a/renv/.gitignore b/renv/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..0ec0cbba2d7755cbd91956afaa585449906a1e16
--- /dev/null
+++ b/renv/.gitignore
@@ -0,0 +1,7 @@
+library/
+local/
+cellar/
+lock/
+python/
+sandbox/
+staging/
diff --git a/renv/activate.R b/renv/activate.R
new file mode 100644
index 0000000000000000000000000000000000000000..c360bf2962d9071ffee0bcb70101316cef71074b
--- /dev/null
+++ b/renv/activate.R
@@ -0,0 +1,1307 @@
+
+local({
+
+  # the requested version of renv
+  version <- "1.0.9"
+  attr(version, "sha") <- NULL
+
+  # the project directory
+  project <- Sys.getenv("RENV_PROJECT")
+  if (!nzchar(project))
+    project <- getwd()
+
+  # use start-up diagnostics if enabled
+  diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE")
+  if (diagnostics) {
+    start <- Sys.time()
+    profile <- tempfile("renv-startup-", fileext = ".Rprof")
+    utils::Rprof(profile)
+    on.exit({
+      utils::Rprof(NULL)
+      elapsed <- signif(difftime(Sys.time(), start, units = "auto"), digits = 2L)
+      writeLines(sprintf("- renv took %s to run the autoloader.", format(elapsed)))
+      writeLines(sprintf("- Profile: %s", profile))
+      print(utils::summaryRprof(profile))
+    }, add = TRUE)
+  }
+
+  # figure out whether the autoloader is enabled
+  enabled <- local({
+
+    # first, check config option
+    override <- getOption("renv.config.autoloader.enabled")
+    if (!is.null(override))
+      return(override)
+
+    # if we're being run in a context where R_LIBS is already set,
+    # don't load -- presumably we're being run as a sub-process and
+    # the parent process has already set up library paths for us
+    rcmd <- Sys.getenv("R_CMD", unset = NA)
+    rlibs <- Sys.getenv("R_LIBS", unset = NA)
+    if (!is.na(rlibs) && !is.na(rcmd))
+      return(FALSE)
+
+    # next, check environment variables
+    # TODO: prefer using the configuration one in the future
+    envvars <- c(
+      "RENV_CONFIG_AUTOLOADER_ENABLED",
+      "RENV_AUTOLOADER_ENABLED",
+      "RENV_ACTIVATE_PROJECT"
+    )
+
+    for (envvar in envvars) {
+      envval <- Sys.getenv(envvar, unset = NA)
+      if (!is.na(envval))
+        return(tolower(envval) %in% c("true", "t", "1"))
+    }
+
+    # enable by default
+    TRUE
+
+  })
+
+  # bail if we're not enabled
+  if (!enabled) {
+
+    # if we're not enabled, we might still need to manually load
+    # the user profile here
+    profile <- Sys.getenv("R_PROFILE_USER", unset = "~/.Rprofile")
+    if (file.exists(profile)) {
+      cfg <- Sys.getenv("RENV_CONFIG_USER_PROFILE", unset = "TRUE")
+      if (tolower(cfg) %in% c("true", "t", "1"))
+        sys.source(profile, envir = globalenv())
+    }
+
+    return(FALSE)
+
+  }
+
+  # avoid recursion
+  if (identical(getOption("renv.autoloader.running"), TRUE)) {
+    warning("ignoring recursive attempt to run renv autoloader")
+    return(invisible(TRUE))
+  }
+
+  # signal that we're loading renv during R startup
+  options(renv.autoloader.running = TRUE)
+  on.exit(options(renv.autoloader.running = NULL), add = TRUE)
+
+  # signal that we've consented to use renv
+  options(renv.consent = TRUE)
+
+  # load the 'utils' package eagerly -- this ensures that renv shims, which
+  # mask 'utils' packages, will come first on the search path
+  library(utils, lib.loc = .Library)
+
+  # unload renv if it's already been loaded
+  if ("renv" %in% loadedNamespaces())
+    unloadNamespace("renv")
+
+  # load bootstrap tools   
+  ansify <- function(text) {
+    if (renv_ansify_enabled())
+      renv_ansify_enhanced(text)
+    else
+      renv_ansify_default(text)
+  }
+  
+  renv_ansify_enabled <- function() {
+  
+    override <- Sys.getenv("RENV_ANSIFY_ENABLED", unset = NA)
+    if (!is.na(override))
+      return(as.logical(override))
+  
+    pane <- Sys.getenv("RSTUDIO_CHILD_PROCESS_PANE", unset = NA)
+    if (identical(pane, "build"))
+      return(FALSE)
+  
+    testthat <- Sys.getenv("TESTTHAT", unset = "false")
+    if (tolower(testthat) %in% "true")
+      return(FALSE)
+  
+    iderun <- Sys.getenv("R_CLI_HAS_HYPERLINK_IDE_RUN", unset = "false")
+    if (tolower(iderun) %in% "false")
+      return(FALSE)
+  
+    TRUE
+  
+  }
+  
+  renv_ansify_default <- function(text) {
+    text
+  }
+  
+  renv_ansify_enhanced <- function(text) {
+  
+    # R help links
+    pattern <- "`\\?(renv::(?:[^`])+)`"
+    replacement <- "`\033]8;;ide:help:\\1\a?\\1\033]8;;\a`"
+    text <- gsub(pattern, replacement, text, perl = TRUE)
+  
+    # runnable code
+    pattern <- "`(renv::(?:[^`])+)`"
+    replacement <- "`\033]8;;ide:run:\\1\a\\1\033]8;;\a`"
+    text <- gsub(pattern, replacement, text, perl = TRUE)
+  
+    # return ansified text
+    text
+  
+  }
+  
+  renv_ansify_init <- function() {
+  
+    envir <- renv_envir_self()
+    if (renv_ansify_enabled())
+      assign("ansify", renv_ansify_enhanced, envir = envir)
+    else
+      assign("ansify", renv_ansify_default, envir = envir)
+  
+  }
+  
+  `%||%` <- function(x, y) {
+    if (is.null(x)) y else x
+  }
+  
+  catf <- function(fmt, ..., appendLF = TRUE) {
+  
+    quiet <- getOption("renv.bootstrap.quiet", default = FALSE)
+    if (quiet)
+      return(invisible())
+  
+    msg <- sprintf(fmt, ...)
+    cat(msg, file = stdout(), sep = if (appendLF) "\n" else "")
+  
+    invisible(msg)
+  
+  }
+  
+  header <- function(label,
+                     ...,
+                     prefix = "#",
+                     suffix = "-",
+                     n = min(getOption("width"), 78))
+  {
+    label <- sprintf(label, ...)
+    n <- max(n - nchar(label) - nchar(prefix) - 2L, 8L)
+    if (n <= 0)
+      return(paste(prefix, label))
+  
+    tail <- paste(rep.int(suffix, n), collapse = "")
+    paste0(prefix, " ", label, " ", tail)
+  
+  }
+  
+  heredoc <- function(text, leave = 0) {
+  
+    # remove leading, trailing whitespace
+    trimmed <- gsub("^\\s*\\n|\\n\\s*$", "", text)
+  
+    # split into lines
+    lines <- strsplit(trimmed, "\n", fixed = TRUE)[[1L]]
+  
+    # compute common indent
+    indent <- regexpr("[^[:space:]]", lines)
+    common <- min(setdiff(indent, -1L)) - leave
+    text <- paste(substring(lines, common), collapse = "\n")
+  
+    # substitute in ANSI links for executable renv code
+    ansify(text)
+  
+  }
+  
+  startswith <- function(string, prefix) {
+    substring(string, 1, nchar(prefix)) == prefix
+  }
+  
+  bootstrap <- function(version, library) {
+  
+    friendly <- renv_bootstrap_version_friendly(version)
+    section <- header(sprintf("Bootstrapping renv %s", friendly))
+    catf(section)
+  
+    # attempt to download renv
+    catf("- Downloading renv ... ", appendLF = FALSE)
+    withCallingHandlers(
+      tarball <- renv_bootstrap_download(version),
+      error = function(err) {
+        catf("FAILED")
+        stop("failed to download:\n", conditionMessage(err))
+      }
+    )
+    catf("OK")
+    on.exit(unlink(tarball), add = TRUE)
+  
+    # now attempt to install
+    catf("- Installing renv  ... ", appendLF = FALSE)
+    withCallingHandlers(
+      status <- renv_bootstrap_install(version, tarball, library),
+      error = function(err) {
+        catf("FAILED")
+        stop("failed to install:\n", conditionMessage(err))
+      }
+    )
+    catf("OK")
+  
+    # add empty line to break up bootstrapping from normal output
+    catf("")
+  
+    return(invisible())
+  }
+  
+  renv_bootstrap_tests_running <- function() {
+    getOption("renv.tests.running", default = FALSE)
+  }
+  
+  renv_bootstrap_repos <- function() {
+  
+    # get CRAN repository
+    cran <- getOption("renv.repos.cran", "https://cloud.r-project.org")
+  
+    # check for repos override
+    repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA)
+    if (!is.na(repos)) {
+  
+      # check for RSPM; if set, use a fallback repository for renv
+      rspm <- Sys.getenv("RSPM", unset = NA)
+      if (identical(rspm, repos))
+        repos <- c(RSPM = rspm, CRAN = cran)
+  
+      return(repos)
+  
+    }
+  
+    # check for lockfile repositories
+    repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity)
+    if (!inherits(repos, "error") && length(repos))
+      return(repos)
+  
+    # retrieve current repos
+    repos <- getOption("repos")
+  
+    # ensure @CRAN@ entries are resolved
+    repos[repos == "@CRAN@"] <- cran
+  
+    # add in renv.bootstrap.repos if set
+    default <- c(FALLBACK = "https://cloud.r-project.org")
+    extra <- getOption("renv.bootstrap.repos", default = default)
+    repos <- c(repos, extra)
+  
+    # remove duplicates that might've snuck in
+    dupes <- duplicated(repos) | duplicated(names(repos))
+    repos[!dupes]
+  
+  }
+  
+  renv_bootstrap_repos_lockfile <- function() {
+  
+    lockpath <- Sys.getenv("RENV_PATHS_LOCKFILE", unset = "renv.lock")
+    if (!file.exists(lockpath))
+      return(NULL)
+  
+    lockfile <- tryCatch(renv_json_read(lockpath), error = identity)
+    if (inherits(lockfile, "error")) {
+      warning(lockfile)
+      return(NULL)
+    }
+  
+    repos <- lockfile$R$Repositories
+    if (length(repos) == 0)
+      return(NULL)
+  
+    keys <- vapply(repos, `[[`, "Name", FUN.VALUE = character(1))
+    vals <- vapply(repos, `[[`, "URL", FUN.VALUE = character(1))
+    names(vals) <- keys
+  
+    return(vals)
+  
+  }
+  
+  renv_bootstrap_download <- function(version) {
+  
+    sha <- attr(version, "sha", exact = TRUE)
+  
+    methods <- if (!is.null(sha)) {
+  
+      # attempting to bootstrap a development version of renv
+      c(
+        function() renv_bootstrap_download_tarball(sha),
+        function() renv_bootstrap_download_github(sha)
+      )
+  
+    } else {
+  
+      # attempting to bootstrap a release version of renv
+      c(
+        function() renv_bootstrap_download_tarball(version),
+        function() renv_bootstrap_download_cran_latest(version),
+        function() renv_bootstrap_download_cran_archive(version)
+      )
+  
+    }
+  
+    for (method in methods) {
+      path <- tryCatch(method(), error = identity)
+      if (is.character(path) && file.exists(path))
+        return(path)
+    }
+  
+    stop("All download methods failed")
+  
+  }
+  
+  renv_bootstrap_download_impl <- function(url, destfile) {
+  
+    mode <- "wb"
+  
+    # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715
+    fixup <-
+      Sys.info()[["sysname"]] == "Windows" &&
+      substring(url, 1L, 5L) == "file:"
+  
+    if (fixup)
+      mode <- "w+b"
+  
+    args <- list(
+      url      = url,
+      destfile = destfile,
+      mode     = mode,
+      quiet    = TRUE
+    )
+  
+    if ("headers" %in% names(formals(utils::download.file)))
+    {
+      headers <- renv_bootstrap_download_custom_headers(url)
+      if (length(headers) && is.character(headers))
+        args$headers <- headers
+    }
+  
+    do.call(utils::download.file, args)
+  
+  }
+  
+  renv_bootstrap_download_custom_headers <- function(url) {
+  
+    headers <- getOption("renv.download.headers")
+    if (is.null(headers))
+      return(character())
+  
+    if (!is.function(headers))
+      stopf("'renv.download.headers' is not a function")
+  
+    headers <- headers(url)
+    if (length(headers) == 0L)
+      return(character())
+  
+    if (is.list(headers))
+      headers <- unlist(headers, recursive = FALSE, use.names = TRUE)
+  
+    ok <-
+      is.character(headers) &&
+      is.character(names(headers)) &&
+      all(nzchar(names(headers)))
+  
+    if (!ok)
+      stop("invocation of 'renv.download.headers' did not return a named character vector")
+  
+    headers
+  
+  }
+  
+  renv_bootstrap_download_cran_latest <- function(version) {
+  
+    spec <- renv_bootstrap_download_cran_latest_find(version)
+    type  <- spec$type
+    repos <- spec$repos
+  
+    baseurl <- utils::contrib.url(repos = repos, type = type)
+    ext <- if (identical(type, "source"))
+      ".tar.gz"
+    else if (Sys.info()[["sysname"]] == "Windows")
+      ".zip"
+    else
+      ".tgz"
+    name <- sprintf("renv_%s%s", version, ext)
+    url <- paste(baseurl, name, sep = "/")
+  
+    destfile <- file.path(tempdir(), name)
+    status <- tryCatch(
+      renv_bootstrap_download_impl(url, destfile),
+      condition = identity
+    )
+  
+    if (inherits(status, "condition"))
+      return(FALSE)
+  
+    # report success and return
+    destfile
+  
+  }
+  
+  renv_bootstrap_download_cran_latest_find <- function(version) {
+  
+    # check whether binaries are supported on this system
+    binary <-
+      getOption("renv.bootstrap.binary", default = TRUE) &&
+      !identical(.Platform$pkgType, "source") &&
+      !identical(getOption("pkgType"), "source") &&
+      Sys.info()[["sysname"]] %in% c("Darwin", "Windows")
+  
+    types <- c(if (binary) "binary", "source")
+  
+    # iterate over types + repositories
+    for (type in types) {
+      for (repos in renv_bootstrap_repos()) {
+  
+        # build arguments for utils::available.packages() call
+        args <- list(type = type, repos = repos)
+  
+        # add custom headers if available -- note that
+        # utils::available.packages() will pass this to download.file()
+        if ("headers" %in% names(formals(utils::download.file)))
+        {
+          headers <- renv_bootstrap_download_custom_headers(url)
+          if (length(headers) && is.character(headers))
+            args$headers <- headers
+        }
+  
+        # retrieve package database
+        db <- tryCatch(
+          as.data.frame(
+            do.call(utils::available.packages, args),
+            stringsAsFactors = FALSE
+          ),
+          error = identity
+        )
+  
+        if (inherits(db, "error"))
+          next
+  
+        # check for compatible entry
+        entry <- db[db$Package %in% "renv" & db$Version %in% version, ]
+        if (nrow(entry) == 0)
+          next
+  
+        # found it; return spec to caller
+        spec <- list(entry = entry, type = type, repos = repos)
+        return(spec)
+  
+      }
+    }
+  
+    # if we got here, we failed to find renv
+    fmt <- "renv %s is not available from your declared package repositories"
+    stop(sprintf(fmt, version))
+  
+  }
+  
+  renv_bootstrap_download_cran_archive <- function(version) {
+  
+    name <- sprintf("renv_%s.tar.gz", version)
+    repos <- renv_bootstrap_repos()
+    urls <- file.path(repos, "src/contrib/Archive/renv", name)
+    destfile <- file.path(tempdir(), name)
+  
+    for (url in urls) {
+  
+      status <- tryCatch(
+        renv_bootstrap_download_impl(url, destfile),
+        condition = identity
+      )
+  
+      if (identical(status, 0L))
+        return(destfile)
+  
+    }
+  
+    return(FALSE)
+  
+  }
+  
+  renv_bootstrap_download_tarball <- function(version) {
+  
+    # if the user has provided the path to a tarball via
+    # an environment variable, then use it
+    tarball <- Sys.getenv("RENV_BOOTSTRAP_TARBALL", unset = NA)
+    if (is.na(tarball))
+      return()
+  
+    # allow directories
+    if (dir.exists(tarball)) {
+      name <- sprintf("renv_%s.tar.gz", version)
+      tarball <- file.path(tarball, name)
+    }
+  
+    # bail if it doesn't exist
+    if (!file.exists(tarball)) {
+  
+      # let the user know we weren't able to honour their request
+      fmt <- "- RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist."
+      msg <- sprintf(fmt, tarball)
+      warning(msg)
+  
+      # bail
+      return()
+  
+    }
+  
+    catf("- Using local tarball '%s'.", tarball)
+    tarball
+  
+  }
+  
+  renv_bootstrap_github_token <- function() {
+    for (envvar in c("GITHUB_TOKEN", "GITHUB_PAT", "GH_TOKEN")) {
+      envval <- Sys.getenv(envvar, unset = NA)
+      if (!is.na(envval))
+        return(envval)
+    }
+  }
+  
+  renv_bootstrap_download_github <- function(version) {
+  
+    enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE")
+    if (!identical(enabled, "TRUE"))
+      return(FALSE)
+  
+    # prepare download options
+    token <- renv_bootstrap_github_token()
+    if (nzchar(Sys.which("curl")) && nzchar(token)) {
+      fmt <- "--location --fail --header \"Authorization: token %s\""
+      extra <- sprintf(fmt, token)
+      saved <- options("download.file.method", "download.file.extra")
+      options(download.file.method = "curl", download.file.extra = extra)
+      on.exit(do.call(base::options, saved), add = TRUE)
+    } else if (nzchar(Sys.which("wget")) && nzchar(token)) {
+      fmt <- "--header=\"Authorization: token %s\""
+      extra <- sprintf(fmt, token)
+      saved <- options("download.file.method", "download.file.extra")
+      options(download.file.method = "wget", download.file.extra = extra)
+      on.exit(do.call(base::options, saved), add = TRUE)
+    }
+  
+    url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version)
+    name <- sprintf("renv_%s.tar.gz", version)
+    destfile <- file.path(tempdir(), name)
+  
+    status <- tryCatch(
+      renv_bootstrap_download_impl(url, destfile),
+      condition = identity
+    )
+  
+    if (!identical(status, 0L))
+      return(FALSE)
+  
+    renv_bootstrap_download_augment(destfile)
+  
+    return(destfile)
+  
+  }
+  
+  # Add Sha to DESCRIPTION. This is stop gap until #890, after which we
+  # can use renv::install() to fully capture metadata.
+  renv_bootstrap_download_augment <- function(destfile) {
+    sha <- renv_bootstrap_git_extract_sha1_tar(destfile)
+    if (is.null(sha)) {
+      return()
+    }
+  
+    # Untar
+    tempdir <- tempfile("renv-github-")
+    on.exit(unlink(tempdir, recursive = TRUE), add = TRUE)
+    untar(destfile, exdir = tempdir)
+    pkgdir <- dir(tempdir, full.names = TRUE)[[1]]
+  
+    # Modify description
+    desc_path <- file.path(pkgdir, "DESCRIPTION")
+    desc_lines <- readLines(desc_path)
+    remotes_fields <- c(
+      "RemoteType: github",
+      "RemoteHost: api.github.com",
+      "RemoteRepo: renv",
+      "RemoteUsername: rstudio",
+      "RemotePkgRef: rstudio/renv",
+      paste("RemoteRef: ", sha),
+      paste("RemoteSha: ", sha)
+    )
+    writeLines(c(desc_lines[desc_lines != ""], remotes_fields), con = desc_path)
+  
+    # Re-tar
+    local({
+      old <- setwd(tempdir)
+      on.exit(setwd(old), add = TRUE)
+  
+      tar(destfile, compression = "gzip")
+    })
+    invisible()
+  }
+  
+  # Extract the commit hash from a git archive. Git archives include the SHA1
+  # hash as the comment field of the tarball pax extended header
+  # (see https://www.kernel.org/pub/software/scm/git/docs/git-archive.html)
+  # For GitHub archives this should be the first header after the default one
+  # (512 byte) header.
+  renv_bootstrap_git_extract_sha1_tar <- function(bundle) {
+  
+    # open the bundle for reading
+    # We use gzcon for everything because (from ?gzcon)
+    # > Reading from a connection which does not supply a 'gzip' magic
+    # > header is equivalent to reading from the original connection
+    conn <- gzcon(file(bundle, open = "rb", raw = TRUE))
+    on.exit(close(conn))
+  
+    # The default pax header is 512 bytes long and the first pax extended header
+    # with the comment should be 51 bytes long
+    # `52 comment=` (11 chars) + 40 byte SHA1 hash
+    len <- 0x200 + 0x33
+    res <- rawToChar(readBin(conn, "raw", n = len)[0x201:len])
+  
+    if (grepl("^52 comment=", res)) {
+      sub("52 comment=", "", res)
+    } else {
+      NULL
+    }
+  }
+  
+  renv_bootstrap_install <- function(version, tarball, library) {
+  
+    # attempt to install it into project library
+    dir.create(library, showWarnings = FALSE, recursive = TRUE)
+    output <- renv_bootstrap_install_impl(library, tarball)
+  
+    # check for successful install
+    status <- attr(output, "status")
+    if (is.null(status) || identical(status, 0L))
+      return(status)
+  
+    # an error occurred; report it
+    header <- "installation of renv failed"
+    lines <- paste(rep.int("=", nchar(header)), collapse = "")
+    text <- paste(c(header, lines, output), collapse = "\n")
+    stop(text)
+  
+  }
+  
+  renv_bootstrap_install_impl <- function(library, tarball) {
+  
+    # invoke using system2 so we can capture and report output
+    bin <- R.home("bin")
+    exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R"
+    R <- file.path(bin, exe)
+  
+    args <- c(
+      "--vanilla", "CMD", "INSTALL", "--no-multiarch",
+      "-l", shQuote(path.expand(library)),
+      shQuote(path.expand(tarball))
+    )
+  
+    system2(R, args, stdout = TRUE, stderr = TRUE)
+  
+  }
+  
+  renv_bootstrap_platform_prefix <- function() {
+  
+    # construct version prefix
+    version <- paste(R.version$major, R.version$minor, sep = ".")
+    prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-")
+  
+    # include SVN revision for development versions of R
+    # (to avoid sharing platform-specific artefacts with released versions of R)
+    devel <-
+      identical(R.version[["status"]],   "Under development (unstable)") ||
+      identical(R.version[["nickname"]], "Unsuffered Consequences")
+  
+    if (devel)
+      prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r")
+  
+    # build list of path components
+    components <- c(prefix, R.version$platform)
+  
+    # include prefix if provided by user
+    prefix <- renv_bootstrap_platform_prefix_impl()
+    if (!is.na(prefix) && nzchar(prefix))
+      components <- c(prefix, components)
+  
+    # build prefix
+    paste(components, collapse = "/")
+  
+  }
+  
+  renv_bootstrap_platform_prefix_impl <- function() {
+  
+    # if an explicit prefix has been supplied, use it
+    prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA)
+    if (!is.na(prefix))
+      return(prefix)
+  
+    # if the user has requested an automatic prefix, generate it
+    auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA)
+    if (is.na(auto) && getRversion() >= "4.4.0")
+      auto <- "TRUE"
+  
+    if (auto %in% c("TRUE", "True", "true", "1"))
+      return(renv_bootstrap_platform_prefix_auto())
+  
+    # empty string on failure
+    ""
+  
+  }
+  
+  renv_bootstrap_platform_prefix_auto <- function() {
+  
+    prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity)
+    if (inherits(prefix, "error") || prefix %in% "unknown") {
+  
+      msg <- paste(
+        "failed to infer current operating system",
+        "please file a bug report at https://github.com/rstudio/renv/issues",
+        sep = "; "
+      )
+  
+      warning(msg)
+  
+    }
+  
+    prefix
+  
+  }
+  
+  renv_bootstrap_platform_os <- function() {
+  
+    sysinfo <- Sys.info()
+    sysname <- sysinfo[["sysname"]]
+  
+    # handle Windows + macOS up front
+    if (sysname == "Windows")
+      return("windows")
+    else if (sysname == "Darwin")
+      return("macos")
+  
+    # check for os-release files
+    for (file in c("/etc/os-release", "/usr/lib/os-release"))
+      if (file.exists(file))
+        return(renv_bootstrap_platform_os_via_os_release(file, sysinfo))
+  
+    # check for redhat-release files
+    if (file.exists("/etc/redhat-release"))
+      return(renv_bootstrap_platform_os_via_redhat_release())
+  
+    "unknown"
+  
+  }
+  
+  renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) {
+  
+    # read /etc/os-release
+    release <- utils::read.table(
+      file             = file,
+      sep              = "=",
+      quote            = c("\"", "'"),
+      col.names        = c("Key", "Value"),
+      comment.char     = "#",
+      stringsAsFactors = FALSE
+    )
+  
+    vars <- as.list(release$Value)
+    names(vars) <- release$Key
+  
+    # get os name
+    os <- tolower(sysinfo[["sysname"]])
+  
+    # read id
+    id <- "unknown"
+    for (field in c("ID", "ID_LIKE")) {
+      if (field %in% names(vars) && nzchar(vars[[field]])) {
+        id <- vars[[field]]
+        break
+      }
+    }
+  
+    # read version
+    version <- "unknown"
+    for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) {
+      if (field %in% names(vars) && nzchar(vars[[field]])) {
+        version <- vars[[field]]
+        break
+      }
+    }
+  
+    # join together
+    paste(c(os, id, version), collapse = "-")
+  
+  }
+  
+  renv_bootstrap_platform_os_via_redhat_release <- function() {
+  
+    # read /etc/redhat-release
+    contents <- readLines("/etc/redhat-release", warn = FALSE)
+  
+    # infer id
+    id <- if (grepl("centos", contents, ignore.case = TRUE))
+      "centos"
+    else if (grepl("redhat", contents, ignore.case = TRUE))
+      "redhat"
+    else
+      "unknown"
+  
+    # try to find a version component (very hacky)
+    version <- "unknown"
+  
+    parts <- strsplit(contents, "[[:space:]]")[[1L]]
+    for (part in parts) {
+  
+      nv <- tryCatch(numeric_version(part), error = identity)
+      if (inherits(nv, "error"))
+        next
+  
+      version <- nv[1, 1]
+      break
+  
+    }
+  
+    paste(c("linux", id, version), collapse = "-")
+  
+  }
+  
+  renv_bootstrap_library_root_name <- function(project) {
+  
+    # use project name as-is if requested
+    asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE")
+    if (asis)
+      return(basename(project))
+  
+    # otherwise, disambiguate based on project's path
+    id <- substring(renv_bootstrap_hash_text(project), 1L, 8L)
+    paste(basename(project), id, sep = "-")
+  
+  }
+  
+  renv_bootstrap_library_root <- function(project) {
+  
+    prefix <- renv_bootstrap_profile_prefix()
+  
+    path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA)
+    if (!is.na(path))
+      return(paste(c(path, prefix), collapse = "/"))
+  
+    path <- renv_bootstrap_library_root_impl(project)
+    if (!is.null(path)) {
+      name <- renv_bootstrap_library_root_name(project)
+      return(paste(c(path, prefix, name), collapse = "/"))
+    }
+  
+    renv_bootstrap_paths_renv("library", project = project)
+  
+  }
+  
+  renv_bootstrap_library_root_impl <- function(project) {
+  
+    root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA)
+    if (!is.na(root))
+      return(root)
+  
+    type <- renv_bootstrap_project_type(project)
+    if (identical(type, "package")) {
+      userdir <- renv_bootstrap_user_dir()
+      return(file.path(userdir, "library"))
+    }
+  
+  }
+  
+  renv_bootstrap_validate_version <- function(version, description = NULL) {
+  
+    # resolve description file
+    #
+    # avoid passing lib.loc to `packageDescription()` below, since R will
+    # use the loaded version of the package by default anyhow. note that
+    # this function should only be called after 'renv' is loaded
+    # https://github.com/rstudio/renv/issues/1625
+    description <- description %||% packageDescription("renv")
+  
+    # check whether requested version 'version' matches loaded version of renv
+    sha <- attr(version, "sha", exact = TRUE)
+    valid <- if (!is.null(sha))
+      renv_bootstrap_validate_version_dev(sha, description)
+    else
+      renv_bootstrap_validate_version_release(version, description)
+  
+    if (valid)
+      return(TRUE)
+  
+    # the loaded version of renv doesn't match the requested version;
+    # give the user instructions on how to proceed
+    dev <- identical(description[["RemoteType"]], "github")
+    remote <- if (dev)
+      paste("rstudio/renv", description[["RemoteSha"]], sep = "@")
+    else
+      paste("renv", description[["Version"]], sep = "@")
+  
+    # display both loaded version + sha if available
+    friendly <- renv_bootstrap_version_friendly(
+      version = description[["Version"]],
+      sha     = if (dev) description[["RemoteSha"]]
+    )
+  
+    fmt <- heredoc("
+      renv %1$s was loaded from project library, but this project is configured to use renv %2$s.
+      - Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.
+      - Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.
+    ")
+    catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote)
+  
+    FALSE
+  
+  }
+  
+  renv_bootstrap_validate_version_dev <- function(version, description) {
+    expected <- description[["RemoteSha"]]
+    is.character(expected) && startswith(expected, version)
+  }
+  
+  renv_bootstrap_validate_version_release <- function(version, description) {
+    expected <- description[["Version"]]
+    is.character(expected) && identical(expected, version)
+  }
+  
+  renv_bootstrap_hash_text <- function(text) {
+  
+    hashfile <- tempfile("renv-hash-")
+    on.exit(unlink(hashfile), add = TRUE)
+  
+    writeLines(text, con = hashfile)
+    tools::md5sum(hashfile)
+  
+  }
+  
+  renv_bootstrap_load <- function(project, libpath, version) {
+  
+    # try to load renv from the project library
+    if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE))
+      return(FALSE)
+  
+    # warn if the version of renv loaded does not match
+    renv_bootstrap_validate_version(version)
+  
+    # execute renv load hooks, if any
+    hooks <- getHook("renv::autoload")
+    for (hook in hooks)
+      if (is.function(hook))
+        tryCatch(hook(), error = warnify)
+  
+    # load the project
+    renv::load(project)
+  
+    TRUE
+  
+  }
+  
+  renv_bootstrap_profile_load <- function(project) {
+  
+    # if RENV_PROFILE is already set, just use that
+    profile <- Sys.getenv("RENV_PROFILE", unset = NA)
+    if (!is.na(profile) && nzchar(profile))
+      return(profile)
+  
+    # check for a profile file (nothing to do if it doesn't exist)
+    path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project)
+    if (!file.exists(path))
+      return(NULL)
+  
+    # read the profile, and set it if it exists
+    contents <- readLines(path, warn = FALSE)
+    if (length(contents) == 0L)
+      return(NULL)
+  
+    # set RENV_PROFILE
+    profile <- contents[[1L]]
+    if (!profile %in% c("", "default"))
+      Sys.setenv(RENV_PROFILE = profile)
+  
+    profile
+  
+  }
+  
+  renv_bootstrap_profile_prefix <- function() {
+    profile <- renv_bootstrap_profile_get()
+    if (!is.null(profile))
+      return(file.path("profiles", profile, "renv"))
+  }
+  
+  renv_bootstrap_profile_get <- function() {
+    profile <- Sys.getenv("RENV_PROFILE", unset = "")
+    renv_bootstrap_profile_normalize(profile)
+  }
+  
+  renv_bootstrap_profile_set <- function(profile) {
+    profile <- renv_bootstrap_profile_normalize(profile)
+    if (is.null(profile))
+      Sys.unsetenv("RENV_PROFILE")
+    else
+      Sys.setenv(RENV_PROFILE = profile)
+  }
+  
+  renv_bootstrap_profile_normalize <- function(profile) {
+  
+    if (is.null(profile) || profile %in% c("", "default"))
+      return(NULL)
+  
+    profile
+  
+  }
+  
+  renv_bootstrap_path_absolute <- function(path) {
+  
+    substr(path, 1L, 1L) %in% c("~", "/", "\\") || (
+      substr(path, 1L, 1L) %in% c(letters, LETTERS) &&
+      substr(path, 2L, 3L) %in% c(":/", ":\\")
+    )
+  
+  }
+  
+  renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) {
+    renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv")
+    root <- if (renv_bootstrap_path_absolute(renv)) NULL else project
+    prefix <- if (profile) renv_bootstrap_profile_prefix()
+    components <- c(root, renv, prefix, ...)
+    paste(components, collapse = "/")
+  }
+  
+  renv_bootstrap_project_type <- function(path) {
+  
+    descpath <- file.path(path, "DESCRIPTION")
+    if (!file.exists(descpath))
+      return("unknown")
+  
+    desc <- tryCatch(
+      read.dcf(descpath, all = TRUE),
+      error = identity
+    )
+  
+    if (inherits(desc, "error"))
+      return("unknown")
+  
+    type <- desc$Type
+    if (!is.null(type))
+      return(tolower(type))
+  
+    package <- desc$Package
+    if (!is.null(package))
+      return("package")
+  
+    "unknown"
+  
+  }
+  
+  renv_bootstrap_user_dir <- function() {
+    dir <- renv_bootstrap_user_dir_impl()
+    path.expand(chartr("\\", "/", dir))
+  }
+  
+  renv_bootstrap_user_dir_impl <- function() {
+  
+    # use local override if set
+    override <- getOption("renv.userdir.override")
+    if (!is.null(override))
+      return(override)
+  
+    # use R_user_dir if available
+    tools <- asNamespace("tools")
+    if (is.function(tools$R_user_dir))
+      return(tools$R_user_dir("renv", "cache"))
+  
+    # try using our own backfill for older versions of R
+    envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME")
+    for (envvar in envvars) {
+      root <- Sys.getenv(envvar, unset = NA)
+      if (!is.na(root))
+        return(file.path(root, "R/renv"))
+    }
+  
+    # use platform-specific default fallbacks
+    if (Sys.info()[["sysname"]] == "Windows")
+      file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv")
+    else if (Sys.info()[["sysname"]] == "Darwin")
+      "~/Library/Caches/org.R-project.R/R/renv"
+    else
+      "~/.cache/R/renv"
+  
+  }
+  
+  renv_bootstrap_version_friendly <- function(version, shafmt = NULL, sha = NULL) {
+    sha <- sha %||% attr(version, "sha", exact = TRUE)
+    parts <- c(version, sprintf(shafmt %||% " [sha: %s]", substring(sha, 1L, 7L)))
+    paste(parts, collapse = "")
+  }
+  
+  renv_bootstrap_exec <- function(project, libpath, version) {
+    if (!renv_bootstrap_load(project, libpath, version))
+      renv_bootstrap_run(version, libpath)
+  }
+  
+  renv_bootstrap_run <- function(version, libpath) {
+  
+    # perform bootstrap
+    bootstrap(version, libpath)
+  
+    # exit early if we're just testing bootstrap
+    if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA)))
+      return(TRUE)
+  
+    # try again to load
+    if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) {
+      return(renv::load(project = getwd()))
+    }
+  
+    # failed to download or load renv; warn the user
+    msg <- c(
+      "Failed to find an renv installation: the project will not be loaded.",
+      "Use `renv::activate()` to re-initialize the project."
+    )
+  
+    warning(paste(msg, collapse = "\n"), call. = FALSE)
+  
+  }
+  
+  renv_json_read <- function(file = NULL, text = NULL) {
+  
+    jlerr <- NULL
+  
+    # if jsonlite is loaded, use that instead
+    if ("jsonlite" %in% loadedNamespaces()) {
+  
+      json <- tryCatch(renv_json_read_jsonlite(file, text), error = identity)
+      if (!inherits(json, "error"))
+        return(json)
+  
+      jlerr <- json
+  
+    }
+  
+    # otherwise, fall back to the default JSON reader
+    json <- tryCatch(renv_json_read_default(file, text), error = identity)
+    if (!inherits(json, "error"))
+      return(json)
+  
+    # report an error
+    if (!is.null(jlerr))
+      stop(jlerr)
+    else
+      stop(json)
+  
+  }
+  
+  renv_json_read_jsonlite <- function(file = NULL, text = NULL) {
+    text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n")
+    jsonlite::fromJSON(txt = text, simplifyVector = FALSE)
+  }
+  
+  renv_json_read_default <- function(file = NULL, text = NULL) {
+  
+    # find strings in the JSON
+    text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n")
+    pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
+    locs <- gregexpr(pattern, text, perl = TRUE)[[1]]
+  
+    # if any are found, replace them with placeholders
+    replaced <- text
+    strings <- character()
+    replacements <- character()
+  
+    if (!identical(c(locs), -1L)) {
+  
+      # get the string values
+      starts <- locs
+      ends <- locs + attr(locs, "match.length") - 1L
+      strings <- substring(text, starts, ends)
+  
+      # only keep those requiring escaping
+      strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE)
+  
+      # compute replacements
+      replacements <- sprintf('"\032%i\032"', seq_along(strings))
+  
+      # replace the strings
+      mapply(function(string, replacement) {
+        replaced <<- sub(string, replacement, replaced, fixed = TRUE)
+      }, strings, replacements)
+  
+    }
+  
+    # transform the JSON into something the R parser understands
+    transformed <- replaced
+    transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE)
+    transformed <- gsub("[[{]", "list(", transformed, perl = TRUE)
+    transformed <- gsub("[]}]", ")", transformed, perl = TRUE)
+    transformed <- gsub(":", "=", transformed, fixed = TRUE)
+    text <- paste(transformed, collapse = "\n")
+  
+    # parse it
+    json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]]
+  
+    # construct map between source strings, replaced strings
+    map <- as.character(parse(text = strings))
+    names(map) <- as.character(parse(text = replacements))
+  
+    # convert to list
+    map <- as.list(map)
+  
+    # remap strings in object
+    remapped <- renv_json_read_remap(json, map)
+  
+    # evaluate
+    eval(remapped, envir = baseenv())
+  
+  }
+  
+  renv_json_read_remap <- function(json, map) {
+  
+    # fix names
+    if (!is.null(names(json))) {
+      lhs <- match(names(json), names(map), nomatch = 0L)
+      rhs <- match(names(map), names(json), nomatch = 0L)
+      names(json)[rhs] <- map[lhs]
+    }
+  
+    # fix values
+    if (is.character(json))
+      return(map[[json]] %||% json)
+  
+    # handle true, false, null
+    if (is.name(json)) {
+      text <- as.character(json)
+      if (text == "true")
+        return(TRUE)
+      else if (text == "false")
+        return(FALSE)
+      else if (text == "null")
+        return(NULL)
+    }
+  
+    # recurse
+    if (is.recursive(json)) {
+      for (i in seq_along(json)) {
+        json[i] <- list(renv_json_read_remap(json[[i]], map))
+      }
+    }
+  
+    json
+  
+  }
+
+  # load the renv profile, if any
+  renv_bootstrap_profile_load(project)
+
+  # construct path to library root
+  root <- renv_bootstrap_library_root(project)
+
+  # construct library prefix for platform
+  prefix <- renv_bootstrap_platform_prefix()
+
+  # construct full libpath
+  libpath <- file.path(root, prefix)
+
+  # run bootstrap code
+  renv_bootstrap_exec(project, libpath, version)
+
+  invisible()
+
+})
diff --git a/renv/settings.json b/renv/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..74c1d4bb846f81c54728052b3d1f4b7f738e93c1
--- /dev/null
+++ b/renv/settings.json
@@ -0,0 +1,19 @@
+{
+  "bioconductor.version": null,
+  "external.libraries": [],
+  "ignored.packages": [],
+  "package.dependency.fields": [
+    "Imports",
+    "Depends",
+    "LinkingTo"
+  ],
+  "ppm.enabled": null,
+  "ppm.ignored.urls": [],
+  "r.version": null,
+  "snapshot.type": "explicit",
+  "use.cache": true,
+  "vcs.ignore.cellar": true,
+  "vcs.ignore.library": true,
+  "vcs.ignore.local": true,
+  "vcs.manage.ignores": true
+}
diff --git a/tests/testthat/helper.R b/tests/testthat/helper.R
index 9ba852e9c2d71a140ffa54428c761b8a098fc081..f8577098c6a672f5a0129bf64e5cfd8b186c5ec9 100644
--- a/tests/testthat/helper.R
+++ b/tests/testthat/helper.R
@@ -3,13 +3,13 @@
 # this file is called before testhat so funcion will be available in all test
 # https://testthat.r-lib.org/articles/test-fixtures.html#withr-defer-
 # could have used with_envvar and local_envvar but had to set them each time
-options(					
-    stacomiR.dbname = "bd_contmig_nat_test",
-    stacomiR.host ="localhost",
-    stacomiR.port = "5432",
-    stacomiR.user = "test",
-    stacomiR.password = "test"				
-)
+# options(					
+#     stacomiR.dbname = "bd_contmig_nat_test",
+#     stacomiR.host ="localhost",
+#     stacomiR.port = "5432",
+#     stacomiR.user = "test",
+#     stacomiR.password = "test"				
+# )
 password <- getOption("stacomiR.password") #if not set will be ""
 dbname <- getOption("stacomiR.dbname") #if not set will be ""
 user <- getOption("stacomiR.user")