-
Notifications
You must be signed in to change notification settings - Fork 21
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
Mobile Coverage points calculator #824
Commits on Jun 6, 2024
-
Configuration menu - View commit details
-
Copy full SHA for c12cf58 - Browse repository at this point
Copy the full SHA c12cf58View commit details -
Configuration menu - View commit details
-
Copy full SHA for a752017 - Browse repository at this point
Copy the full SHA a752017View commit details -
Configuration menu - View commit details
-
Copy full SHA for a38119e - Browse repository at this point
Copy the full SHA a38119eView commit details -
Configuration menu - View commit details
-
Copy full SHA for c628887 - Browse repository at this point
Copy the full SHA c628887View commit details -
Configuration menu - View commit details
-
Copy full SHA for 92ac409 - Browse repository at this point
Copy the full SHA 92ac409View commit details -
moved to using decimals now that summing lists is involved, and we need to retain accuracy
Configuration menu - View commit details
-
Copy full SHA for 7c0956e - Browse repository at this point
Copy the full SHA 7c0956eView commit details -
still need to decide how the multipliers are going to be indexed. 0-indexed is easy, but it seems what to talk about a radio being "0th ranked" in a hex.
Configuration menu - View commit details
-
Copy full SHA for 172d3a8 - Browse repository at this point
Copy the full SHA 172d3a8View commit details -
Configuration menu - View commit details
-
Copy full SHA for 38e25d2 - Browse repository at this point
Copy the full SHA 38e25d2View commit details -
Configuration menu - View commit details
-
Copy full SHA for 86af16f - Browse repository at this point
Copy the full SHA 86af16fView commit details -
Configuration menu - View commit details
-
Copy full SHA for bd868f3 - Browse repository at this point
Copy the full SHA bd868f3View commit details -
Configuration menu - View commit details
-
Copy full SHA for ce66053 - Browse repository at this point
Copy the full SHA ce66053View commit details -
the speedtest multiplier is allowed to be zero. It can completely negate a radios rewards. speedtest 2
Configuration menu - View commit details
-
Copy full SHA for ac55763 - Browse repository at this point
Copy the full SHA ac55763View commit details -
Configuration menu - View commit details
-
Copy full SHA for c63cf03 - Browse repository at this point
Copy the full SHA c63cf03View commit details -
Configuration menu - View commit details
-
Copy full SHA for 901dae7 - Browse repository at this point
Copy the full SHA 901dae7View commit details -
it seems a more accurate name for where we are currently, I think
Configuration menu - View commit details
-
Copy full SHA for f9fe094 - Browse repository at this point
Copy the full SHA f9fe094View commit details -
Configuration menu - View commit details
-
Copy full SHA for 1a02c2f - Browse repository at this point
Copy the full SHA 1a02c2fView commit details -
Configuration menu - View commit details
-
Copy full SHA for 526a9d6 - Browse repository at this point
Copy the full SHA 526a9d6View commit details -
For the way we talk about Ranking of radios, it doesn't make much sense for a radio to be ranked 0th for a hex.
Configuration menu - View commit details
-
Copy full SHA for febe516 - Browse repository at this point
Copy the full SHA febe516View commit details -
Configuration menu - View commit details
-
Copy full SHA for 5a69e11 - Browse repository at this point
Copy the full SHA 5a69e11View commit details -
Removing hexes that do not meet the rank requirements is easier to think about in its own step
Configuration menu - View commit details
-
Copy full SHA for 9ed0800 - Browse repository at this point
Copy the full SHA 9ed0800View commit details -
Use more expected name for hex coverage points
the HIP says estimated coverage points, but no one thinks of them that way, because there is nothing about them that is an esimate, they are very concrete values.
Configuration menu - View commit details
-
Copy full SHA for 5f90176 - Browse repository at this point
Copy the full SHA 5f90176View commit details -
Now that we have some integration tests, we can trust what code is being used
Configuration menu - View commit details
-
Copy full SHA for 2fe76e8 - Browse repository at this point
Copy the full SHA 2fe76e8View commit details -
Make calculating coverage points a top level function
I want this crate to make the algorithm one of the most important things. Hiding it inside a structs impl block seems not a great of doing that, I think. I also don't think the rewardable radio impl block should be moved to the top to make the algorithm more front and center, in my mind it would only make RewardableRadio look more important.
Configuration menu - View commit details
-
Copy full SHA for 5f3f14a - Browse repository at this point
Copy the full SHA 5f3f14aView commit details -
Configuration menu - View commit details
-
Copy full SHA for 16dee05 - Browse repository at this point
Copy the full SHA 16dee05View commit details -
Configuration menu - View commit details
-
Copy full SHA for c5018dd - Browse repository at this point
Copy the full SHA c5018ddView commit details -
trust scores and covered hexes are linked in many ways. I'm opting to precompute multiple values then have quick access to them, rather than waiting until they're needed and computing them for every hex. Or carrying around a spot for computed data that get's filled on the first use. When the rest of the types are fleshed out, some benchmarks will be done to determine if this is a problem.
Configuration menu - View commit details
-
Copy full SHA for 18d1ca3 - Browse repository at this point
Copy the full SHA 18d1ca3View commit details -
Configuration menu - View commit details
-
Copy full SHA for 92f5c69 - Browse repository at this point
Copy the full SHA 92f5c69View commit details -
Clippy wants the method to take ownership to follow the `to_*()` convention.
Configuration menu - View commit details
-
Copy full SHA for 347551f - Browse repository at this point
Copy the full SHA 347551fView commit details -
Match HIP explicitly for latency values
The original implementation allowed the upper limit as inclusive, and it was called out in PR as not matching the HIP. #737
Configuration menu - View commit details
-
Copy full SHA for d516120 - Browse repository at this point
Copy the full SHA d516120View commit details -
Configuration menu - View commit details
-
Copy full SHA for 6eed581 - Browse repository at this point
Copy the full SHA 6eed581View commit details -
Change verified radio threshold to enum
Provides a named boolean to the status of meeting subscriber thresholds. Also provides a nice place to add new states in the case more HIPs are passed regarding subscribers thresholds.
Configuration menu - View commit details
-
Copy full SHA for c4d842a - Browse repository at this point
Copy the full SHA c4d842aView commit details -
Configuration menu - View commit details
-
Copy full SHA for 073a0ee - Browse repository at this point
Copy the full SHA 073a0eeView commit details -
Configuration menu - View commit details
-
Copy full SHA for df0b365 - Browse repository at this point
Copy the full SHA df0b365View commit details -
Add a user definable key for radios
This may be hardcoded to a type in the future, but until we know that type, it's easy to make it generic and only enforce the radio returns the same type the coverage map is expecting
Configuration menu - View commit details
-
Copy full SHA for 84b10f3 - Browse repository at this point
Copy the full SHA 84b10f3View commit details -
Configuration menu - View commit details
-
Copy full SHA for af08ee9 - Browse repository at this point
Copy the full SHA af08ee9View commit details -
helpers for mobile rewards report
I don't know if i like all the helpers in here. but I'm not sure where to put them yet.
Configuration menu - View commit details
-
Copy full SHA for 913005d - Browse repository at this point
Copy the full SHA 913005dView commit details -
Configuration menu - View commit details
-
Copy full SHA for 29b1dc6 - Browse repository at this point
Copy the full SHA 29b1dc6View commit details -
coverage map trait takes key directly
we're constructing a temporary rewardable radio to implement rewardable radio. If we make one directly, the coverage map doesn't have to care about the entire radio, just the key type.
Configuration menu - View commit details
-
Copy full SHA for 34fd895 - Browse repository at this point
Copy the full SHA 34fd895View commit details -
SubscriberThreshold -> RadioThreshold
Thresholds have already moved away from being solely about subscribers. And this makes clearer the fact that a radio being considered "valid" can have many factors, not only subscribers.
Configuration menu - View commit details
-
Copy full SHA for b3f7924 - Browse repository at this point
Copy the full SHA b3f7924View commit details -
move boosted hexes iter to the mobile-verifier
The mobile-verifier needs to be able to report on only the boosted hexes. The calculator is not concerned with that, but it can provide the necessary hooks for the mobile-verifier to create the boosted hexes report.
Configuration menu - View commit details
-
Copy full SHA for 3fdaf60 - Browse repository at this point
Copy the full SHA 3fdaf60View commit details -
Configuration menu - View commit details
-
Copy full SHA for 69568bb - Browse repository at this point
Copy the full SHA 69568bbView commit details -
do not handle cleaning values for reports
that belongs in mobile-verifier
Configuration menu - View commit details
-
Copy full SHA for 7547025 - Browse repository at this point
Copy the full SHA 7547025View commit details -
Configuration menu - View commit details
-
Copy full SHA for 6f6d06a - Browse repository at this point
Copy the full SHA 6f6d06aView commit details -
Thought I got this with a previous commit, apparently not. Also add some spacing for readability
Configuration menu - View commit details
-
Copy full SHA for 0f01422 - Browse repository at this point
Copy the full SHA 0f01422View commit details -
Configuration menu - View commit details
-
Copy full SHA for 3195958 - Browse repository at this point
Copy the full SHA 3195958View commit details -
Configuration menu - View commit details
-
Copy full SHA for 3f721e1 - Browse repository at this point
Copy the full SHA 3f721e1View commit details -
Configuration menu - View commit details
-
Copy full SHA for 38584b6 - Browse repository at this point
Copy the full SHA 38584b6View commit details -
the coverage map is going to be used before entering this crate, so we don't need to put a restriction around it. The restriction will be that we only accept types provided from that crate.
Configuration menu - View commit details
-
Copy full SHA for b9f985e - Browse repository at this point
Copy the full SHA b9f985eView commit details -
use RankedCoverage from coverage map
requires pulling in helium-crypto as a dev dependency for testing
Configuration menu - View commit details
-
Copy full SHA for a62b276 - Browse repository at this point
Copy the full SHA a62b276View commit details -
do not panic for incorrect signal levels
return a calculator error if a rewardable radio cannot be constructed.
Configuration menu - View commit details
-
Copy full SHA for 36af33e - Browse repository at this point
Copy the full SHA 36af33eView commit details -
Configuration menu - View commit details
-
Copy full SHA for 821be75 - Browse repository at this point
Copy the full SHA 821be75View commit details -
Despire data given as input, only output data used for calculation. Enforce the rules of speedtests, min of 2, max of 6, ordered newest to oldest. BoostedHexes contain the boosted value they used. Location Trust Scores contain the trust score based on boosted hexes.
Configuration menu - View commit details
-
Copy full SHA for dd613bc - Browse repository at this point
Copy the full SHA dd613bcView commit details -
Restrict construction of RewardableRadio
Make the fields private so users have to go through the constructor to get a radio, and cannot change values of fields after the fact, as it will not trigger anything to be recalculated.
Configuration menu - View commit details
-
Copy full SHA for 0b6df3d - Browse repository at this point
Copy the full SHA 0b6df3dView commit details -
Configuration menu - View commit details
-
Copy full SHA for a6ee102 - Browse repository at this point
Copy the full SHA a6ee102View commit details -
move multiplier calculation into location crate
needs to know about radio type
Configuration menu - View commit details
-
Copy full SHA for 7821a86 - Browse repository at this point
Copy the full SHA 7821a86View commit details -
bring in speedtest and location changes
use contstructors when we can, that's when calculations are done for multipliers
Configuration menu - View commit details
-
Copy full SHA for efa1c37 - Browse repository at this point
Copy the full SHA efa1c37View commit details -
Configuration menu - View commit details
-
Copy full SHA for d113dd4 - Browse repository at this point
Copy the full SHA d113dd4View commit details -
Configuration menu - View commit details
-
Copy full SHA for 47999df - Browse repository at this point
Copy the full SHA 47999dfView commit details -
Configuration menu - View commit details
-
Copy full SHA for 28a0aa0 - Browse repository at this point
Copy the full SHA 28a0aa0View commit details -
Configuration menu - View commit details
-
Copy full SHA for 51150b2 - Browse repository at this point
Copy the full SHA 51150b2View commit details -
represent boosted hex eligiblity with an enum
There is more than 1 case that can preclude a radio from eligibility, let's communicate that in a better way that a boolean.
Configuration menu - View commit details
-
Copy full SHA for fb1da40 - Browse repository at this point
Copy the full SHA fb1da40View commit details -
Configuration menu - View commit details
-
Copy full SHA for ac3a77f - Browse repository at this point
Copy the full SHA ac3a77fView commit details -
Configuration menu - View commit details
-
Copy full SHA for 19956c0 - Browse repository at this point
Copy the full SHA 19956c0View commit details -
Configuration menu - View commit details
-
Copy full SHA for 847a1fa - Browse repository at this point
Copy the full SHA 847a1faView commit details -
Configuration menu - View commit details
-
Copy full SHA for 4541393 - Browse repository at this point
Copy the full SHA 4541393View commit details -
assert against expected points in integration
allows us to remove radio_type getter from RewardableRadio
Configuration menu - View commit details
-
Copy full SHA for 8a8b3ca - Browse repository at this point
Copy the full SHA 8a8b3caView commit details -
Configuration menu - View commit details
-
Copy full SHA for 36d93b5 - Browse repository at this point
Copy the full SHA 36d93b5View commit details -
Configuration menu - View commit details
-
Copy full SHA for 1aadb87 - Browse repository at this point
Copy the full SHA 1aadb87View commit details -
Use inner line comment to describe crate
inner line comments "//!" describe what is above. outer line comments "///" describe what is below. Thank you Matty.
Configuration menu - View commit details
-
Copy full SHA for ff38db3 - Browse repository at this point
Copy the full SHA ff38db3View commit details -
We can not need to worry about constructor naming conventions by moving more decision making into the constructors themselves. `RewardableRadio::new` now only brings to the surface the fact that location trust scores need to know about coverage, and covered hexes need to know about location trust multiplier. But nothing more internally.
Configuration menu - View commit details
-
Copy full SHA for cb6b3ef - Browse repository at this point
Copy the full SHA cb6b3efView commit details -
Configuration menu - View commit details
-
Copy full SHA for a9e4846 - Browse repository at this point
Copy the full SHA a9e4846View commit details -
Configuration menu - View commit details
-
Copy full SHA for 5d7bd20 - Browse repository at this point
Copy the full SHA 5d7bd20View commit details -
Configuration menu - View commit details
-
Copy full SHA for 03dfe72 - Browse repository at this point
Copy the full SHA 03dfe72View commit details -
Configuration menu - View commit details
-
Copy full SHA for 1730802 - Browse repository at this point
Copy the full SHA 1730802View commit details -
Configuration menu - View commit details
-
Copy full SHA for d96ddab - Browse repository at this point
Copy the full SHA d96ddabView commit details -
Configuration menu - View commit details
-
Copy full SHA for f94def7 - Browse repository at this point
Copy the full SHA f94def7View commit details -
question was answered, negative
"No, if the radio covers a boosted hex, then the location trust score is calculated using the more restrictive distance_to_asserted rule." - bbalser
Configuration menu - View commit details
-
Copy full SHA for 4601b74 - Browse repository at this point
Copy the full SHA 4601b74View commit details -
Configuration menu - View commit details
-
Copy full SHA for 33e7573 - Browse repository at this point
Copy the full SHA 33e7573View commit details -
Configuration menu - View commit details
-
Copy full SHA for 6a43d7b - Browse repository at this point
Copy the full SHA 6a43d7bView commit details -
Configuration menu - View commit details
-
Copy full SHA for 7004083 - Browse repository at this point
Copy the full SHA 7004083View commit details -
You could make the argument to remove these fields, they were used in the construction of a radio, and play a critical role in determining points. I chose to keep them around because if anything happens where you have a radio and want information about values within, these fields will be crucial in helping you figure that out.
Configuration menu - View commit details
-
Copy full SHA for 963e9c3 - Browse repository at this point
Copy the full SHA 963e9c3View commit details -
remove radio information from returned coverage points
rather than consuming a radio you were forced to construct, and returning much of the same information in a different shape. You get to keep the radio you've made, and if you want to know about both, you can hold on to both.
Configuration menu - View commit details
-
Copy full SHA for 4780bf3 - Browse repository at this point
Copy the full SHA 4780bf3View commit details -
try not to compare directly against values
This tests cares about the relative value of the speedtest multiplier being applied. As long as that relationship holds, this test is fine. It doesn't want to worry about arbitrary points changing.
Configuration menu - View commit details
-
Copy full SHA for bac1804 - Browse repository at this point
Copy the full SHA bac1804View commit details -
provide a parameterized test for each type of radio
This allows us to be more specific about how much a hex contributes to each type of radio without needing to know how individual hex values stack.
Configuration menu - View commit details
-
Copy full SHA for d846d7d - Browse repository at this point
Copy the full SHA d846d7dView commit details -
Configuration menu - View commit details
-
Copy full SHA for 3336070 - Browse repository at this point
Copy the full SHA 3336070View commit details -
There's nothing that can be further enforced by having a newtype. Making the field as `_millis` communicates the same ammount of information as the newtype.
Configuration menu - View commit details
-
Copy full SHA for c4e43eb - Browse repository at this point
Copy the full SHA c4e43ebView commit details -
SpeedtestTier is Copy, as well as BytePs
We don't need to enforce passing references for Copy types, let people use them directly and the compiler can figure it out.
Configuration menu - View commit details
-
Copy full SHA for 7be97e9 - Browse repository at this point
Copy the full SHA 7be97e9View commit details -
Configuration menu - View commit details
-
Copy full SHA for 55c530c - Browse repository at this point
Copy the full SHA 55c530cView commit details -
switchup location testing angle
Rather than testing statements like "the multiplier should be an average of the scores". This module benefits more from describing the different scenarios, and showing boosted and unboosted versions in contrast with each other, I think.
Configuration menu - View commit details
-
Copy full SHA for 4684bb0 - Browse repository at this point
Copy the full SHA 4684bb0View commit details -
Configuration menu - View commit details
-
Copy full SHA for fca8c2f - Browse repository at this point
Copy the full SHA fca8c2fView commit details -
There's nothing that can be further enforced by having a newtype. Making the field as `meters_from_` communicates the same ammount of information as the newtype.
Configuration menu - View commit details
-
Copy full SHA for aada11f - Browse repository at this point
Copy the full SHA aada11fView commit details -
name base_coverage_points consistently
having bare coverage_point names laying around can be quickly confusing.
Configuration menu - View commit details
-
Copy full SHA for 479e932 - Browse repository at this point
Copy the full SHA 479e932View commit details -
Speaking of a single rank at a time simplifies the test by not needing to know how values stack on top of each other. I kept indoor/outdoor as separate tests as to not overwhelm the reader with a parameterized test that has too many variables
Configuration menu - View commit details
-
Copy full SHA for 6fa795d - Browse repository at this point
Copy the full SHA 6fa795dView commit details -
use correct radio type for test
copy/paste error from rebasing on top of coverage-map updates, yay! But now we know the tests break.
Configuration menu - View commit details
-
Copy full SHA for 3d3cd08 - Browse repository at this point
Copy the full SHA 3d3cd08View commit details -
clippy does not like overlapping ranges
I agree with the concept, so I've added the lower bounds. Personally, I still think these match statements are easier to read than the equivalent `else if` expression. So they're staying as range comparisons.
Configuration menu - View commit details
-
Copy full SHA for 389134b - Browse repository at this point
Copy the full SHA 389134bView commit details
Commits on Jun 7, 2024
-
exchange struct constructor for function
I like the idea of the API to this crate being 2 functions. In my head, that makes it clearer that any functions hanging off of exposed structs can be used for information gathering, but are ancillary to the main use of this crate.
Configuration menu - View commit details
-
Copy full SHA for df93e3d - Browse repository at this point
Copy the full SHA df93e3dView commit details -
Configuration menu - View commit details
-
Copy full SHA for 81e7e25 - Browse repository at this point
Copy the full SHA 81e7e25View commit details -
move radio_threshold earlier in argument list
This puts the information about the radio closer to each other, the grouping feels nicer, I think
Configuration menu - View commit details
-
Copy full SHA for ff65ac8 - Browse repository at this point
Copy the full SHA ff65ac8View commit details -
include all fields in coverage points
this is stepping towards having a single struct
Configuration menu - View commit details
-
Copy full SHA for 83b0a21 - Browse repository at this point
Copy the full SHA 83b0a21View commit details -
Configuration menu - View commit details
-
Copy full SHA for b35f2ae - Browse repository at this point
Copy the full SHA b35f2aeView commit details -
Configuration menu - View commit details
-
Copy full SHA for 6e8fd68 - Browse repository at this point
Copy the full SHA 6e8fd68View commit details -
remove wrapping struct for location trust scores
This means we don't need to unwrap anything, and the API is more strictly dealing with data alone. The location funtions are only public to the crate to prevent someone from attempting to put together they're own coverage points calculator. They must go through the calculate_coverage_points function.
Configuration menu - View commit details
-
Copy full SHA for 3c696c3 - Browse repository at this point
Copy the full SHA 3c696c3View commit details -
remove wrapping CoveredHexes struct
Same as location, we want to deal more directly with data, while keeping the only way to use the crate be through the top level calculate_coverage_points function.
Configuration menu - View commit details
-
Copy full SHA for 5991da7 - Browse repository at this point
Copy the full SHA 5991da7View commit details -
remove wrapping struct from speedtests
dealing more directly with data. forcing use through the top level api.
Configuration menu - View commit details
-
Copy full SHA for bfa23d2 - Browse repository at this point
Copy the full SHA bfa23d2View commit details -
Configuration menu - View commit details
-
Copy full SHA for 3da915f - Browse repository at this point
Copy the full SHA 3da915fView commit details -
move calcuating coverage points into constructor
I thought `coverage_point_calculator::calculate_coverage_points()` didn't read very well. And since we now have a single struct to care about (outside of providing arguments), it seemed to me `coverage_point_calculator::CoveragePoints::new()` read rather nicely.
Configuration menu - View commit details
-
Copy full SHA for 958b2d1 - Browse repository at this point
Copy the full SHA 958b2d1View commit details -
Removing derive Default for Speedtest
I don't think a zeroed out Speedtest is a sensible default
Configuration menu - View commit details
-
Copy full SHA for dc02abc - Browse repository at this point
Copy the full SHA dc02abcView commit details
Commits on Jun 10, 2024
-
Fix incorrect speedtests conversion
I had typed the wrong value when bringing over megabytes per second conversion. We found some values in a real database during testing that should have gotten a different speedtest tier.
Configuration menu - View commit details
-
Copy full SHA for 75e3d4b - Browse repository at this point
Copy the full SHA 75e3d4bView commit details
Commits on Jun 11, 2024
-
Take responsibility of rounding shares and total coverage points
For consistency, the calculator is now truncating values that would have been truncated be the user of the calculator, so we avoid a situation where 2 users of the calculator are using different rounding strategies. The fields that make up the truncated values are provided untouched. Truncating fully to a u64 causes calculations to be off by quite a margin.
Configuration menu - View commit details
-
Copy full SHA for 1abeb84 - Browse repository at this point
Copy the full SHA 1abeb84View commit details -
To keep consistent with the reward calculations this crate is replacing, any rounding of values needs to be avoided before rewards are calculated. This means users of the values will need to handle routing going into protobufs themselves.
Configuration menu - View commit details
-
Copy full SHA for f252947 - Browse repository at this point
Copy the full SHA f252947View commit details -
hip-103: oracles and provider boosting crossover
When a hex is boosted by a provider, it's oracle (assignment) boosting multiplier is automatically pushed to 1x. hip-103: top level oracle/provider boosting test
Configuration menu - View commit details
-
Copy full SHA for ec39a07 - Browse repository at this point
Copy the full SHA ec39a07View commit details -
Come up with names for different scenarios, they are a combination of factors that effect readio scores.
Configuration menu - View commit details
-
Copy full SHA for cfc884a - Browse repository at this point
Copy the full SHA cfc884aView commit details -
Configuration menu - View commit details
-
Copy full SHA for 419b273 - Browse repository at this point
Copy the full SHA 419b273View commit details
Commits on Jun 12, 2024
-
hip-103: provider boost increases oracle boost always
If a hex is boosted by a provider, that hex is deemed valuable from an oracle context, and should always be 1x. Hexes were being "cleaned" of their boost values _before_ trying to determine the oracle multplier, which coupled a hexes boost effect to the assignment multiplier to wether or not the radio was eligible for boosting rewards. That was incorrect. Hexes are now "cleaned" at the same time as determining the multipliers.
Configuration menu - View commit details
-
Copy full SHA for 87b6b3a - Browse repository at this point
Copy the full SHA 87b6b3aView commit details -
I could see an argument for the collection being moved to the front as well. But I think either is a better case than in the middle. I chose the end here because I think it reads easier when testing to have the function, then small decision making structs, _then_ the collection that could be constructed in place.
Configuration menu - View commit details
-
Copy full SHA for 0399213 - Browse repository at this point
Copy the full SHA 0399213View commit details