-
Notifications
You must be signed in to change notification settings - Fork 4
R-tipping functionality #183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ryandeeley
wants to merge
88
commits into
main
Choose a base branch
from
r-tipping_functionality
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 76 commits
Commits
Show all changes
88 commits
Select commit
Hold shift + click to select a range
e58aeab
added first draft for RateSystem
raphael-roemer c7d44b1
Merge branch 'main' into RateSystem
oameye c71f1b4
Merge branch 'main' into RateSystem
reykboerner 525c6a1
incorporated RateSystem file
reykboerner 4e8366c
small typo fix
reykboerner 727740f
undid wrong fix
reykboerner 3acaddb
Removed RateSystem Lines
raphael-roemer cae20d6
Merge branch 'main' into RateSystem
raphael-roemer d32c1c5
Return RateSystem changes
raphael-roemer 5ee2ed9
Again delete Rate stuff
raphael-roemer 444eb72
Include Rate stuff again
raphael-roemer b8f145a
added new RateSystem Version
raphael-roemer f8230d7
Compressed RateSystemDraft2.jl script, created RateSystemTestsDraft.j…
ryandeeley 320fa82
Corrected src/CriticalTransitions.jl file.
ryandeeley 189f62b
Moved contents of dev/ file to test/ file and reset src/CriticalTrans…
ryandeeley bba545b
Collected all old and new RateSystem scripts into the test/ratesystem…
ryandeeley dcaf8aa
yep
ryandeeley 650b6fa
Added PolynomialRoots to dependencies.
ryandeeley f6d97e3
See previous.
ryandeeley 3febe82
See previous again.
ryandeeley 8e0a7b3
Exported truscottbrindley-mod-gen-det function.
ryandeeley e2f006e
Removed CoupledODEs functionality from systems/ folder.
ryandeeley 74ba1ae
Removed the system I added.
ryandeeley 5786d48
Merge branch 'main' into RateSystem
reykboerner 6e57725
Merge branch 'main' into RateSystem
oameye bdd468e
Starting a RateSystem Example
raphael-roemer 020b80f
work on example of RateSystem
raphael-roemer 894945b
work on example of RateSystem
raphael-roemer af0efc4
work on example of RateSystem
raphael-roemer 9e1f68d
work on example of RateSystem
raphael-roemer d3c9ece
added documentation in RateSystem file
raphael-roemer 12d4a01
Merge branch 'main' into RateSystem
raphael-roemer e3d2156
corrected mistake in RateSystem file
raphael-roemer 90f4228
improved documentation of test2
raphael-roemer 1703378
work on the example for RateSystem
raphael-roemer 2a5619e
added codes for the RateSystem example
raphael-roemer 260e18f
correction in MaierStein example
raphael-roemer 64d775c
small corrections in Test and RateSystemDraft
raphael-roemer cdd41f4
addition to RateSystem example
raphael-roemer cbe4abe
additions to RateSystem example
raphael-roemer 6ab08ec
additions to RateSystem example
raphael-roemer c47fdd4
correction in RateSystem example
raphael-roemer 5266412
correction in RateSystem.jl
raphael-roemer 12ab98f
added RateSystem.md to pages.jl
raphael-roemer f13cd91
Merge branch 'main' into RateSystem
reykboerner e9f90c8
moved RateSystem source code to src
reykboerner 14a97d6
applied formatter, fixed typo, disabled spell check until PR review
reykboerner f8d73ef
remove CairoMakie dep
reykboerner cf5afb2
added RateSystem test
reykboerner e7f8580
small fix
reykboerner 063b84b
applied Formatter
reykboerner 1feff1a
small edits in docs and added docstring drafts
reykboerner 4e0ab57
deleted test/ratesystem/RateSystem.jl
raphael-roemer 41128cc
deleted test/ratesystem/RateSystemDraft1.jl and test/ratesystem/RateS…
raphael-roemer 2dcffc8
deleted test/ratesystem
raphael-roemer 00f0ef2
deleted examples/RateSystem.jl
raphael-roemer 729ea5f
expanded documentaation of RateSystem
raphael-roemer 648c863
expanded documentation
raphael-roemer b147beb
added plot of parameter shift in RateSystem documentation
raphael-roemer 79715af
deleted NLPModelsIpopt from project.toml
raphael-roemer eb43377
fixed error in Project.toml
raphael-roemer 4cdbd7d
fixed quotation marks in quickstart.md
raphael-roemer db71cb3
removed the ! from apply_ramping
raphael-roemer 923849d
fixed error in documentation of RateSystem
raphael-roemer 8634b8d
resolving documentation issue with RateProtocol-plot
raphael-roemer 1c0999d
improved documentation of apply_ramping
raphael-roemer 44f11fb
correction in tes of RaateSystem
raphael-roemer 722cc74
corrected typo in RateProtocol docstring
raphael-roemer 345865f
added plot of lambda to example of RateSystem
raphael-roemer a6e8029
removed unnecessary formatting information and improved beginning of …
raphael-roemer 3c94279
correction in docstring
raphael-roemer 5f1f6bc
recovered docs/Project.toml
reykboerner ef73286
updated .toml and applied Formatter
reykboerner 7656282
Merge branch 'main' into r-tipping_functionality
ryandeeley 7b79902
added source files
reykboerner be7aca8
added moving_sinks draft
reykboerner 35b6c30
apply formatter and enable spelling again
oameye c354813
Merge branch 'main' into r-tipping_functionality
oameye 92740dc
Added draft version of the critical_rate function.
ryandeeley f84b031
Merge branch 'main' into r-tipping_functionality
oameye f65f61d
Slight corrections to align with how fixed_points works.
ryandeeley 4243f90
Made corrections to the critical_rate function in the process of gett…
ryandeeley eea5bb5
Slight corrections to align with how fixed_points works.
ryandeeley 0a68506
Merge branch 'main' into r-tipping_functionality
reykboerner 7b77fc0
fixed docs error
reykboerner a55936f
delete deprecated files
reykboerner 722a458
Merge branch 'main' into r-tipping_functionality
reykboerner 304e2ca
update moving_sinks, fix spelling and bump version
reykboerner File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,6 @@ on: | |
| types: | ||
| - opened | ||
| - reopened | ||
| - synchronize | ||
| - ready_for_review | ||
|
|
||
| jobs: | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| # Setting up a `RateSystem`: a prototypical model for R-tipping | ||
|
|
||
| Let us explore an example of how to construct a `RateSystem` from an autonomous deterministic dynamical system (i.e. a `CoupledODEs`) and a time-dependent forcing protocol called `RateProtocol`. | ||
|
|
||
| We first consider the following simple one-dimensional autonomous system with one attractor, given by the ordinary differential equation: | ||
| ```math | ||
| \begin{aligned} | ||
| \dot{x} &= (x+\lambda)^2 - 1 | ||
| \end{aligned} | ||
| ``` | ||
| The parameter ``\lambda`` shifts the location of the extrema of the drift field. | ||
| We implement this system as follows: | ||
|
|
||
| ```@example RateSystem | ||
| using CriticalTransitions | ||
| using CairoMakie | ||
| function f(u,p,t) # out-of-place | ||
| x = u[1] | ||
| λ = p[1] | ||
| dx = (x+λ)^2 - 1 | ||
| return SVector{1}(dx) | ||
| end | ||
| lambda = 0.0 | ||
| p = [lambda] | ||
| x0 = [-1.] | ||
| auto_sys = CoupledODEs(f,x0,p) | ||
| ``` | ||
|
|
||
| ## Non-autonomous case | ||
|
|
||
| Now, we want to explore a non-autonomous version of the system. | ||
| We consider a setting where in the past and in the future the system is autnonomous and in between there is a non-autonomous period ``[t_start, t_end]`` with a time-dependent parameter ramping given by the function ``\lambda(rt)``. Choosing different values of the parameter ``r`` allows us to vary the speed of the parameter ramping. | ||
|
|
||
| We start by defining the function ``\lambda(t)``: | ||
| ```@example RateSystem | ||
| function λ(p,t) | ||
| λ_max = p[1] | ||
| lambda = (λ_max/2)*(tanh(λ_max*t/2)+1) | ||
| return SVector{1}(lambda) | ||
| end | ||
| λ_max = 3. | ||
| p_lambda = [λ_max] # parameter of the function lambda | ||
| ``` | ||
|
|
||
|
|
||
| We plot the function ``λ(p_lambda,t)`` | ||
|
|
||
| ```@example RateSystem | ||
| lambda_plotvals = [λ(p_lambda, t)[1] for t in -10.0:0.1:10.0] | ||
| figλ = Figure(); axsλ = Axis(figλ[1,1],xlabel="t",ylabel=L"\lambda") | ||
| lines!(axsλ,-10.0:0.1:10.0,lambda_plotvals,linewidth=2,label=L"\lambda(p_{\lambda}, t)") | ||
| axislegend(axsλ,position=:rc,labelsize=10) | ||
| figλ | ||
| ``` | ||
|
|
||
|
|
||
| Now, we define the RateProtocol that describes how and when the function ``λ(p_lambda,t)`` is used to | ||
| make autonomous system non-autonomous: | ||
|
|
||
| ```@example RateSystem | ||
| r = 4/3-0.02 # r just below critical rate 4/3 | ||
| t_start = -Inf # start time of non-autonomous part | ||
| t_end = Inf # end time of non-autonomous part | ||
| rp = CriticalTransitions.RateProtocol(λ,p_lambda,r,t_start,t_end) | ||
| ``` | ||
|
|
||
|
|
||
|
|
||
| Now, we set up the combined system with autonomous past and future and non-autonomous ramping in between: | ||
|
|
||
| ```@example RateSystem | ||
| t0 = -10. # initial time of the system | ||
| nonauto_sys = apply_ramping(auto_sys,rp,t0) | ||
| ``` | ||
|
|
||
| We can compute trajectories of this new system in the familiar way: | ||
| ```@example RateSystem | ||
| T = 20. # final simulation time | ||
| auto_traj = trajectory(auto_sys,T,x0) | ||
| nonauto_traj = trajectory(nonauto_sys,T,x0) | ||
| ``` | ||
|
|
||
| We plot the two trajectories | ||
|
|
||
| ```@example RateSystem | ||
| fig = Figure(); axs = Axis(fig[1,1],xlabel="t",ylabel="x") | ||
| lines!(axs,t0.+auto_traj[2],auto_traj[1][:,1],linewidth=2,label=L"\text{Autonomous system}") | ||
| lines!(axs,nonauto_traj[2],nonauto_traj[1][:,1],linewidth=2,label=L"\text{Nonautonomous system}") | ||
| axislegend(axs,position=:rc,labelsize=10) | ||
| fig | ||
| ``` | ||
|
|
||
| ----- | ||
| Author: Raphael Roemer | ||
|
|
||
| Date: 30 Jun 2025 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| # we consider the ODE dxₜ/dt = f(xₜ,λ(rt)) | ||
| # here λ = λ(t) ∈ Rᵐ is a function containing all the system parameters | ||
|
|
||
| # We ask the user to define: | ||
| # 1) a ContinuousTimeDynamicalSystem that should be investigated and | ||
| # 2) a protocol for the time-dependent forcing with the struct RateProtocol | ||
|
|
||
| # Then we give back the ContinuousTimeDynamicalSystem with the parameter | ||
| # changing according to the rate protocol | ||
| """ | ||
| RateProtocol | ||
| Time-dependent forcing protocol specified by the following fields: | ||
| - `λ::Function`: forcing function of the form `λ(p, t_start; kwargs...)`` | ||
| - `p_lambda::Vector`: parameters of forcing function | ||
reykboerner marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - `r::Float64`: rate parameter | ||
| - `t_start::Float64`: start time of protocol | ||
| - `t_end::Float64`: end time of protocol | ||
| If `t_start` and `t_end` are not provided, they are set to `t_start=-Inf`, and `t_end=Inf`. | ||
| If `p_lambda` is not provided, it is set to an empty array `[]`. | ||
| The forcing protocol contains all the information that allows to take an ODE of the form | ||
| `dxₜ/dt = f(xₜ,λ)` | ||
| with `λ ∈ Rᵐ` containing all the system parameters, and make it an ODE of the form | ||
| `dxₜ/dt = f(xₜ,λ(rt))` | ||
| with `λ(t) ∈ Rᵐ`. | ||
| """ | ||
| mutable struct RateProtocol | ||
| λ::Function | ||
| p_lambda::Vector | ||
| r::Float64 | ||
| t_start::Float64 | ||
| t_end::Float64 | ||
| end | ||
reykboerner marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| # convenience functions | ||
|
|
||
| function RateProtocol(λ::Function, p_lambda::Vector, r::Float64) | ||
| RateProtocol(λ, p_lambda, r, -Inf, Inf) | ||
| end | ||
| RateProtocol(λ::Function, r::Float64)=RateProtocol(λ, [], r, -Inf, Inf) | ||
| #RateProtocol(λ::Function,p_lambda::Vector,r::Float64,t_start::Float64)=RateProtocol(λ,p_lambda,r,t_start,Inf) | ||
| #RateProtocol(λ::Function,r::Float64,t_start::Float64)=RateProtocol(λ,[],r,t_start,Inf) | ||
|
|
||
| function modified_drift( | ||
| u, | ||
| p, | ||
| t, | ||
| ds::ContinuousTimeDynamicalSystem, | ||
| λ::Function, | ||
| t_start::Float64, | ||
| t_end::Float64, | ||
| r::Float64; | ||
| kwargs..., | ||
| ) | ||
| if t_start > t_end | ||
| error("Please ensure that t_start ≤ t_end.") | ||
| end | ||
|
|
||
| p̃ = if r*t ≤ t_start | ||
| λ(p, t_start; kwargs...) | ||
| elseif t_start < r*t < t_end | ||
| λ(p, r*t; kwargs...) # the value(s) of λ(rt) | ||
| else | ||
| λ(p, t_end; kwargs...) # the value(s) of λ(rt) | ||
| end; # the value(s) of λ(rt) | ||
| return ds.integ.f(u, p̃, t) | ||
| end; | ||
reykboerner marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| """ | ||
| apply_ramping(sys::CoupledODEs, rp::RateProtocol, t0=0.0; kwargs...) | ||
| Applies a time-dependent [`RateProtocol`](@def) to a given autonomous deterministic dynamical system | ||
| `sys`, turning it into a non-autonomous dynamical system. The returned [`CoupledODEs`](@ref) | ||
| has the explicit parameter time-dependence incorporated. | ||
| The returned [`CoupledODEs`](@ref) is autonomous from `t_0` to `t_start`, | ||
| then non-autnonmous from `t_start` to `t_end` with the parameter shift given by the [`RateProtocol`](@def), | ||
| and again autonomous from `t_end` to the end of the simulation: | ||
| `t_0` autonomous `t_start` non-autonomous `t_end` autonomous `∞` | ||
| """ | ||
| function apply_ramping(auto_sys::CoupledODEs, rp::RateProtocol, t0=0.0; kwargs...) | ||
| # we wish to return a continuous time dynamical system with modified drift field | ||
|
|
||
| f(u, p, t) = modified_drift( | ||
| u, p, t, auto_sys, rp.λ, rp.t_start, rp.t_end, rp.r; kwargs... | ||
| ) | ||
| prob = remake(auto_sys.integ.sol.prob; f, p=rp.p_lambda, tspan=(t0, Inf)) | ||
| nonauto_sys = CoupledODEs(prob, auto_sys.diffeq) | ||
| return nonauto_sys | ||
| end | ||
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| """ | ||
| moving_sinks(ds::ContinuousTimeDynamicalSystem, rp::RateProtocol, box; kwargs...) | ||
|
|
||
| Calculates fixed points of a nonautonomous dynamical system at snapshots in time, giving | ||
| insight into how the equilibria change as the forcing changes over time. | ||
|
|
||
| ## Input | ||
| `ds` is a dynamical system of type `ContinuousTimeDynamicalSystem`, `rp` a `RateProtocol`, | ||
| and `box` is a vector of intervals (e.g. `[interval(0,1), interval(-1,1)]`) | ||
| that delimits the phase space volume in which to look for equilibria | ||
| (see [`fixedpoints`](@ref)). | ||
|
|
||
| ## Keyword arguments | ||
| - `times = 0:0.1:1`: time points (relative to the system time `t`) | ||
|
|
||
| ## output | ||
| Returns a triple of vectors: | ||
| 1. Fixed points found at each time point | ||
| 2. Eigenvalues associated with the fixed points | ||
| 3. Stability of the fixed points (1 - stable; 0 - unstable) | ||
|
|
||
| The term "moving sinks" refers to Wieczorek et al. (2023). | ||
| """ | ||
| function moving_sinks(ds::ContinuousTimeDynamicalSystem, rp::RateProtocol, box; | ||
| times=0:0.1:1) | ||
reykboerner marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| fp, eig, stab = [], [], [] | ||
| for t in times | ||
| rate_sys = apply_ramping(ds, rp, t) | ||
| _fp, _eig, _stab = fixedpoints(rate_sys, box) | ||
reykboerner marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| push!(fp, _fp) | ||
| push!(eig, _eig) | ||
| push!(stab, _stab) | ||
| end | ||
| return fp, eig, stab | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| using CriticalTransitions | ||
| using Test | ||
|
|
||
| @testset "RateSystem" begin | ||
| function f(u, p, t) # out-of-place | ||
| x = u[1] | ||
| λ = p[1] | ||
| dx = (x+λ)^2 - 1 | ||
| return SVector{1}(dx) | ||
| end | ||
|
|
||
| lambda = 0.0 | ||
| p = [lambda] | ||
| x0 = [-1.0] | ||
| auto_sys = CoupledODEs(f, x0, p) | ||
|
|
||
| function λ(p, t) | ||
| λ_max = p[1] | ||
| lambda = (λ_max/2)*(tanh(λ_max*t/2)+1) | ||
| return SVector{1}(lambda) | ||
| end | ||
|
|
||
| λ_max = 3.0 | ||
| p_lambda = [λ_max] # parameter of the function lambda | ||
|
|
||
| r = 4/3-0.02 # r just below critical rate | ||
| t_start = -Inf # start time of non-autonomous part | ||
| t_end = Inf # end time of non-autonomous part | ||
|
|
||
| rp = CriticalTransitions.RateProtocol(λ, p_lambda, r, t_start, t_end) | ||
|
|
||
| t0 = -10.0 # initial time of the system | ||
| nonauto_sys = apply_ramping(auto_sys, rp, t0) | ||
|
|
||
| T = 20.0 # final simulation time | ||
| auto_traj = trajectory(auto_sys, T, x0) | ||
| nonauto_traj = trajectory(nonauto_sys, T, x0) | ||
|
|
||
| @test isapprox(auto_traj[1][end, 1], -1; atol=1e-4) | ||
| @test isapprox(nonauto_traj[1][end, 1], -4; atol=1e-4) | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
|
|
||
| @testset "moving_sinks" begin | ||
| using ChaosTools | ||
| # Dynamical system | ||
| function fhn(u,p,t) | ||
| eps, b = p | ||
| x, y = u | ||
| dx = (-x^3 + x - y)/eps | ||
| dy = -b*y + x | ||
| return SA[dx, dy] | ||
| end | ||
|
|
||
| p = [1,6] | ||
| sys = CoupledODEs(fhn, [1.,1], p) | ||
|
|
||
| # Forcing | ||
| function λ(p, t) | ||
| λ_max = p[2] | ||
| lambda = (λ_max/2)*(tanh(λ_max*t/2)+1) | ||
| return SVector{2}([p[1], lambda]) | ||
| end | ||
|
|
||
| r = 0.1 | ||
| rp = CriticalTransitions.RateProtocol(λ, p, r, -10, 10) | ||
|
|
||
| # Calculate moving sinks | ||
| box = [interval(-2,2), interval(-1,1)] | ||
| fp, eig, stab = moving_sinks(sys, rp, box; times=0:0.1:1) | ||
| @test length(fp[1]) == 3 | ||
| end |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.