diff --git a/.gitignore b/.gitignore index 2b6d31e..1b8929f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,11 @@ .Rhistory .RData .Ruserdata - +.DS_Store +Thumbs.db .httr-oauth +/public/ +/resources/ content/post/.DS_Store diff --git a/config.yaml b/config.yaml index 3816851..732f7f5 100644 --- a/config.yaml +++ b/config.yaml @@ -1,4 +1,4 @@ -baseurl: / +baseurl: https://trusting-payne-5ce5b1.netlify.app/ languageCode: en-us title: A Hugo website theme: hugo-lithium @@ -17,9 +17,9 @@ menu: - name: About url: /about/ - name: GitHub - url: https://github.com/rstudio/blogdown + url: https://github.com/dwfainstein/finalproject_653 - name: Twitter - url: https://twitter.com/rstudio + url: https://twitter.com/TeachAbilities params: MathJaxCDN: //cdnjs.cloudflare.com/ajax/libs MathJaxVersion: 2.7.5 diff --git a/content/post/2021-06-01-importing-strava-data/index.Rmarkdown b/content/post/2021-06-01-importing-strava-data/index.Rmarkdown index a5f6711..1914c3f 100644 --- a/content/post/2021-06-01-importing-strava-data/index.Rmarkdown +++ b/content/post/2021-06-01-importing-strava-data/index.Rmarkdown @@ -21,13 +21,13 @@ knitr::opts_chunk$set(echo = TRUE) # Importing Strava data for use with RStudio -This blog post will guide you the somewhat complicated process of bringing in your own personal Strava data for use within the RStudio environment. To begin, you will need to have two things: an active Strava account and an RStudio .Rmd ready to use. +This blog post will guide you through the somewhat complicated process of bringing in your own personal Strava data to analyze with R. To begin, you will need to have two things: an active Strava account and an RStudio `.Rmd` ready to use. This post will cover two distinct two ways to download your data. -[The first method: complex and limited (but small!)](#the-first-method-complex-and-limited-but-small) is somewhat complex, and uses API calls to return a dataframe containing a fairly limited set of information: Distance, speed, duration, elevation, location, and time. +[The first method](#the-first-method-complex-and-limited-but-small) is somewhat complex, and uses API calls to return a data frame containing a fairly limited set of information: Distance, speed, duration, elevation, location, and time. -[The second method: quick and easy, but can be a very large download!] (just threaten to delete your account and they will give you an option to download all data they have collected!) and returns a much larger set of information...all of the preceding information, plus entire route maps for each activity, as well any photos you uploaded to Strava with those activities. +[The second method](#the-second-method-quick-and-easy-but-can-be-a-very-large-download) threatens to delete your account, but they give you an option to download all data they have collected! It returns a much larger set of information...all of the preceding information, plus entire route maps for each activity, as well any photos you uploaded to Strava with those activities. ## The first method: complex and limited (but small!) {#the-first-method-complex-and-limited-but-small} @@ -35,11 +35,11 @@ First, visit . If you are not logged in, it will prompt you to enter your login credentials. Once you are logged in, you will be taken to the Strava page to create an API Application. -
+ ![initial API screen](img/shot1.png) -
+ You will need to enter some basic information to complete this process. @@ -57,21 +57,21 @@ For the **authorization callback domain**, enter *developers.strava.com.* When you are done, you should have it filled out something like this: -
+ ![completed API creation form](img/shot2.png) -
+ When you click on Create, it will ask you to update your app icon. You can add any image file you like, and then it will take you to a screen listing your information. -
+ ![click to reveal the secret!](img/shot4.png) -
-For the next step, you will need to show your **Client Secret**, which will display a long alphanumeric string that is unique to you. This allows RStudio to talk to Strava for the initial handshake, verifying your identity and allowing RStudio to pull your data. + +For the next step, you will need to show your **Client Secret**, which will display a long alphanumeric string that is unique to you. This allows R to talk to Strava for the initial handshake, verifying your identity and allowing R to pull your data. In your .Rmd, add the following lines of code: @@ -125,15 +125,15 @@ Some things to note: be sure to enter your own **Application Name**, **Client ID Check both boxes, and then click Authorize to link Strava with your data. -
+ ![click to authorize](img/shot5.png) -
+ After the Authorization is complete, you will have a file called *stoken* appear in your working environment. Once that file is in place, you can comment out the two lines of code directly under the spot where you entered your Client Secret. You will see a little note there that it only needs to happen once: -\#create the authentication token (only once) +`#create the authentication token (only once)` Once you run that chunk, it will download your data into a dataframe called "**data_df.Rda**" which a simple click will add to RStudio for your continued exploration. @@ -141,27 +141,27 @@ Once you run that chunk, it will download your data into a dataframe called "**d ## The second method: quick and easy, but can be a very large download! -This method is pretty simple. Simply visit and scroll down a bit to the *Download Request* section. +This method is pretty simple. Visit and scroll down a bit to the *Download Request* section. + -
![But I don't want to delete my account!](img/shot7.png) -
+ Click on the Request Your Archive button, and they will prepare your archive and email you a download link to the email they have on file. Make sure your email address is up to date! -
+ ![Seven days to get this done!](img/shot8.png) -
+ Soon, you will get a download link in your email. Click to download, and you will soon have a folder full of everything that Strava has collected on you as an athlete. -The most useful files for Rstudio will the .csv that houses all of your activity data, and the .gpx files that contain a fairly complete map every individual activity. +The most useful files will be the `.csv` that houses all of your activity data, and the `.gpx` files that contain a fairly complete map of every individual activity. -To add the .csv file, make sure that activities.csv file is housed in a **data** folder in your project directory, and then run the following code: +To add the `.csv` file, make sure that `activities.csv` file is housed in a **data** folder in your project directory, and then run the following code: ```{r importing desired data fields, eval=FALSE} library(readr) @@ -174,14 +174,13 @@ activities <- read_csv("data/activities.csv", `Distance` =col_number(), `Elevation Gain` =col_number())) View(activities) - ``` -Once you have done that, you should have a .csv file with all of your activities. If you would also like to work with the .gpx files for detailed maps of everything you've done, the following code will do the trick: +Once you have done that, you should have a `.csv` file with all of your activities. If you would also like to work with the `.gpx` files for detailed maps of everything you've done, the following code will do the trick: ```{r bringing in the gpx data, eval=FALSE} gpxdata <- process_data("data/activities_gpx") #gpxdata <- slice(gpxdata, -c(63744, 63745, 63746)) YOU MIGHT NEED TO USE SOMETHINNG LIKE THIS LINE IF YOU BRING IN IN ANY BAD DATA...I DID ``` -You will have to wait a while, as this is quite a large file to bring in...but once it is in, you will have quite a few options for manipulating your data! As a first step, you will want to tidy your imported data. See David's informative blog post for more details on how to do that. +You will have to wait a while, as this is quite a large file to bring in...but once it is in, you will have quite a few options for manipulating your data! As a first step, you will want to tidy your imported data. See [David's informative blog post](/2021/06/02/tidying-and-wrangling-strava-data/) for more details on how to do that. diff --git a/content/post/2021-06-01-importing-strava-data/index.markdown b/content/post/2021-06-01-importing-strava-data/index.markdown index 0af8065..8beca38 100644 --- a/content/post/2021-06-01-importing-strava-data/index.markdown +++ b/content/post/2021-06-01-importing-strava-data/index.markdown @@ -17,25 +17,25 @@ tags: [] # Importing Strava data for use with RStudio -This blog post will guide you the somewhat complicated process of bringing in your own personal Strava data for use within the RStudio environment. To begin, you will need to have two things: an active Strava account and an RStudio .Rmd ready to use. +This blog post will guide you through the somewhat complicated process of bringing in your own personal Strava data to analyze with R. To begin, you will need to have two things: an active Strava account and an RStudio `.Rmd` ready to use. This post will cover two distinct two ways to download your data. -[The first method: complex and limited (but small!)](#the-first-method-complex-and-limited-but-small) is somewhat complex, and uses API calls to return a dataframe containing a fairly limited set of information: Distance, speed, duration, elevation, location, and time. +[The first method](#the-first-method-complex-and-limited-but-small) is somewhat complex, and uses API calls to return a data frame containing a fairly limited set of information: Distance, speed, duration, elevation, location, and time. -[The second method: quick and easy, but can be a very large download!] (just threaten to delete your account and they will give you an option to download all data they have collected!) and returns a much larger set of information...all of the preceding information, plus entire route maps for each activity, as well any photos you uploaded to Strava with those activities. +[The second method](#the-second-method-quick-and-easy-but-can-be-a-very-large-download) threatens to delete your account, but they give you an option to download all data they have collected! It returns a much larger set of information...all of the preceding information, plus entire route maps for each activity, as well any photos you uploaded to Strava with those activities. ## The first method: complex and limited (but small!) {#the-first-method-complex-and-limited-but-small} First, visit . -If you are not logged in, it will prompt you to enter your login credentials. Once you are logged in, you will be taken to the Strava page to create an API Application. +If you are not logged in, it will prompt you to enter your login credentials. Once you are logged in, you will be taken to the Strava page to create an API Application. + -
![initial API screen](img/shot1.png) -
+ You will need to enter some basic information to complete this process. @@ -53,21 +53,21 @@ For the **authorization callback domain**, enter *developers.strava.com.* When you are done, you should have it filled out something like this: -
+ ![completed API creation form](img/shot2.png) -
+ When you click on Create, it will ask you to update your app icon. You can add any image file you like, and then it will take you to a screen listing your information. -
+ ![click to reveal the secret!](img/shot4.png) -
-For the next step, you will need to show your **Client Secret**, which will display a long alphanumeric string that is unique to you. This allows RStudio to talk to Strava for the initial handshake, verifying your identity and allowing RStudio to pull your data. + +For the next step, you will need to show your **Client Secret**, which will display a long alphanumeric string that is unique to you. This allows R to talk to Strava for the initial handshake, verifying your identity and allowing R to pull your data. In your .Rmd, add the following lines of code: @@ -121,15 +121,15 @@ Some things to note: be sure to enter your own **Application Name**, **Client ID Check both boxes, and then click Authorize to link Strava with your data. -
+ ![click to authorize](img/shot5.png) -
+ After the Authorization is complete, you will have a file called *stoken* appear in your working environment. Once that file is in place, you can comment out the two lines of code directly under the spot where you entered your Client Secret. You will see a little note there that it only needs to happen once: -\#create the authentication token (only once) +`#create the authentication token (only once)` Once you run that chunk, it will download your data into a dataframe called "**data_df.Rda**" which a simple click will add to RStudio for your continued exploration. @@ -137,27 +137,27 @@ Once you run that chunk, it will download your data into a dataframe called "**d ## The second method: quick and easy, but can be a very large download! -This method is pretty simple. Simply visit and scroll down a bit to the *Download Request* section. +This method is pretty simple. Visit and scroll down a bit to the *Download Request* section. + -
![But I don't want to delete my account!](img/shot7.png) -
+ Click on the Request Your Archive button, and they will prepare your archive and email you a download link to the email they have on file. Make sure your email address is up to date! -
+ ![Seven days to get this done!](img/shot8.png) -
+ Soon, you will get a download link in your email. Click to download, and you will soon have a folder full of everything that Strava has collected on you as an athlete. -The most useful files for Rstudio will the .csv that houses all of your activity data, and the .gpx files that contain a fairly complete map every individual activity. +The most useful files will be the `.csv` that houses all of your activity data, and the `.gpx` files that contain a fairly complete map of every individual activity. -To add the .csv file, make sure that activities.csv file is housed in a **data** folder in your project directory, and then run the following code: +To add the `.csv` file, make sure that `activities.csv` file is housed in a **data** folder in your project directory, and then run the following code: ```r @@ -173,7 +173,7 @@ activities <- read_csv("data/activities.csv", View(activities) ``` -Once you have done that, you should have a .csv file with all of your activities. If you would also like to work with the .gpx files for detailed maps of everything you've done, the following code will do the trick: +Once you have done that, you should have a `.csv` file with all of your activities. If you would also like to work with the `.gpx` files for detailed maps of everything you've done, the following code will do the trick: ```r @@ -181,4 +181,4 @@ gpxdata <- process_data("data/activities_gpx") #gpxdata <- slice(gpxdata, -c(63744, 63745, 63746)) YOU MIGHT NEED TO USE SOMETHINNG LIKE THIS LINE IF YOU BRING IN IN ANY BAD DATA...I DID ``` -You will have to wait a while, as this is quite a large file to bring in...but once it is in, you will have quite a few options for manipulating your data! As a first step, you will want to tidy your imported data. See David's informative blog post for more details on how to do that. +You will have to wait a while, as this is quite a large file to bring in...but once it is in, you will have quite a few options for manipulating your data! As a first step, you will want to tidy your imported data. See [David's informative blog post](/2021/06/02/tidying-and-wrangling-strava-data/) for more details on how to do that. diff --git a/content/post/2021-06-01-parallel-iteration/index.Rmarkdown b/content/post/2021-06-01-parallel-iteration/index.Rmarkdown index d9a8164..73127e5 100644 --- a/content/post/2021-06-01-parallel-iteration/index.Rmarkdown +++ b/content/post/2021-06-01-parallel-iteration/index.Rmarkdown @@ -40,7 +40,7 @@ Earlier in our blog series, you can read a post on how we used API calls to brin ```{r firststep} #reading in data for sandbox -strav_data <- read_csv(here("content/post/2021-04-16-functional-programming-with-strava-data/data", "strav_csv.csv")) +strav_data <- read_csv(here("static", "data", "strav_csv.csv")) tidyfunc <- strav_data %>% select(where(~length(unique(.)) > 1)) %>% @@ -86,6 +86,7 @@ oneplot <- tidy_data %>% subtitle = "Data displays trends found within the week", x = "", y = "Number of Hikes") +oneplot ``` Now we will create a parallel iteration of the data by grouping by activity and nesting. This will create a data frame with individual frames nested within it categorized by activity. By doing this, we are able to produce separate plots displaying weekly data for each activity type. @@ -99,7 +100,7 @@ final_plots <- nest() %>% mutate(plots = map2(data, act_type, ~{ ggplot(.x, aes(weekday)) + - geom_histogram(stat = "count") + + geom_bar(stat = "count") + labs(title = glue("Amount of {.y} activity over the week"), subtitle = "Data displays trends found within the week", x = "", @@ -109,6 +110,7 @@ final_plots <- #display a plot. To change which activity you are able to view, change the number within the brackets. weeklydata$plots[[2]] +weeklydata$plots[[4]] ``` The final step is to save all of the plots. We will do this in three steps: diff --git a/content/post/2021-06-01-parallel-iteration/index.markdown b/content/post/2021-06-01-parallel-iteration/index.markdown index 601f3c8..1e69528 100644 --- a/content/post/2021-06-01-parallel-iteration/index.markdown +++ b/content/post/2021-06-01-parallel-iteration/index.markdown @@ -40,8 +40,11 @@ oneplot <- tidy_data %>% subtitle = "Data displays trends found within the week", x = "", y = "Number of Hikes") +oneplot ``` + + Now we will create a parallel iteration of the data by grouping by activity and nesting. This will create a data frame with individual frames nested within it categorized by activity. By doing this, we are able to produce separate plots displaying weekly data for each activity type. @@ -54,7 +57,7 @@ final_plots <- nest() %>% mutate(plots = map2(data, act_type, ~{ ggplot(.x, aes(weekday)) + - geom_histogram(stat = "count") + + geom_bar(stat = "count") + labs(title = glue("Amount of {.y} activity over the week"), subtitle = "Data displays trends found within the week", x = "", @@ -67,6 +70,12 @@ weeklydata$plots[[2]] +```r +weeklydata$plots[[4]] +``` + + + The final step is to save all of the plots. We will do this in three steps: 1. create a directory within your machine's files 2. create file paths for the plots to follow diff --git a/content/post/2021-06-01-parallel-iteration/index_files/figure-html/multiple plots-1.png b/content/post/2021-06-01-parallel-iteration/index_files/figure-html/multiple plots-1.png index 06c6eea..daff69c 100644 Binary files a/content/post/2021-06-01-parallel-iteration/index_files/figure-html/multiple plots-1.png and b/content/post/2021-06-01-parallel-iteration/index_files/figure-html/multiple plots-1.png differ diff --git a/content/post/2021-06-01-parallel-iteration/index_files/figure-html/multiple plots-2.png b/content/post/2021-06-01-parallel-iteration/index_files/figure-html/multiple plots-2.png new file mode 100644 index 0000000..7d43613 Binary files /dev/null and b/content/post/2021-06-01-parallel-iteration/index_files/figure-html/multiple plots-2.png differ diff --git a/content/post/2021-06-01-parallel-iteration/index_files/figure-html/one plot-1.png b/content/post/2021-06-01-parallel-iteration/index_files/figure-html/one plot-1.png new file mode 100644 index 0000000..90e68b2 Binary files /dev/null and b/content/post/2021-06-01-parallel-iteration/index_files/figure-html/one plot-1.png differ diff --git a/content/post/2021-06-01-ridgeline-plots/index.html b/content/post/2021-06-01-ridgeline-plots/index.html deleted file mode 100644 index ebdfec5..0000000 --- a/content/post/2021-06-01-ridgeline-plots/index.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - - - - - - - - - - - - -Ridgeline Plots - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - -
-

Let’s have fun with your Strava data!

-

This blog post is intended to provide an additional example of the ways personal data can be used. Our final product will be a ridgeline plot a la Joy Division’s Unknown Pleasures. Slap it on a t-shirt, throw it on a mug, and fool your friends! Or most likely strangers! Because your friends probably already know your musical preferences!

-

Them: Oh, you’re a Joy Division fan?

-

You: No! I just love cycling and data!

-
-
-

Alright friends

-

First things first, open up RStudio and start a brand new R Markdown file. We’re going to use quite a few packages, most of which have been introduced in our other blog posts (link here). Here’s what we’ll need:

-
knitr::opts_chunk$set(echo = TRUE)
-
-library(tidyverse)
-
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.0 ──
-
## ✓ ggplot2 3.3.3     ✓ purrr   0.3.4
-## ✓ tibble  3.1.2     ✓ dplyr   1.0.6
-## ✓ tidyr   1.1.2     ✓ stringr 1.4.0
-## ✓ readr   1.4.0     ✓ forcats 0.5.0
-
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
-## x dplyr::filter() masks stats::filter()
-## x dplyr::lag()    masks stats::lag()
-
library(purrr)
-library(repurrrsive)
-library(here)
-
## here() starts at /Users/dfainstein/Desktop/R/finalproject_653
-
library(janitor)
-
## 
-## Attaching package: 'janitor'
-
## The following objects are masked from 'package:stats':
-## 
-##     chisq.test, fisher.test
-
library(lubridate)
-
## 
-## Attaching package: 'lubridate'
-
## The following objects are masked from 'package:base':
-## 
-##     date, intersect, setdiff, union
-
library(rStrava)
-library(plyr)
-
## ------------------------------------------------------------------------------
-
## You have loaded plyr after dplyr - this is likely to cause problems.
-## If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
-## library(plyr); library(dplyr)
-
## ------------------------------------------------------------------------------
-
## 
-## Attaching package: 'plyr'
-
## The following object is masked from 'package:here':
-## 
-##     here
-
## The following objects are masked from 'package:dplyr':
-## 
-##     arrange, count, desc, failwith, id, mutate, rename, summarise,
-##     summarize
-
## The following object is masked from 'package:purrr':
-## 
-##     compact
-

We’re going to do a bit of jumping ahead, by assuming you have already loaded in your Strava data and created a tidy dataframe with it. We’ll further modify and tidy, but if you aren’t quite to this point see this previous post which will walk you through loading and cleaning: (link here).

-

This is how your data frame should look assuming you followed the directions in the previous post:

-
# rmarkdown::paged_table(tidyfunc)
-
-
-

Step 1

-

We’ll start by beginning to pare down the data frame. We want to select the activities we do the most, so we don’t end up with strange incomplete lines. We can use the function created in [earlier post] to do this:

-
-
-

Step 2A

-

In order to create lines that mimic the “ridge” effect, we’ll also need to split our data frames, by activity type and dates. The peaks and valleys of our ridgeline plot will reflect the high and low elevation points reached during an individual activity, while the length of the line will be created by collapsing activity across date spans. Keep in mind this will require a moderate to large dataset with a lot of points to manipulate. If that’s not the case, we can simulate the data, which kind of makes you a liar. But I’ll show you how to do it anyway. [decide if this step is something you want to include and if this method works for creating the plot - ask DA]

-

If you have a large enough data set [how many points should I be aiming for? Idk!] skip ahead to step 2B.

-
# here I'll need a small data set
-# Maybe one option is to way pare down current data set to use as an example
-# If you do that, don't include data chunk
-
-# Then will walk through creation of a function to simulate additional data 
-
-
-

Step 2B

-

In our example data frame, we’ll split into the following activity types:

-
# need function for picking out activities
-# ex <-
-# tidyfunc %>% 
-#   filter(type == "Ride") %>% 
-#   select(distance, elapsed_time, elev_high, elev_low, date)
-

Next, we’ll split up our date column into 3 separate columns: year, month, and day. This will allow us to

-
-
-

Step 3

-
- - - - -
- - - - - - - - - - - - - - - diff --git a/content/post/2021-06-08-oh-snap-it-is-bonus-content/index.html b/content/post/2021-06-08-oh-snap-it-is-bonus-content/index.html deleted file mode 100644 index 18867ca..0000000 --- a/content/post/2021-06-08-oh-snap-it-is-bonus-content/index.html +++ /dev/null @@ -1,269 +0,0 @@ - - - - - - - - - - - - - - - -OH SNAP IT IS BONUS CONTENT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - -
library(ggplot2)
-library(dplyr)
-
## 
-## Attaching package: 'dplyr'
-
## The following objects are masked from 'package:stats':
-## 
-##     filter, lag
-
## The following objects are masked from 'package:base':
-## 
-##     intersect, setdiff, setequal, union
-
all_states <- map_data("state")  
-p <- ggplot()
-p <- p + geom_polygon( data=all_states, aes(x=long, y=lat, group = group),colour="white", fill="grey30" )
-
-
-ny <- filter(all_states, region == "new york")
-wa <- filter(all_states, region == "washington")
-id <- filter(all_states, region == "idaho")
-mt <- filter(all_states, region == "montana")
-nd <- filter(all_states, region == "north dakota")
-mi <- filter(all_states, region == "michigan")
-me <- filter(all_states, region == "maine")
-vt <- filter(all_states, region == "vermont")
-mn <- filter(all_states, region == "minnesota")
-wi <- filter(all_states, region == "wisconsin")
-nh <- filter(all_states, region == "new hampshire")
-
-
-
-
-
-p + geom_polygon(data = ny, aes(x=long, y=lat, group = group),fill="yellow") +
-  geom_polygon(data = wa, aes(x=long, y=lat, group = group),fill="yellow")+
-  geom_polygon(data = id, aes(x=long, y=lat, group = group),fill="yellow")+
-  geom_polygon(data = mt, aes(x=long, y=lat, group = group),fill="yellow")+
-  geom_polygon(data = nd, aes(x=long, y=lat, group = group),fill="yellow")+
-  geom_polygon(data = mi, aes(x=long, y=lat, group = group),fill="yellow")+
-  geom_polygon(data = vt, aes(x=long, y=lat, group = group),fill="yellow")+
-  geom_polygon(data = mn, aes(x=long, y=lat, group = group),fill="yellow")+
-  geom_polygon(data = wi, aes(x=long, y=lat, group = group),fill="yellow")+
-  geom_polygon(data = me, aes(x=long, y=lat, group = group),fill="yellow")+
-  geom_polygon(data = nh, aes(x=long, y=lat, group = group),fill="yellow") + 
-  labs(title = "Top 10 US States",
-       subtitle = "This is a map of the top 10 states in the United States.",
-       caption = "Actually it's the top 11 but that sounded dorky. Also don't tell Alaska about this.") + 
-  theme(panel.background = element_rect(color = "black", fill = "lightblue"))
-

- - - - -
- - - - - - - - - - - - - - - diff --git a/content/post/2021-06-08-tidying-and-wrangling-strava-data/index.Rmarkdown b/content/post/2021-06-08-tidying-and-wrangling-strava-data/index.Rmarkdown index 0a43bbb..a7d3daf 100644 --- a/content/post/2021-06-08-tidying-and-wrangling-strava-data/index.Rmarkdown +++ b/content/post/2021-06-08-tidying-and-wrangling-strava-data/index.Rmarkdown @@ -35,7 +35,7 @@ is how to effectively take control of their own data to make novel and interesting visualizations or depictions of one's hard work. In some senses, Strava makes this easy by packing your data for you with options on how you wish to view your achievements. For the DIY'er, the story is a little more -complicated. As we've outlined above with the reading in of your personal Strava +complicated. As we've outlined [previously](/2021/06/01/importing-strava-data/) with the reading in of your personal Strava data, there is a consistent theme of following key steps to have our data ready for your most creative projects. @@ -45,12 +45,20 @@ yards as the unit of measurement. This is in contrast to the remainder of activities, which seem to default to either the metric or imperial units defined when you start your account. In recognizing that other activities (e.g., sprinting) may be recorded in inappropriate units (e.g., miles for sprinting, -when feet is preferable), the following function is flexible to incorporate +when feet or meters is preferable), the following function is flexible to incorporate other conversions that you deem appropriate: ```{r conversion_function, echo=TRUE} yardstometers <- function(yards, swimming) { ifelse(swimming, yards * 1.09361, yards) } + +convert_to <- function(distance, + to_convert, + conversion = function(x) x * 1.09361) { + ifelse(to_convert, conversion(distance), distance) +} +convert_to(c(100, 30, 20), c(TRUE, FALSE, TRUE)) +convert_to(c(100, 30, 20), c(TRUE, FALSE, TRUE), function(x) x*100) ``` @@ -74,7 +82,7 @@ proportions_activity <- function(activities, threshold = 0.02) { ``` The following code chunk takes data from the prior API calls and tidy's a -dataframe for us using the two abovementioned functions. The custom functions +dataframe for us using the two above mentioned functions. The custom functions are combined with pre-existing functions from the Tidyverse to whittle down the incoming data to it's most essential features and also excludes activities that you don't do very often (e.g., that one time you went stand up paddle boarding @@ -132,4 +140,4 @@ tidyfunc %>% ``` -Hopefully what you noticed in the code above is that I purposefully selected 6 columns for demonstration purposes. This was 6 of 49 columns, and it's really not up to us what will be useful to you! Some columns may be really useful for you for the types of activities that you do (e.g., you'll really want to know distance for running and cycling; you might care less about distance for strength workouts). Also, the `reactable()` function is a really nice way to quickly and efficiently build a clean, searcheable table. Buyer beware - once you go `reactable()` you might never go back to `kable()`! +Hopefully what you noticed in the code above is that I purposefully selected 6 columns for demonstration purposes. This was 6 of 49 columns, and it's really not up to us what will be useful to you! Some columns may be really useful for you for the types of activities that you do (e.g., you'll really want to know distance for running and cycling; you might care less about distance for strength workouts). Also, the `reactable()` function is a really nice way to quickly and efficiently build a clean, search-able table. Buyer beware - once you go `reactable()` you might never go back to `kable()`! diff --git a/content/post/2021-06-08-tidying-and-wrangling-strava-data/index.markdown b/content/post/2021-06-08-tidying-and-wrangling-strava-data/index.markdown index 0a99c2a..e8939bd 100644 --- a/content/post/2021-06-08-tidying-and-wrangling-strava-data/index.markdown +++ b/content/post/2021-06-08-tidying-and-wrangling-strava-data/index.markdown @@ -8,10 +8,15 @@ tags: [] --- + + + + + Strava (http://labs.strava.com) is a data rich platform to collect, store, and @@ -20,7 +25,7 @@ is how to effectively take control of their own data to make novel and interesting visualizations or depictions of one’s hard work. In some senses, Strava makes this easy by packing your data for you with options on how you wish to view your achievements. For the DIY’er, the story is a little more -complicated. As we’ve outlined above with the reading in of your personal Strava +complicated. As we’ve outlined [previously](/2021/06/01/importing-strava-data/) with the reading in of your personal Strava data, there is a consistent theme of following key steps to have our data ready for your most creative projects. @@ -30,15 +35,30 @@ yards as the unit of measurement. This is in contrast to the remainder of activities, which seem to default to either the metric or imperial units defined when you start your account. In recognizing that other activities (e.g., sprinting) may be recorded in inappropriate units (e.g., miles for sprinting, -when feet is preferable), the following function is flexible to incorporate +when feet or meters is preferable), the following function is flexible to incorporate other conversions that you deem appropriate: ``` r yardstometers <- function(yards, swimming) { ifelse(swimming, yards * 1.09361, yards) } + +convert_to <- function(distance, + to_convert, + conversion = function(x) x * 1.09361) { + ifelse(to_convert, conversion(distance), distance) +} +convert_to(c(100, 30, 20), c(TRUE, FALSE, TRUE)) +``` + + ## [1] 109.3610 30.0000 21.8722 + +``` r +convert_to(c(100, 30, 20), c(TRUE, FALSE, TRUE), function(x) x*100) ``` + ## [1] 10000 30 2000 + We also want to sort out which activities occurred frequently enough that they would be useful to display visually. In our view, having 98% of your activities comprise three different types (e.g., hiking, running, and biking), and 2% of @@ -59,7 +79,7 @@ proportions_activity <- function(activities, threshold = 0.02) { ``` The following code chunk takes data from the prior API calls and tidy’s a -dataframe for us using the two abovementioned functions. The custom functions +dataframe for us using the two above mentioned functions. The custom functions are combined with pre-existing functions from the Tidyverse to whittle down the incoming data to it’s most essential features and also excludes activities that you don’t do very often (e.g., that one time you went stand up paddle boarding @@ -94,7 +114,7 @@ see how well it matches what you have in front of you. *Note*: it is perfectly acceptable to have rows or columns that you don’t foresee using. Our view is to leave you with too much data that you can opt to select from, as opposed to too little data leaving you wishing you had another data point on your cycling ridge -plots! +plots\! ``` r tidyfunc %>% @@ -112,6 +132,6 @@ tidyfunc %>% ```
- + -Hopefully what you noticed in the code above is that I purposefully selected 6 columns for demonstration purposes. This was 6 of 49 columns, and it’s really not up to us what will be useful to you! Some columns may be really useful for you for the types of activities that you do (e.g., you’ll really want to know distance for running and cycling; you might care less about distance for strength workouts). Also, the `reactable()` function is a really nice way to quickly and efficiently build a clean, searcheable table. Buyer beware - once you go `reactable()` you might never go back to `kable()`! +Hopefully what you noticed in the code above is that I purposefully selected 6 columns for demonstration purposes. This was 6 of 49 columns, and it’s really not up to us what will be useful to you\! Some columns may be really useful for you for the types of activities that you do (e.g., you’ll really want to know distance for running and cycling; you might care less about distance for strength workouts). Also, the `reactable()` function is a really nice way to quickly and efficiently build a clean, search-able table. Buyer beware - once you go `reactable()` you might never go back to `kable()`\! diff --git a/content/post/2021-06-08-tidying-and-wrangling-strava-data/index_files/react/react-dom.min.js b/content/post/2021-06-08-tidying-and-wrangling-strava-data/index_files/react/react-dom.min.js index 8e1a6dc..25fd056 100644 --- a/content/post/2021-06-08-tidying-and-wrangling-strava-data/index_files/react/react-dom.min.js +++ b/content/post/2021-06-08-tidying-and-wrangling-strava-data/index_files/react/react-dom.min.js @@ -1,4 +1,4 @@ -/** @license React v17.0.0 +/** @license React v16.12.0 * react-dom.production.min.js * * Copyright (c) Facebook, Inc. and its affiliates. @@ -6,240 +6,237 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -(function(){/* +/* Modernizr 3.0.0pre (Custom Build) | MIT */ -'use strict';(function(M,ha){"object"===typeof exports&&"undefined"!==typeof module?ha(exports,require("react")):"function"===typeof define&&define.amd?define(["exports","react"],ha):(M=M||self,ha(M.ReactDOM={},M.React))})(this,function(M,ha){function m(a){for(var b="https://reactjs.org/docs/error-decoder.html?invariant="+a,c=1;cb}return!1}function Q(a,b,c,d,e,f,g){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=f;this.removeEmptyString=g}function Ed(a,b,c,d){var e=I.hasOwnProperty(b)?I[b]:null;var f=null!==e?0===e.type:d?!1:!(2h||e[g]!==f[h])return"\n"+e[g].replace(" at new "," at ");while(1<=g&&0<=h)}break}}}finally{Gd=!1,Error.prepareStackTrace=c}return(a=a?a.displayName||a.name:"")?Kb(a):""}function oi(a){switch(a.tag){case 5:return Kb(a.type);case 16:return Kb("Lazy");case 13:return Kb("Suspense"); -case 19:return Kb("SuspenseList");case 0:case 2:case 15:return a=Bc(a.type,!1),a;case 11:return a=Bc(a.type.render,!1),a;case 22:return a=Bc(a.type._render,!1),a;case 1:return a=Bc(a.type,!0),a;default:return""}}function hb(a){if(null==a)return null;if("function"===typeof a)return a.displayName||a.name||null;if("string"===typeof a)return a;switch(a){case wa:return"Fragment";case Ua:return"Portal";case Lb:return"Profiler";case Hd:return"StrictMode";case Mb:return"Suspense";case Cc:return"SuspenseList"}if("object"=== -typeof a)switch(a.$$typeof){case Id:return(a.displayName||"Context")+".Consumer";case Jd:return(a._context.displayName||"Context")+".Provider";case Dc:var b=a.render;b=b.displayName||b.name||"";return a.displayName||(""!==b?"ForwardRef("+b+")":"ForwardRef");case Ec:return hb(a.type);case Kd:return hb(a._render);case Ld:b=a._payload;a=a._init;try{return hb(a(b))}catch(c){}}return null}function xa(a){switch(typeof a){case "boolean":case "number":case "object":case "string":case "undefined":return a; -default:return""}}function Df(a){var b=a.type;return(a=a.nodeName)&&"input"===a.toLowerCase()&&("checkbox"===b||"radio"===b)}function pi(a){var b=Df(a)?"checked":"value",c=Object.getOwnPropertyDescriptor(a.constructor.prototype,b),d=""+a[b];if(!a.hasOwnProperty(b)&&"undefined"!==typeof c&&"function"===typeof c.get&&"function"===typeof c.set){var e=c.get,f=c.set;Object.defineProperty(a,b,{configurable:!0,get:function(){return e.call(this)},set:function(a){d=""+a;f.call(this,a)}});Object.defineProperty(a, -b,{enumerable:c.enumerable});return{getValue:function(){return d},setValue:function(a){d=""+a},stopTracking:function(){a._valueTracker=null;delete a[b]}}}}function Fc(a){a._valueTracker||(a._valueTracker=pi(a))}function Ef(a){if(!a)return!1;var b=a._valueTracker;if(!b)return!0;var c=b.getValue();var d="";a&&(d=Df(a)?a.checked?"true":"false":a.value);a=d;return a!==c?(b.setValue(a),!0):!1}function Gc(a){a=a||("undefined"!==typeof document?document:void 0);if("undefined"===typeof a)return null;try{return a.activeElement|| -a.body}catch(b){return a.body}}function Md(a,b){var c=b.checked;return B({},b,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=c?c:a._wrapperState.initialChecked})}function Ff(a,b){var c=null==b.defaultValue?"":b.defaultValue,d=null!=b.checked?b.checked:b.defaultChecked;c=xa(null!=b.value?b.value:c);a._wrapperState={initialChecked:d,initialValue:c,controlled:"checkbox"===b.type||"radio"===b.type?null!=b.checked:null!=b.value}}function Gf(a,b){b=b.checked;null!=b&&Ed(a,"checked", -b,!1)}function Nd(a,b){Gf(a,b);var c=xa(b.value),d=b.type;if(null!=c)if("number"===d){if(0===c&&""===a.value||a.value!=c)a.value=""+c}else a.value!==""+c&&(a.value=""+c);else if("submit"===d||"reset"===d){a.removeAttribute("value");return}b.hasOwnProperty("value")?Od(a,b.type,c):b.hasOwnProperty("defaultValue")&&Od(a,b.type,xa(b.defaultValue));null==b.checked&&null!=b.defaultChecked&&(a.defaultChecked=!!b.defaultChecked)}function Hf(a,b,c){if(b.hasOwnProperty("value")||b.hasOwnProperty("defaultValue")){var d= -b.type;if(!("submit"!==d&&"reset"!==d||void 0!==b.value&&null!==b.value))return;b=""+a._wrapperState.initialValue;c||b===a.value||(a.value=b);a.defaultValue=b}c=a.name;""!==c&&(a.name="");a.defaultChecked=!!a._wrapperState.initialChecked;""!==c&&(a.name=c)}function Od(a,b,c){if("number"!==b||Gc(a.ownerDocument)!==a)null==c?a.defaultValue=""+a._wrapperState.initialValue:a.defaultValue!==""+c&&(a.defaultValue=""+c)}function qi(a){var b="";ha.Children.forEach(a,function(a){null!=a&&(b+=a)});return b} -function Pd(a,b){a=B({children:void 0},b);if(b=qi(b.children))a.children=b;return a}function ib(a,b,c,d){a=a.options;if(b){b={};for(var e=0;e=c.length))throw Error(m(93));c=c[0]}b=c}null==b&&(b="");c=b}a._wrapperState={initialValue:xa(c)}}function Jf(a,b){var c=xa(b.value),d=xa(b.defaultValue);null!=c&&(c=""+c,c!==a.value&&(a.value=c),null==b.defaultValue&&a.defaultValue!== -c&&(a.defaultValue=c));null!=d&&(a.defaultValue=""+d)}function Kf(a,b){b=a.textContent;b===a._wrapperState.initialValue&&""!==b&&null!==b&&(a.value=b)}function Lf(a){switch(a){case "svg":return"http://www.w3.org/2000/svg";case "math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function Rd(a,b){return null==a||"http://www.w3.org/1999/xhtml"===a?Lf(b):"http://www.w3.org/2000/svg"===a&&"foreignObject"===b?"http://www.w3.org/1999/xhtml":a}function Mf(a,b,c){return null== -b||"boolean"===typeof b||""===b?"":c||"number"!==typeof b||0===b||Nb.hasOwnProperty(a)&&Nb[a]?(""+b).trim():b+"px"}function Nf(a,b){a=a.style;for(var c in b)if(b.hasOwnProperty(c)){var d=0===c.indexOf("--"),e=Mf(c,b[c],d);"float"===c&&(c="cssFloat");d?a.setProperty(c,e):a[c]=e}}function Sd(a,b){if(b){if(ri[a]&&(null!=b.children||null!=b.dangerouslySetInnerHTML))throw Error(m(137,a));if(null!=b.dangerouslySetInnerHTML){if(null!=b.children)throw Error(m(60));if(!("object"===typeof b.dangerouslySetInnerHTML&& -"__html"in b.dangerouslySetInnerHTML))throw Error(m(61));}if(null!=b.style&&"object"!==typeof b.style)throw Error(m(62));}}function Td(a,b){if(-1===a.indexOf("-"))return"string"===typeof b.is;switch(a){case "annotation-xml":case "color-profile":case "font-face":case "font-face-src":case "font-face-uri":case "font-face-format":case "font-face-name":case "missing-glyph":return!1;default:return!0}}function Ud(a){a=a.target||a.srcElement||window;a.correspondingUseElement&&(a=a.correspondingUseElement); -return 3===a.nodeType?a.parentNode:a}function Of(a){if(a=Ob(a)){if("function"!==typeof Vd)throw Error(m(280));var b=a.stateNode;b&&(b=Hc(b),Vd(a.stateNode,a.type,b))}}function Pf(a){jb?kb?kb.push(a):kb=[a]:jb=a}function Qf(){if(jb){var a=jb,b=kb;kb=jb=null;Of(a);if(b)for(a=0;ad?0:1<=b)return{node:c,offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=tg(c)}}function vg(a,b){return a&&b?a===b?!0:a&&3===a.nodeType?!1:b&&3===b.nodeType?vg(a,b.parentNode):"contains"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1}function wg(){for(var a=window,b=Gc();b instanceof a.HTMLIFrameElement;){try{var c="string"===typeof b.contentWindow.location.href}catch(d){c=!1}if(c)a=b.contentWindow; -else break;b=Gc(a.document)}return b}function me(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&("input"===b&&("text"===a.type||"search"===a.type||"tel"===a.type||"url"===a.type||"password"===a.type)||"textarea"===b||"true"===a.contentEditable)}function xg(a,b,c){var d=c.window===c?c.document:9===c.nodeType?c:c.ownerDocument;ne||null==qb||qb!==Gc(d)||(d=qb,"selectionStart"in d&&me(d)?d={start:d.selectionStart,end:d.selectionEnd}:(d=(d.ownerDocument&&d.ownerDocument.defaultView||window).getSelection(), -d={anchorNode:d.anchorNode,anchorOffset:d.anchorOffset,focusNode:d.focusNode,focusOffset:d.focusOffset}),$b&&Zb($b,d)||($b=d,d=Tc(oe,"onSelect"),0ub||(a.current=ue[ub],ue[ub]=null,ub--)}function A(a,b,c){ub++;ue[ub]=a.current;a.current=b}function vb(a,b){var c=a.type.contextTypes;if(!c)return Ha;var d=a.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b)return d.__reactInternalMemoizedMaskedChildContext;var e={},f;for(f in c)e[f]=b[f];d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext= -b,a.__reactInternalMemoizedMaskedChildContext=e);return e}function S(a){a=a.childContextTypes;return null!==a&&void 0!==a}function Rg(a,b,c){if(D.current!==Ha)throw Error(m(168));A(D,b);A(J,c)}function Sg(a,b,c){var d=a.stateNode;a=b.childContextTypes;if("function"!==typeof d.getChildContext)return c;d=d.getChildContext();for(var e in d)if(!(e in a))throw Error(m(108,hb(b)||"Unknown",e));return B({},c,d)}function Xc(a){a=(a=a.stateNode)&&a.__reactInternalMemoizedMergedChildContext||Ha;Ya=D.current; -A(D,a);A(J,J.current);return!0}function Tg(a,b,c){var d=a.stateNode;if(!d)throw Error(m(169));c?(a=Sg(a,b,Ya),d.__reactInternalMemoizedMergedChildContext=a,t(J),t(D),A(D,a)):t(J);A(J,c)}function wb(){switch(nj()){case Yc:return 99;case Ug:return 98;case Vg:return 97;case Wg:return 96;case Xg:return 95;default:throw Error(m(332));}}function Yg(a){switch(a){case 99:return Yc;case 98:return Ug;case 97:return Vg;case 96:return Wg;case 95:return Xg;default:throw Error(m(332));}}function Za(a,b){a=Yg(a); -return oj(a,b)}function bc(a,b,c){a=Yg(a);return ve(a,b,c)}function ja(){if(null!==Zc){var a=Zc;Zc=null;we(a)}Zg()}function Zg(){if(!xe&&null!==pa){xe=!0;var a=0;try{var b=pa;Za(99,function(){for(;ap?(x=l,l=null):x=l.sibling;var C=r(e,l,h[p],k);if(null===C){null===l&&(l=x);break}a&&l&&null=== -C.alternate&&b(e,l);g=f(C,g,p);null===v?m=C:v.sibling=C;v=C;l=x}if(p===h.length)return c(e,l),m;if(null===l){for(;px?(C=p,p=null):C=p.sibling;var Da=r(e,p,q.value,k);if(null===Da){null===p&&(p=C);break}a&&p&&null===Da.alternate&&b(e,p);g=f(Da,g,x);null===v?l=Da:v.sibling=Da;v=Da;p=C}if(q.done)return c(e,p),l;if(null===p){for(;!q.done;x++,q=h.next())q=n(e,q.value,k),null!==q&&(g=f(q,g,x),null===v?l=q:v.sibling=q,v=q);return l}for(p=d(e,p);!q.done;x++,q=h.next())q=t(p,e,x,q.value,k),null!==q&&(a&&null!== -q.alternate&&p.delete(null===q.key?x:q.key),g=f(q,g,x),null===v?l=q:v.sibling=q,v=q);a&&p.forEach(function(a){return b(e,a)});return l}return function(a,d,f,h){var k="object"===typeof f&&null!==f&&f.type===wa&&null===f.key;k&&(f=f.props.children);var l="object"===typeof f&&null!==f;if(l)switch(f.$$typeof){case ec:a:{l=f.key;for(k=d;null!==k;){if(k.key===l){switch(k.tag){case 7:if(f.type===wa){c(a,k.sibling);d=e(k,f.props.children);d.return=a;a=d;break a}break;default:if(k.elementType===f.type){c(a, -k.sibling);d=e(k,f.props);d.ref=dc(a,k,f);d.return=a;a=d;break a}}c(a,k);break}else b(a,k);k=k.sibling}f.type===wa?(d=zb(f.props.children,a.mode,h,f.key),d.return=a,a=d):(h=fd(f.type,f.key,f.props,null,a.mode,h),h.ref=dc(a,d,f),h.return=a,a=h)}return g(a);case Ua:a:{for(k=f.key;null!==d;){if(d.key===k)if(4===d.tag&&d.stateNode.containerInfo===f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[]);d.return=a;a=d;break a}else{c(a,d);break}else b(a,d);d= -d.sibling}d=De(f,a.mode,h);d.return=a;a=d}return g(a)}if("string"===typeof f||"number"===typeof f)return f=""+f,null!==d&&6===d.tag?(c(a,d.sibling),d=e(d,f),d.return=a,a=d):(c(a,d),d=Ce(f,a.mode,h),d.return=a,a=d),g(a);if(gd(f))return w(a,d,f,h);if(Jb(f))return z(a,d,f,h);l&&ed(a,f);if("undefined"===typeof f&&!k)switch(a.tag){case 1:case 22:case 0:case 11:case 15:throw Error(m(152,hb(a.type)||"Component"));}return c(a,d)}}function $a(a){if(a===fc)throw Error(m(174));return a}function Ee(a,b){A(gc, -b);A(hc,a);A(ka,fc);a=b.nodeType;switch(a){case 9:case 11:b=(b=b.documentElement)?b.namespaceURI:Rd(null,"");break;default:a=8===a?b.parentNode:b,b=a.namespaceURI||null,a=a.tagName,b=Rd(b,a)}t(ka);A(ka,b)}function Ab(a){t(ka);t(hc);t(gc)}function ih(a){$a(gc.current);var b=$a(ka.current);var c=Rd(b,a.type);b!==c&&(A(hc,a),A(ka,c))}function Fe(a){hc.current===a&&(t(ka),t(hc))}function hd(a){for(var b=a;null!==b;){if(13===b.tag){var c=b.memoizedState;if(null!==c&&(c=c.dehydrated,null===c||"$?"===c.data|| -"$!"===c.data))return b}else if(19===b.tag&&void 0!==b.memoizedProps.revealOrder){if(0!==(b.flags&64))return b}else if(null!==b.child){b.child.return=b;b=b.child;continue}if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}return null}function jh(a,b){var c=Z(5,null,null,0);c.elementType="DELETED";c.type="DELETED";c.stateNode=b;c.return=a;c.flags=8;null!==a.lastEffect?(a.lastEffect.nextEffect=c,a.lastEffect=c):a.firstEffect= -a.lastEffect=c}function kh(a,b){switch(a.tag){case 5:var c=a.type;b=1!==b.nodeType||c.toLowerCase()!==b.nodeName.toLowerCase()?null:b;return null!==b?(a.stateNode=b,!0):!1;case 6:return b=""===a.pendingProps||3!==b.nodeType?null:b,null!==b?(a.stateNode=b,!0):!1;case 13:return!1;default:return!1}}function Ge(a){if(la){var b=Na;if(b){var c=b;if(!kh(a,b)){b=tb(c.nextSibling);if(!b||!kh(a,b)){a.flags=a.flags&-1025|2;la=!1;ra=a;return}jh(ra,c)}ra=a;Na=tb(b.firstChild)}else a.flags=a.flags&-1025|2,la=!1, -ra=a}}function lh(a){for(a=a.return;null!==a&&5!==a.tag&&3!==a.tag&&13!==a.tag;)a=a.return;ra=a}function id(a){if(a!==ra)return!1;if(!la)return lh(a),la=!0,!1;var b=a.type;if(5!==a.tag||"head"!==b&&"body"!==b&&!re(b,a.memoizedProps))for(b=Na;b;)jh(a,b),b=tb(b.nextSibling);lh(a);if(13===a.tag){a=a.memoizedState;a=null!==a?a.dehydrated:null;if(!a)throw Error(m(317));a:{a=a.nextSibling;for(b=0;a;){if(8===a.nodeType){var c=a.data;if("/$"===c){if(0===b){Na=tb(a.nextSibling);break a}b--}else"$"!==c&&"$!"!== -c&&"$?"!==c||b++}a=a.nextSibling}Na=null}}else Na=ra?tb(a.stateNode.nextSibling):null;return!0}function He(){Na=ra=null;la=!1}function Ie(){for(var a=0;af))throw Error(m(301));f+=1;K=N=null;b.updateQueue=null;jc.current=rj;a=c(d,e)}while(kc)}jc.current=jd;b=null!==N&&null!==N.next;ic=0;K=N=y=null;kd=!1;if(b)throw Error(m(300));return a}function ab(){var a={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};null===K?y.memoizedState=K=a:K=K.next=a;return K}function bb(){if(null===N){var a=y.alternate;a=null!==a?a.memoizedState:null}else a=N.next;var b=null===K?y.memoizedState:K.next;if(null!== -b)K=b,N=a;else{if(null===a)throw Error(m(310));N=a;a={memoizedState:N.memoizedState,baseState:N.baseState,baseQueue:N.baseQueue,queue:N.queue,next:null};null===K?y.memoizedState=K=a:K=K.next=a}return K}function ma(a,b){return"function"===typeof b?b(a):b}function lc(a,b,c){b=bb();c=b.queue;if(null===c)throw Error(m(311));c.lastRenderedReducer=a;var d=N,e=d.baseQueue,f=c.pending;if(null!==f){if(null!==e){var g=e.next;e.next=f.next;f.next=g}d.baseQueue=e=f;c.pending=null}if(null!==e){e=e.next;d=d.baseState; -var h=g=f=null,k=e;do{var l=k.lane;if((ic&l)===l)null!==h&&(h=h.next={lane:0,action:k.action,eagerReducer:k.eagerReducer,eagerState:k.eagerState,next:null}),d=k.eagerReducer===a?k.eagerState:a(d,k.action);else{var n={lane:l,action:k.action,eagerReducer:k.eagerReducer,eagerState:k.eagerState,next:null};null===h?(g=h=n,f=d):h=h.next=n;y.lanes|=l;La|=l}k=k.next}while(null!==k&&k!==e);null===h?f=d:h.next=g;X(d,b.memoizedState)||(fa=!0);b.memoizedState=d;b.baseState=f;b.baseQueue=h;c.lastRenderedState= -d}return[b.memoizedState,c.dispatch]}function mc(a,b,c){b=bb();c=b.queue;if(null===c)throw Error(m(311));c.lastRenderedReducer=a;var d=c.dispatch,e=c.pending,f=b.memoizedState;if(null!==e){c.pending=null;var g=e=e.next;do f=a(f,g.action),g=g.next;while(g!==e);X(f,b.memoizedState)||(fa=!0);b.memoizedState=f;null===b.baseQueue&&(b.baseState=f);c.lastRenderedState=f}return[f,d]}function mh(a,b,c){var d=b._getVersion;d=d(b._source);var e=b._workInProgressVersionPrimary;if(null!==e)a=e===d;else if(a=a.mutableReadLanes, -a=(ic&a)===a)b._workInProgressVersionPrimary=d,Bb.push(b);if(a)return c(b._source);Bb.push(b);throw Error(m(350));}function nh(a,b,c,d){var e=R;if(null===e)throw Error(m(349));var f=b._getVersion,g=f(b._source),h=jc.current,k=h.useState(function(){return mh(e,b,c)}),l=k[1],n=k[0];k=K;var t=a.memoizedState,r=t.refs,w=r.getSnapshot,z=t.source;t=t.subscribe;var B=y;a.memoizedState={refs:r,source:b,subscribe:d};h.useEffect(function(){r.getSnapshot=c;r.setSnapshot=l;var a=f(b._source);if(!X(g,a)){a=c(b._source); -X(n,a)||(l(a),a=Oa(B),e.mutableReadLanes|=a&e.pendingLanes);a=e.mutableReadLanes;e.entangledLanes|=a;for(var d=e.entanglements,h=a;0c?98:c,function(){a(!0)});Za(97\x3c/script>",a=a.removeChild(a.firstChild)):"string"===typeof d.is?a=g.createElement(c,{is:d.is}):(a=g.createElement(c),"select"===c&&(g=a,d.multiple? -g.multiple=!0:d.size&&(g.size=d.size))):a=g.createElementNS(a,c);a[Fa]=b;a[Wc]=d;wj(a,b,!1,!1);b.stateNode=a;g=Td(c,d);switch(c){case "dialog":z("cancel",a);z("close",a);e=d;break;case "iframe":case "object":case "embed":z("load",a);e=d;break;case "video":case "audio":for(e=0;eVe&&(b.flags|=64,f=!0,oc(d,!1),b.lanes=33554432)}else{if(!f)if(a=hd(g),null!==a){if(b.flags|=64,f=!0,c=a.updateQueue,null!==c&&(b.updateQueue=c,b.flags|=4),oc(d,!0),null===d.tail&&"hidden"===d.tailMode&& -!g.alternate&&!la)return b=b.lastEffect=d.lastEffect,null!==b&&(b.nextEffect=null),null}else 2*P()-d.renderingStartTime>Ve&&1073741824!==c&&(b.flags|=64,f=!0,oc(d,!1),b.lanes=33554432);d.isBackwards?(g.sibling=b.child,b.child=g):(c=d.last,null!==c?c.sibling=g:b.child=g,d.last=g)}return null!==d.tail?(c=d.tail,d.rendering=c,d.tail=c.sibling,d.lastEffect=b.lastEffect,d.renderingStartTime=P(),c.sibling=null,b=E.current,A(E,f?b&1|2:b&1),c):null;case 23:case 24:return ta=cb.current,t(cb),null!==a&&null!== -a.memoizedState!==(null!==b.memoizedState)&&"unstable-defer-without-hiding"!==d.mode&&(b.flags|=4),null}throw Error(m(156,b.tag));}function yj(a,b){switch(a.tag){case 1:return S(a.type)&&(t(J),t(D)),b=a.flags,b&4096?(a.flags=b&-4097|64,a):null;case 3:Ab();t(J);t(D);Ie();b=a.flags;if(0!==(b&64))throw Error(m(285));a.flags=b&-4097|64;return a;case 5:return Fe(a),null;case 13:return t(E),b=a.flags,b&4096?(a.flags=b&-4097|64,a):null;case 19:return t(E),null;case 4:return Ab(),null;case 10:return ze(a), -null;case 23:case 24:return ta=cb.current,t(cb),null;default:return null}}function We(a,b){try{var c="",d=b;do c+=oi(d),d=d.return;while(d);var e=c}catch(f){e="\nError generating stack: "+f.message+"\n"+f.stack}return{value:a,source:b,stack:e}}function Xe(a,b){try{console.error(b.value)}catch(c){setTimeout(function(){throw c;})}}function Lh(a,b,c){c=Ia(-1,c);c.tag=3;c.payload={element:null};var d=b.value;c.callback=function(){rd||(rd=!0,Ye=d);Xe(a,b)};return c}function Mh(a,b,c){c=Ia(-1,c);c.tag= -3;var d=a.type.getDerivedStateFromError;if("function"===typeof d){var e=b.value;c.payload=function(){Xe(a,b);return d(e)}}var f=a.stateNode;null!==f&&"function"===typeof f.componentDidCatch&&(c.callback=function(){"function"!==typeof d&&(null===na?na=new Set([this]):na.add(this),Xe(a,b));var c=b.stack;this.componentDidCatch(b.value,{componentStack:null!==c?c:""})});return c}function Nh(a){var b=a.ref;if(null!==b)if("function"===typeof b)try{b(null)}catch(c){Qa(a,c)}else b.current=null}function zj(a, -b){switch(b.tag){case 0:case 11:case 15:case 22:return;case 1:if(b.flags&256&&null!==a){var c=a.memoizedProps,d=a.memoizedState;a=b.stateNode;b=a.getSnapshotBeforeUpdate(b.elementType===b.type?c:ea(b.type,c),d);a.__reactInternalSnapshotBeforeUpdate=b}return;case 3:b.flags&256&&se(b.stateNode.containerInfo);return;case 5:case 6:case 4:case 17:return}throw Error(m(163));}function Aj(a,b,c,d){switch(c.tag){case 0:case 11:case 15:case 22:b=c.updateQueue;b=null!==b?b.lastEffect:null;if(null!==b){a=b=b.next; -do 3===(a.tag&3)&&(d=a.create,a.destroy=d()),a=a.next;while(a!==b)}b=c.updateQueue;b=null!==b?b.lastEffect:null;if(null!==b){a=b=b.next;do{var e=a;d=e.next;e=e.tag;0!==(e&4)&&0!==(e&1)&&(Oh(c,a),Bj(c,a));a=d}while(a!==b)}return;case 1:a=c.stateNode;c.flags&4&&(null===b?a.componentDidMount():(d=c.elementType===c.type?b.memoizedProps:ea(c.type,b.memoizedProps),a.componentDidUpdate(d,b.memoizedState,a.__reactInternalSnapshotBeforeUpdate)));b=c.updateQueue;null!==b&&ch(c,b,a);return;case 3:b=c.updateQueue; -if(null!==b){a=null;if(null!==c.child)switch(c.child.tag){case 5:a=c.child.stateNode;break;case 1:a=c.child.stateNode}ch(c,b,a)}return;case 5:a=c.stateNode;null===b&&c.flags&4&&Og(c.type,c.memoizedProps)&&a.focus();return;case 6:return;case 4:return;case 12:return;case 13:null===c.memoizedState&&(c=c.alternate,null!==c&&(c=c.memoizedState,null!==c&&(c=c.dehydrated,null!==c&&ag(c))));return;case 19:case 17:case 20:case 21:case 23:case 24:return}throw Error(m(163));}function Ph(a,b){for(var c=a;;){if(5=== -c.tag){var d=c.stateNode;if(b)d=d.style,"function"===typeof d.setProperty?d.setProperty("display","none","important"):d.display="none";else{d=c.stateNode;var e=c.memoizedProps.style;e=void 0!==e&&null!==e&&e.hasOwnProperty("display")?e.display:null;d.style.display=Mf("display",e)}}else if(6===c.tag)c.stateNode.nodeValue=b?"":c.memoizedProps;else if((23!==c.tag&&24!==c.tag||null===c.memoizedState||c===a)&&null!==c.child){c.child.return=c;c=c.child;continue}if(c===a)break;for(;null===c.sibling;){if(null=== -c.return||c.return===a)return;c=c.return}c.sibling.return=c.return;c=c.sibling}}function Qh(a,b,c){if(db&&"function"===typeof db.onCommitFiberUnmount)try{db.onCommitFiberUnmount(Ze,b)}catch(f){}switch(b.tag){case 0:case 11:case 14:case 15:case 22:a=b.updateQueue;if(null!==a&&(a=a.lastEffect,null!==a)){c=a=a.next;do{var d=c,e=d.destroy;d=d.tag;if(void 0!==e)if(0!==(d&4))Oh(b,c);else{d=b;try{e()}catch(f){Qa(d,f)}}c=c.next}while(c!==a)}break;case 1:Nh(b);a=b.stateNode;if("function"===typeof a.componentWillUnmount)try{a.props= -b.memoizedProps,a.state=b.memoizedState,a.componentWillUnmount()}catch(f){Qa(b,f)}break;case 5:Nh(b);break;case 4:Rh(a,b)}}function Sh(a){a.alternate=null;a.child=null;a.dependencies=null;a.firstEffect=null;a.lastEffect=null;a.memoizedProps=null;a.memoizedState=null;a.pendingProps=null;a.return=null;a.updateQueue=null}function Th(a){return 5===a.tag||3===a.tag||4===a.tag}function Uh(a){a:{for(var b=a.return;null!==b;){if(Th(b))break a;b=b.return}throw Error(m(160));}var c=b;b=c.stateNode;switch(c.tag){case 5:var d= -!1;break;case 3:b=b.containerInfo;d=!0;break;case 4:b=b.containerInfo;d=!0;break;default:throw Error(m(161));}c.flags&16&&(qc(b,""),c.flags&=-17);a:b:for(c=a;;){for(;null===c.sibling;){if(null===c.return||Th(c.return)){c=null;break a}c=c.return}c.sibling.return=c.return;for(c=c.sibling;5!==c.tag&&6!==c.tag&&18!==c.tag;){if(c.flags&2)continue b;if(null===c.child||4===c.tag)continue b;else c.child.return=c,c=c.child}if(!(c.flags&2)){c=c.stateNode;break a}}d?$e(a,c,b):af(a,c,b)}function $e(a,b,c){var d= -a.tag,e=5===d||6===d;if(e)a=e?a.stateNode:a.stateNode.instance,b?8===c.nodeType?c.parentNode.insertBefore(a,b):c.insertBefore(a,b):(8===c.nodeType?(b=c.parentNode,b.insertBefore(a,c)):(b=c,b.appendChild(a)),c=c._reactRootContainer,null!==c&&void 0!==c||null!==b.onclick||(b.onclick=Vc));else if(4!==d&&(a=a.child,null!==a))for($e(a,b,c),a=a.sibling;null!==a;)$e(a,b,c),a=a.sibling}function af(a,b,c){var d=a.tag,e=5===d||6===d;if(e)a=e?a.stateNode:a.stateNode.instance,b?c.insertBefore(a,b):c.appendChild(a); -else if(4!==d&&(a=a.child,null!==a))for(af(a,b,c),a=a.sibling;null!==a;)af(a,b,c),a=a.sibling}function Rh(a,b,c){c=b;for(var d=!1,e,f;;){if(!d){e=c.return;a:for(;;){if(null===e)throw Error(m(160));f=e.stateNode;switch(e.tag){case 5:e=f;f=!1;break a;case 3:e=f.containerInfo;f=!0;break a;case 4:e=f.containerInfo;f=!0;break a}e=e.return}d=!0}if(5===c.tag||6===c.tag){a:for(var g=a,h=c,k=h;;)if(Qh(g,k),null!==k.child&&4!==k.tag)k.child.return=k,k=k.child;else{if(k===h)break a;for(;null===k.sibling;){if(null=== -k.return||k.return===h)break a;k=k.return}k.sibling.return=k.return;k=k.sibling}f?(g=e,h=c.stateNode,8===g.nodeType?g.parentNode.removeChild(h):g.removeChild(h)):e.removeChild(c.stateNode)}else if(4===c.tag){if(null!==c.child){e=c.stateNode.containerInfo;f=!0;c.child.return=c;c=c.child;continue}}else if(Qh(a,c),null!==c.child){c.child.return=c;c=c.child;continue}if(c===b)break;for(;null===c.sibling;){if(null===c.return||c.return===b)return;c=c.return;4===c.tag&&(d=!1)}c.sibling.return=c.return;c= -c.sibling}}function bf(a,b){switch(b.tag){case 0:case 11:case 14:case 15:case 22:var c=b.updateQueue;c=null!==c?c.lastEffect:null;if(null!==c){var d=c=c.next;do 3===(d.tag&3)&&(a=d.destroy,d.destroy=void 0,void 0!==a&&a()),d=d.next;while(d!==c)}return;case 1:return;case 5:c=b.stateNode;if(null!=c){d=b.memoizedProps;var e=null!==a?a.memoizedProps:d;a=b.type;var f=b.updateQueue;b.updateQueue=null;if(null!==f){c[Wc]=d;"input"===a&&"radio"===d.type&&null!=d.name&&Gf(c,d);Td(a,e);b=Td(a,d);for(e=0;ee&&(e=g);c&=~f}c=e;c=P()-c;c=(120>c?120:480>c?480:1080>c?1080:1920>c?1920:3E3>c?3E3:4320>c?4320:1960*Hj(c/1960))-c;if(10 component higher in the tree to provide a loading indicator or placeholder to display.")}5!== -L&&(L=2);k=We(k,h);r=g;do{switch(r.tag){case 3:f=k;r.flags|=4096;b&=-b;r.lanes|=b;var B=Lh(r,f,b);bh(r,B);break a;case 1:f=k;var A=r.type,D=r.stateNode;if(0===(r.flags&64)&&("function"===typeof A.getDerivedStateFromError||null!==D&&"function"===typeof D.componentDidCatch&&(null===na||!na.has(D)))){r.flags|=4096;b&=-b;r.lanes|=b;var F=Mh(r,f,b);bh(r,F);break a}}r=r.return}while(null!==r)}bi(c)}catch(qa){b=qa;G===c&&null!==c&&(G=c=c.return);continue}break}while(1)}function Xh(){var a=vd.current;vd.current= -jd;return null===a?jd:a}function sc(a,b){var c=n;n|=16;var d=Xh();R===a&&O===b||Gb(a,b);do try{Mj();break}catch(e){Yh(a,e)}while(1);ye();n=c;vd.current=d;if(null!==G)throw Error(m(261));R=null;O=0;return L}function Mj(){for(;null!==G;)ci(G)}function Gj(){for(;null!==G&&!Nj();)ci(G)}function ci(a){var b=Oj(a.alternate,a,ta);a.memoizedProps=a.pendingProps;null===b?bi(a):G=b;jf.current=null}function bi(a){var b=a;do{var c=b.alternate;a=b.return;if(0===(b.flags&2048)){c=uj(c,b,ta);if(null!==c){G=c;return}c= -b;if(24!==c.tag&&23!==c.tag||null===c.memoizedState||0!==(ta&1073741824)||0===(c.mode&4)){for(var d=0,e=c.child;null!==e;)d|=e.lanes|e.childLanes,e=e.sibling;c.childLanes=d}null!==a&&0===(a.flags&2048)&&(null===a.firstEffect&&(a.firstEffect=b.firstEffect),null!==b.lastEffect&&(null!==a.lastEffect&&(a.lastEffect.nextEffect=b.firstEffect),a.lastEffect=b.lastEffect),1g&&(h=g,g=A,A=h),h=ug(p,A),f=ug(p,g),h&&f&&(1!==u.rangeCount||u.anchorNode!==h.node||u.anchorOffset!==h.offset||u.focusNode!==f.node||u.focusOffset!==f.offset)&&(q=q.createRange(),q.setStart(h.node,h.offset),u.removeAllRanges(),A>g?(u.addRange(q),u.extend(f.node, -f.offset)):(q.setEnd(f.node,f.offset),u.addRange(q))))));q=[];for(u=p;u=u.parentNode;)1===u.nodeType&&q.push({element:u,left:u.scrollLeft,top:u.scrollTop});"function"===typeof p.focus&&p.focus();for(p=0;pP()-cf?Gb(a,0):hf|=c);ba(a,b)}function Dj(a,b){var c=a.stateNode;null!==c&&c.delete(b);b=0;0===b&&(b=a.mode,0===(b&2)?b=1:0===(b&4)?b=99===wb()?1:2:(0===ua&&(ua=Fb),b=nb(62914560&~ua),0===b&&(b=4194304))); -c=W();a=ud(a,b);null!==a&&(Oc(a,b,c),ba(a,c))}function Tj(a,b,c,d){this.tag=a;this.key=c;this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null;this.index=0;this.ref=null;this.pendingProps=b;this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null;this.mode=d;this.flags=0;this.lastEffect=this.firstEffect=this.nextEffect=null;this.childLanes=this.lanes=0;this.alternate=null}function Pe(a){a=a.prototype;return!(!a||!a.isReactComponent)}function Uj(a){if("function"=== -typeof a)return Pe(a)?1:0;if(void 0!==a&&null!==a){a=a.$$typeof;if(a===Dc)return 11;if(a===Ec)return 14}return 2}function Ma(a,b){var c=a.alternate;null===c?(c=Z(a.tag,b,a.key,a.mode),c.elementType=a.elementType,c.type=a.type,c.stateNode=a.stateNode,c.alternate=a,a.alternate=c):(c.pendingProps=b,c.type=a.type,c.flags=0,c.nextEffect=null,c.firstEffect=null,c.lastEffect=null);c.childLanes=a.childLanes;c.lanes=a.lanes;c.child=a.child;c.memoizedProps=a.memoizedProps;c.memoizedState=a.memoizedState;c.updateQueue= -a.updateQueue;b=a.dependencies;c.dependencies=null===b?null:{lanes:b.lanes,firstContext:b.firstContext};c.sibling=a.sibling;c.index=a.index;c.ref=a.ref;return c}function fd(a,b,c,d,e,f){var g=2;d=a;if("function"===typeof a)Pe(a)&&(g=1);else if("string"===typeof a)g=5;else a:switch(a){case wa:return zb(c.children,e,f,b);case ei:g=8;e|=16;break;case Hd:g=8;e|=1;break;case Lb:return a=Z(12,c,b,e|8),a.elementType=Lb,a.type=Lb,a.lanes=f,a;case Mb:return a=Z(13,c,b,e),a.type=Mb,a.elementType=Mb,a.lanes= -f,a;case Cc:return a=Z(19,c,b,e),a.elementType=Cc,a.lanes=f,a;case of:return Te(c,e,f,b);case pf:return a=Z(24,c,b,e),a.elementType=pf,a.lanes=f,a;default:if("object"===typeof a&&null!==a)switch(a.$$typeof){case Jd:g=10;break a;case Id:g=9;break a;case Dc:g=11;break a;case Ec:g=14;break a;case Ld:g=16;d=null;break a;case Kd:g=22;break a}throw Error(m(130,null==a?a:typeof a,""));}b=Z(g,c,b,e);b.elementType=a;b.type=d;b.lanes=f;return b}function zb(a,b,c,d){a=Z(7,a,d,b);a.lanes=c;return a}function Te(a, -b,c,d){a=Z(23,a,d,b);a.elementType=of;a.lanes=c;return a}function Ce(a,b,c){a=Z(6,a,null,b);a.lanes=c;return a}function De(a,b,c){b=Z(4,null!==a.children?a.children:[],a.key,b);b.lanes=c;b.stateNode={containerInfo:a.containerInfo,pendingChildren:null,implementation:a.implementation};return b}function Vj(a,b,c){this.tag=b;this.containerInfo=a;this.finishedWork=this.pingCache=this.current=this.pendingChildren=null;this.timeoutHandle=-1;this.pendingContext=this.context=null;this.hydrate=c;this.callbackNode= -null;this.callbackPriority=0;this.eventTimes=Array(31).fill(0);this.expirationTimes=Array(31).fill(-1);this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0;this.entanglements=Array(31).fill(0);this.mutableSourceEagerHydrationData=null}function Wj(a,b,c){var d=3