diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml
index f105ede..cf9c349 100644
--- a/.github/workflows/swift.yml
+++ b/.github/workflows/swift.yml
@@ -13,7 +13,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
- swift: ["5.9"]
+ swift: ["6.0"]
steps:
- uses: swift-actions/setup-swift@v1
with:
diff --git a/.periphery.yml b/.periphery.yml
new file mode 100644
index 0000000..2df913e
--- /dev/null
+++ b/.periphery.yml
@@ -0,0 +1,3 @@
+retain_public: true
+targets:
+- Reducer
diff --git a/.swift-version b/.swift-version
index f0933d4..5049538 100644
--- a/.swift-version
+++ b/.swift-version
@@ -1 +1 @@
-5.10
\ No newline at end of file
+6.0
\ No newline at end of file
diff --git a/.swiftformat b/.swiftformat
new file mode 100644
index 0000000..a000ba5
--- /dev/null
+++ b/.swiftformat
@@ -0,0 +1,50 @@
+# file options
+
+# --exclude Tests/XCTestManifests.swift,Tests/BadConfig,Snapshots,Build,PluginTests
+
+# format options
+
+--allman false
+--binarygrouping 4,8
+--commas inline
+--decimalgrouping 3,6
+--elseposition same-line
+--voidtype void
+--exponentcase lowercase
+--exponentgrouping disabled
+--fractiongrouping disabled
+--header strip
+--hexgrouping 4,8
+--hexliteralcase uppercase
+--ifdef indent
+--indent 4
+--indentcase false
+--importgrouping alpha
+--linebreaks lf
+--maxwidth 150
+--octalgrouping 4,8
+--operatorfunc spaced
+--typedelimiter space-after
+--patternlet hoist
+--ranges spaced
+--self remove
+--redundanttype inferred
+--semicolons inline
+--stripunusedargs always
+--swiftversion 5.10
+--trimwhitespace always
+--wraparguments before-first
+--wrapcollections before-first
+--wrapconditions after-first
+
+# rules
+
+--enable isEmpty
+--acronyms "ID,URL,UUID"
+--enable organizeDeclarations
+--markcategories false
+--organizationmode visibility
+--structthreshold 1
+--classthreshold 1
+--enumthreshold 1
+--extensionlength 1
\ No newline at end of file
diff --git a/.swiftlint.yml b/.swiftlint.yml
index bba7650..fe4851b 100644
--- a/.swiftlint.yml
+++ b/.swiftlint.yml
@@ -71,7 +71,7 @@ opt_in_rules: # some rules are only opt-in
- multiline_arguments
- multiline_literal_brackets
- multiline_parameters
- - no_extension_access_modifier
+ # - no_extension_access_modifier
- nslocalizedstring_key
- number_separator
- object_literal
diff --git a/.swiftpm/configuration/Package.resolved b/.swiftpm/configuration/Package.resolved
new file mode 100644
index 0000000..a54adf8
--- /dev/null
+++ b/.swiftpm/configuration/Package.resolved
@@ -0,0 +1,24 @@
+{
+ "originHash" : "92071d932bcc245a6254633147125ac8851348c79823b708d0e51337b06aa0e2",
+ "pins" : [
+ {
+ "identity" : "swiftformat",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/nicklockwood/SwiftFormat",
+ "state" : {
+ "revision" : "d6309f7440889427426143b4a0b100b959d3f3e6",
+ "version" : "0.54.3"
+ }
+ },
+ {
+ "identity" : "swiftlintplugins",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/SimplyDanny/SwiftLintPlugins",
+ "state" : {
+ "revision" : "6c3d6c32a37224179dc290f21e03d1238f3d963b",
+ "version" : "0.56.2"
+ }
+ }
+ ],
+ "version" : 3
+}
diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/Reducer.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/Reducer.xcscheme
new file mode 100644
index 0000000..79956d6
--- /dev/null
+++ b/.swiftpm/xcode/xcshareddata/xcschemes/Reducer.xcscheme
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 86b5651..0000000
--- a/Makefile
+++ /dev/null
@@ -1,133 +0,0 @@
-.PHONY: set-version pod-push mint test code-coverage-summary code-coverage-details code-coverage-file code-coverage-upload lint-check lint-autocorrect sourcery jazzy docc prebuild notify-telegram help
-.DEFAULT_GOAL := help
-
-# Version
-
-ifndef TO
-set-version:
- $(error Missing new version number. Please use `make set-version TO=1.2.3`)
-else
-set-version:
- sed -i .bkp -E "s/(s\.version.*=.*)'.*'/\1'${TO}'/" *.podspec
- sed -i .bkp -E "s/(, from: )\".*\"\)/\1\"${TO}\")/" README.md
- rm *.bkp
-endif
-
-# Pod push
-pod-push:
- bundle exec pod trunk push Reducer.podspec --allow-warnings
-
-mint:
- command -v mint || brew install mint
- mint bootstrap
-
-# Unit Test
-
-test: SHELL:=/bin/bash
-test:
- set -eo pipefail && \
- swift test --enable-code-coverage --build-path .build
-
-code-coverage-summary:
- xcrun llvm-cov report \
- .build/x86_64-apple-macosx/debug/ReducerPackageTests.xctest/Contents/MacOS/ReducerPackageTests \
- --instr-profile .build/x86_64-apple-macosx/debug/codecov/default.profdata \
- --ignore-filename-regex='.*build/checkouts.*' \
- --ignore-filename-regex='Tests/.*'
-
-code-coverage-details:
- xcrun llvm-cov show \
- .build/x86_64-apple-macosx/debug/ReducerPackageTests.xctest/Contents/MacOS/ReducerPackageTests \
- --instr-profile .build/x86_64-apple-macosx/debug/codecov/default.profdata \
- --ignore-filename-regex='.*build/checkouts.*' \
- --ignore-filename-regex='Tests/.*'
-
-code-coverage-file:
- xcrun llvm-cov show \
- .build/x86_64-apple-macosx/debug/ReducerPackageTests.xctest/Contents/MacOS/ReducerPackageTests \
- --instr-profile .build/x86_64-apple-macosx/debug/codecov/default.profdata \
- --ignore-filename-regex='.*build/checkouts.*' \
- --ignore-filename-regex='Tests/.*' > coverage.txt
-
-code-coverage-upload:
- bash <(curl -s https://codecov.io/bash) \
- -X xcodellvm \
- -X gcov \
- -f coverage.txt
-
-# Lint
-
-lint-check:
- mint run swiftlint lint --strict
-lint-autocorrect:
- mint run swiftlint autocorrect
-
-# Sourcery
-
-sourcery:
- mint run sourcery
-
-# Docc
-docc:
- xcodebuild docbuild -scheme "Reducer" -sdk macosx12.3 -configuration Debug -destination "platform=macOS" SYMROOT=tmp
- cp -R tmp/Debug/Reducer.doccarchive docs/docc/
- mint run docc2html -f docs/docc/Reducer.doccarchive docs/docc/Reducer
- rm -rf tmp
-
-# Jazzy
-
-jazzy:
- bundle exec jazzy --module Reducer --swift-build-tool spm --build-tool-arguments -Xswiftc,-swift-version,-Xswiftc,5 --output docs/api/Reducer
-
-# Pre-Build
-
-prebuild: sourcery lint-autocorrect lint-check
-
-# Help
-
-help:
- @echo Possible tasks
- @echo
- @echo make set-version TO=1.2.3
- @echo -- sets the SwiftRex version to the given value
- @echo -- param1: TO = required, new version number
- @echo
- @echo make pod-push
- @echo -- publishes the pod on CocoaPods repository
- @echo
- @echo make mint
- @echo -- bootstrap mint dependency manager
- @echo
- @echo make test
- @echo -- runs all the unit tests
- @echo
- @echo make code-coverage-summary
- @echo -- shows a code coverage summary
- @echo
- @echo make code-coverage-details
- @echo -- shows a code coverage detailed report
- @echo
- @echo make code-coverage-file
- @echo -- creates a code coverage file to be uploaded to codecov
- @echo
- @echo make code-coverage-upload
- @echo -- upload code coverage file to codecov
- @echo
- @echo make lint-check
- @echo -- validates the code style
- @echo
- @echo make lint-autocorrect
- @echo -- automatic linting for auto-fixable rules
- @echo
- @echo make sourcery
- @echo -- code generation
- @echo
- @echo make jazzy
- @echo -- generates documentation
- @echo
- @echo make docc
- @echo "-- generates DocC documentation"
- @echo
- @echo make prebuild
- @echo -- runs the pre-build phases
- @echo
diff --git a/Mintfile b/Mintfile
deleted file mode 100644
index e925d9e..0000000
--- a/Mintfile
+++ /dev/null
@@ -1,2 +0,0 @@
-realm/SwiftLint@0.54.0
-DoccZz/docc2html@0.5.3
diff --git a/Package.resolved b/Package.resolved
new file mode 100644
index 0000000..261b649
--- /dev/null
+++ b/Package.resolved
@@ -0,0 +1,24 @@
+{
+ "originHash" : "803ac8338fe0c55943c1dbe80216b87723033a79498a9bea118b0c64ced165fe",
+ "pins" : [
+ {
+ "identity" : "swiftformat",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/nicklockwood/SwiftFormat",
+ "state" : {
+ "revision" : "d6309f7440889427426143b4a0b100b959d3f3e6",
+ "version" : "0.54.3"
+ }
+ },
+ {
+ "identity" : "swiftlintplugins",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/SimplyDanny/SwiftLintPlugins",
+ "state" : {
+ "revision" : "6c3d6c32a37224179dc290f21e03d1238f3d963b",
+ "version" : "0.56.2"
+ }
+ }
+ ],
+ "version" : 3
+}
diff --git a/Package.swift b/Package.swift
index cbcba31..71d1b64 100644
--- a/Package.swift
+++ b/Package.swift
@@ -1,32 +1,28 @@
-// swift-tools-version: 5.9
+// swift-tools-version: 5.10
import PackageDescription
-let devModeInXcode = false
-
let package = Package(
name: "Reducer",
- platforms: [.macOS(.v10_13), .iOS(.v12), .tvOS(.v12), .watchOS(.v4)],
+ platforms: [.macOS(.v12), .iOS(.v12), .tvOS(.v12), .watchOS(.v4)],
products: [
.library(name: "Reducer", targets: ["Reducer"])
- ].compactMap { $0 },
+ ],
+ dependencies: [
+ .package(url: "https://github.com/SimplyDanny/SwiftLintPlugins", from: "0.56.2"),
+ .package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.54.0")
+ ],
targets: [
.target(
name: "Reducer",
- dependencies: [],
- plugins: devModeInXcode ? ["SwiftLintXcode"] : []
- ),
- .testTarget(name: "ReducerTests", dependencies: ["Reducer"])
- ] + (devModeInXcode ? [
- .binaryTarget(
- name: "SwiftLintBinary",
- url: "https://github.com/realm/SwiftLint/releases/download/0.54.0/SwiftLintBinary-macos.artifactbundle.zip",
- checksum: "963121d6babf2bf5fd66a21ac9297e86d855cbc9d28322790646b88dceca00f1"
+ plugins: [
+ .plugin(name: "SwiftLintBuildToolPlugin", package: "SwiftLintPlugins"),
+ .plugin(name: "SwiftFormat", package: "SwiftFormat")
+ ]
),
- .plugin(
- name: "SwiftLintXcode",
- capability: .buildTool(),
- dependencies: ["SwiftLintBinary"]
+ .testTarget(
+ name: "ReducerTests",
+ dependencies: ["Reducer"]
)
- ] : []),
+ ],
swiftLanguageVersions: [.v5]
)
diff --git a/Plugins/SwiftLintXcode/Path+Helpers.swift b/Plugins/SwiftLintXcode/Path+Helpers.swift
deleted file mode 100644
index 0698dc6..0000000
--- a/Plugins/SwiftLintXcode/Path+Helpers.swift
+++ /dev/null
@@ -1,42 +0,0 @@
-import Foundation
-import PackagePlugin
-
-#if os(Linux)
-import Glibc
-#else
-import Darwin
-#endif
-
-extension Path {
- /// Scans the receiver, then all of its parents looking for a configuration file with the name ".swiftlint.yml".
- ///
- /// - returns: Path to the configuration file, or nil if one cannot be found.
- func firstConfigurationFileInParentDirectories() -> Path? {
- let defaultConfigurationFileName = ".swiftlint.yml"
- let proposedDirectory = sequence(
- first: self,
- next: { path in
- guard path.stem.count > 1 else {
- // Check we're not at the root of this filesystem, as `removingLastComponent()`
- // will continually return the root from itself.
- return nil
- }
-
- return path.removingLastComponent()
- }
- ).first { path in
- let potentialConfigurationFile = path.appending(subpath: defaultConfigurationFileName)
- return potentialConfigurationFile.isAccessible()
- }
- return proposedDirectory?.appending(subpath: defaultConfigurationFileName)
- }
-
- /// Safe way to check if the file is accessible from within the current process sandbox.
- private func isAccessible() -> Bool {
- let result = string.withCString { pointer in
- access(pointer, R_OK)
- }
-
- return result == 0
- }
-}
diff --git a/Plugins/SwiftLintXcode/SwiftLintPlugin.swift b/Plugins/SwiftLintXcode/SwiftLintPlugin.swift
deleted file mode 100644
index 892edf0..0000000
--- a/Plugins/SwiftLintXcode/SwiftLintPlugin.swift
+++ /dev/null
@@ -1,102 +0,0 @@
-import Foundation
-import PackagePlugin
-
-@main
-struct SwiftLintPlugin: BuildToolPlugin {
- func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] {
- guard let sourceTarget = target as? SourceModuleTarget else {
- return []
- }
- return createBuildCommands(
- inputFiles: sourceTarget.sourceFiles(withSuffix: "swift").map(\.path),
- packageDirectory: context.package.directory,
- workingDirectory: context.pluginWorkDirectory,
- tool: try context.tool(named: "swiftlint")
- )
- }
-
- private func addOptionalArguments(
- to arguments: [String],
- inputFiles: [Path],
- packageDirectory: Path,
- workingDirectory: Path
- ) -> [String] {
- // Determine whether we need to enable cache or not (for Xcode Cloud we don't)
- var arguments = arguments
- if ProcessInfo.processInfo.environment["CI_XCODE_CLOUD"] == "TRUE" {
- arguments.append("--no-cache")
- } else {
- arguments.append("--cache-path")
- arguments.append("\(workingDirectory)")
- }
-
- // Manually look for configuration files, to avoid issues when the plugin does not execute our tool from the
- // package source directory.
- if let configuration = packageDirectory.firstConfigurationFileInParentDirectories() {
- arguments.append(contentsOf: ["--config", "\(configuration.string)"])
- }
- arguments += inputFiles.map(\.string)
- return arguments
- }
-
- private func createBuildCommands(
- inputFiles: [Path],
- packageDirectory: Path,
- workingDirectory: Path,
- tool: PluginContext.Tool
- ) -> [Command] {
- if inputFiles.isEmpty {
- // Don't lint anything if there are no Swift source files in this target
- return []
- }
-
- let differentCommands = [
- [
- "lint",
- "--format",
- "--quiet",
- "--force-exclude"
- ],
- [
- "lint",
- "--quiet",
- "--force-exclude"
- ]
- ]
-
- // We are not producing output files and this is needed only to not include cache files into bundle
- let outputFilesDirectory = workingDirectory.appending("Output")
-
- return differentCommands.map { arguments in
- .prebuildCommand(
- displayName: "SwiftLint",
- executable: tool.path,
- arguments: addOptionalArguments(
- to: arguments,
- inputFiles: inputFiles,
- packageDirectory: packageDirectory,
- workingDirectory: workingDirectory
- ),
- outputFilesDirectory: outputFilesDirectory
- )
- }
- }
-}
-
-#if canImport(XcodeProjectPlugin)
-import XcodeProjectPlugin
-
-extension SwiftLintPlugin: XcodeBuildToolPlugin {
- func createBuildCommands(context: XcodePluginContext, target: XcodeTarget) throws -> [Command] {
- let inputFilePaths = target.inputFiles
- .filter { $0.type == .source && $0.path.extension == "swift" }
- .map(\.path)
- return createBuildCommands(
- inputFiles: inputFilePaths,
- packageDirectory: context.xcodeProject.directory,
- workingDirectory: context.pluginWorkDirectory,
- tool: try context.tool(named: "swiftlint")
- )
- }
-}
-#endif
diff --git a/README.md b/README.md
index 43f924f..68e986e 100644
--- a/README.md
+++ b/README.md
@@ -30,13 +30,13 @@ This pattern, also known as ["Redux"](https://redux.js.org/basics/data-flow), al
The ``MiddlewareProtocol`` pipeline can do two things: dispatch outgoing actions and handling incoming actions. But what they can NOT do is changing the app state. Middlewares have read-only access to the up-to-date state of our apps, but when mutations are required we use the ``MutableReduceFunction`` function:
```swift
-(ActionType, inout StateType) -> Void
+(Action, inout State) -> Void
```
Which has the same semantics (but better performance) than old ``ReduceFunction``:
```swift
-(ActionType, StateType) -> StateType
+(Action, State) -> State
```
Given an action and the current state (as a mutable inout), it calculates the new state and changes it:
diff --git a/Sources/Reducer/Reducer+Compose.swift b/Sources/Reducer/Reducer+Compose.swift
index 5251632..3384cb5 100644
--- a/Sources/Reducer/Reducer+Compose.swift
+++ b/Sources/Reducer/Reducer+Compose.swift
@@ -1,48 +1,12 @@
-extension Reducer {
- /**
- Composes two or more reducers in series, to be evaluated from the left to the right for each incoming action.
-
- When composing reducer A with reducer B, when an action X arrives, first it will be forwarded to
- reducer A together with the initial state. This reducer may return a slightly (or completely) changed state from
- that operation, and this state will then be forwarded to reducer B together with the same action X. If you change
- the order, results may vary as you can imagine. Monoids don't necessarily hold the commutative axiom, although
- sometimes they do. What they necessarily hold is the associativity axiom, which means that if you compose A and B,
- and later C, it's exactly the same as if you compose A to a previously composed B and C:
- `.compose(.compose(A, B), C) == .compose(A, .compose(B, C))`. So please don't worry about surrounding your reducers with parenthesis:
- ```
- let globalReducer = .compose(firstReducer, secondReducer, thirdReducer, andSoOn)
- ```
-
- - Parameters:
- - first: First reducer `(ActionType, inout StateType) -> Void`, let's call it `f(x)`
- - others: Second, Third, nth reducers `(ActionType, inout StateType) -> Void`, let's call it `g(x)`
- - Returns: a composed reducer `(ActionType, inout StateType) -> Void` equivalent to `g(f(x))`
- */
- public static func compose(_ first: Reducer, _ others: Reducer...) -> Reducer {
+public extension Reducer {
+ static func compose(
+ _ first: Reducer,
+ _ others: Reducer...
+ ) -> Reducer {
compose([first] + others)
}
- /**
- Composes reducers in series, to be evaluated in the same order as contained in the array, for each incoming action.
-
- When composing reducer A with reducer B, when an action X arrives, first it will be forwarded to
- reducer A together with the initial state. This reducer may return a slightly (or completely) changed state from
- that operation, and this state will then be forwarded to reducer B together with the same action X. If you change
- the order, results may vary as you can imagine. Monoids don't necessarily hold the commutative axiom, although
- sometimes they do. What they necessarily hold is the associativity axiom, which means that if you compose A and B,
- and later C, it's exactly the same as if you compose A to a previously composed B and C:
- `.compose(.compose(A, B), C) == .compose(A, .compose(B, C))`. So please don't worry about surrounding your reducers with parenthesis:
- ```
- let globalReducer = .compose([firstReducer, secondReducer, thirdReducer, andSoOn])
- ```
-
- - Parameters:
- - reducers: Array with zero or many reducers `(ActionType, inout StateType) -> Void`, to be evaluated in the same
- order as contained in the array. If the array is empty, no operation will happen, which is similar to
- the `Reducer.identity` instance.
- - Returns: a composed reducer `(ActionType, inout StateType) -> Void` equivalent to `g(f(x))`
- */
- public static func compose(_ reducers: [Reducer]) -> Reducer {
+ static func compose(_ reducers: [Reducer]) -> Reducer {
.reduce { action, state in
reducers.forEach { $0.reduce(action, &state) }
}
diff --git a/Sources/Reducer/Reducer+DSL.swift b/Sources/Reducer/Reducer+DSL.swift
index 14aef83..51b7ffe 100644
--- a/Sources/Reducer/Reducer+DSL.swift
+++ b/Sources/Reducer/Reducer+DSL.swift
@@ -1,53 +1,13 @@
import Foundation
-/**
- DSL Builder for Reducer compose
- */
@resultBuilder public enum ReducerBuilder {
- /**
- DSL Builder for Reducer compose
- - Parameter reducers: the reducers to be combined/
- - Returns: the composed reducer that will run all the inner reducers sequentially/
- */
public static func buildBlock(_ reducers: Reducer...) -> Reducer {
.compose(reducers)
}
}
-extension Reducer {
- /**
- Composes two or more reducers in series, to be evaluated from the top to the bottom for each incoming action.
-
- When composing reducer A with reducer B, when an action X arrives, first it will be forwarded to
- reducer A together with the initial state. This reducer may return a slightly (or completely) changed state from
- that operation, and this state will then be forwarded to reducer B together with the same action X. If you change
- the order, results may vary as you can imagine. Monoids don't necessarily hold the commutative axiom, although
- sometimes they do.
-
- For example you can compose reducers like this:
- ```
- Reducer.compose {
- Reducer
- .login
- .lift(action: \.loginAction, state: \.loginState)
-
- Reducer
- .lifecycle
- .lift(action: \.lifecycleAction, state: \.lifecycleState)
-
- Reducer.app
-
- Reducer.reduce { action, state in
- // some inline reducer
- }
- }
- ```
-
- - Parameter content: a result builder (DSL) having zero or more reducers to be composed sequentially
- - Returns: a composed reducer `(ActionType, inout StateType) -> Void` equivalent to running all the internal
- reducers in series
- */
- public static func compose(@ReducerBuilder content: () -> Reducer) -> Reducer {
+public extension Reducer {
+ static func compose(@ReducerBuilder content: () -> Reducer) -> Reducer {
content()
}
}
diff --git a/Sources/Reducer/Reducer+Identity.swift b/Sources/Reducer/Reducer+Identity.swift
index d559f54..c31b511 100644
--- a/Sources/Reducer/Reducer+Identity.swift
+++ b/Sources/Reducer/Reducer+Identity.swift
@@ -1,26 +1,5 @@
-extension Reducer {
- /**
- No-op reducer. Composing it with any other reducer will not change anything from the other reducer behaviour, regardless if the identity reducer
- is on the left-hand side or the right-hand side or this composition. This is the neutral element in a monoidal composition.
-
- Therefore:
- ```
- .compose( Reducer, .identity )
- == .compose( .identity, Reducer )
- == Reducer
- ```
-
- This is useful for composition purposes, for example when you call a function `Array.reduce` in an array of Reducers and you need a no-op start:
- ```
- [reducer1, reducer2].reduce(.identity) { accumulator, nextReducer in
- Reducer.compose(accumulator, nextReducer)
- }
- // .identity won't have any behaviour and the final composition ".identity >>> reducer1, reducer2" will be as if .identity wasn't there.
- ```
-
- The implementation of this reducer, as one should expect, simply ignores the action and returns the state unchanged
- */
- public static var identity: Reducer {
+public extension Reducer {
+ static var identity: Reducer {
.init { _, _ in }
}
}
diff --git a/Sources/Reducer/Reducer+LiftClosure.swift b/Sources/Reducer/Reducer+LiftClosure.swift
index 5391d88..42627f7 100644
--- a/Sources/Reducer/Reducer+LiftClosure.swift
+++ b/Sources/Reducer/Reducer+LiftClosure.swift
@@ -1,82 +1,16 @@
-extension Reducer {
- /**
- A type-lifting method. The global state of your app is _Whole_, and the `Reducer` handles _Part_, that is a
- sub-state.
-
- Let's suppose you may want to have a `gpsReducer` that knows about the following `struct`:
- ```
- struct Location {
- let latitude: Double
- let longitude: Double
- }
- ```
-
- Let's call it _Part_. Both, this state and its reducer will be part of an external framework, used by dozens of
- apps. Internally probably the `Reducer` will receive some known `ActionType` and calculate a new location. On the
- main app we have a global state, that we now call _Whole_.
-
- ```
- struct MyGlobalState {
- let title: String?
- let listOfItems: [Item]
- let currentLocation: Location
- }
- ```
-
- As expected, _Part_ (`Location`) is a property of _Whole_ (`MyGlobalState`). This relationship could be less
- direct, for example there could be several levels of properties until you find the _Part_ in the _Whole_, like
- `global.firstLevel.secondLevel.currentLocation`, but let's keep it a single-level for this example.
-
- Because our `Store` understands _Whole_ (`MyGlobalState`) and our `gpsReducer` understands _Part_ (`Location`), we
- must `lift` the `Reducer` to the _Whole_ level, by using:
-
- ```
- let globalStateReducer = gpsReducer.lift(
- actionGetter: { $0 },
- stateGetter: { global in global.currentLocation },
- stateSetter: { global, part in global.currentLocation = path }
- )
- // where:
- // globalStateReducer: Reducer
- // ↑ lift
- // gpsReducer: Reducer
- ```
-
- Now this reducer can be used within our `Store` or even composed with others. It also can be used in other apps as
- long as we have a way to lift it to the world of _Whole_.
-
- Same strategy works for the `action`, as you can guess by the `actionGetter` parameter. You can provide a function
- that takes a global action (_Whole_) and returns an optional local action (_Part_). It's optional because perhaps
- you want to ignore actions that are not relevant for this reducer.
-
- - Parameters:
- - actionGetter: a way to convert a global action into a local action, but it's optional because maybe this
- reducer shouldn't care about certain actions. Because actions are usually enums, you can switch
- over the enum and in case it's nothing you care about, you simply return nil in the closure. If
- you don't want to lift this reducer in terms of `action`, just provide the identity function
- `{ $0 }` as input.
- - stateGetter: a way to read from a global state and extract only the part that it's relevant for this reducer,
- by traversing the tree of the global state until you find the property you want, for example:
- `{ $0.currentGame.scoreBoard }`
- - stateSetter: a way to write back into the global state once you finished reducing the _Part_, so now you have
- a new part that was calculated by this reducer and you want to set it into the global state, also
- provided as the first parameter as an `inout` property:
- `{ globalState, newScoreBoard in globalState.currentGame.scoreBoard = newScoreBoard }`
- - Returns: a `Reducer` that maps actions and states from the original specialised
- reducer into a more generic and global reducer, to be used in a larger context.
- */
- public func lift(
- action: PrismExtract
- ) -> Reducer {
+ public extension Reducer {
+ func lift(
+ action: PrismExtract
+ ) -> Reducer {
.reduce { globalAction, globalState in
guard let localAction = action.tryToExtract(globalAction) else { return }
self.reduce(localAction, &globalState)
}
}
- public func lift(
- state: Lens
- ) -> Reducer {
+ func lift(
+ state: Lens
+ ) -> Reducer {
.reduce { globalAction, globalState in
var localState = state.extract(from: globalState)
self.reduce(globalAction, &localState)
@@ -84,10 +18,10 @@ extension Reducer {
}
}
- public func lift(
- action: PrismExtract,
- state: Lens
- ) -> Reducer {
+ func lift(
+ action: PrismExtract,
+ state: Lens
+ ) -> Reducer {
.reduce { globalAction, globalState in
guard let localAction = action.tryToExtract(globalAction) else { return }
var localState = state.extract(from: globalState)
@@ -96,17 +30,14 @@ extension Reducer {
}
}
- public func lift(
- _ lifter: ReducerLift
- ) -> Reducer {
+ func lift(
+ _ lifter: ReducerLift
+ ) -> Reducer {
lift(action: lifter.action, state: lifter.state)
}
}
public struct ReducerLift {
- fileprivate let action: PrismExtract
- fileprivate let state: Lens
-
public init(action: PrismExtract, state: Lens) {
self.state = state
self.action = action
@@ -121,10 +52,13 @@ public struct ReducerLift {
state: Lens.compose(global.state, local.state)
)
}
+
+ fileprivate let action: PrismExtract
+ fileprivate let state: Lens
}
-extension ReducerLift where GlobalAction == LocalAction, GlobalState == LocalState {
- public static var identity: ReducerLift {
+public extension ReducerLift where GlobalAction == LocalAction, GlobalState == LocalState {
+ static var identity: ReducerLift {
.init(action: .identity, state: .identity)
}
}
@@ -137,12 +71,12 @@ public struct PrismExtract {
}
}
-extension PrismExtract {
- public static func keyPath(_ keyPath: KeyPath) -> Self {
+public extension PrismExtract {
+ static func keyPath(_ keyPath: KeyPath) -> Self {
.tryingToExtract { $0[keyPath: keyPath] }
}
- public static func compose(
+ static func compose(
_ moreAbstract: PrismExtract,
_ moreSpecific: PrismExtract
) -> PrismExtract {
@@ -152,8 +86,8 @@ extension PrismExtract {
}
}
-extension PrismExtract where Enum == Case {
- public static var identity: Self {
+public extension PrismExtract where Enum == Case {
+ static var identity: Self {
.tryingToExtract { $0 }
}
}
@@ -166,8 +100,8 @@ public struct PrismEmbed {
}
}
-extension PrismEmbed {
- public static func compose(
+public extension PrismEmbed {
+ static func compose(
_ moreAbstract: PrismEmbed,
_ moreSpecific: PrismEmbed
) -> PrismEmbed {
@@ -177,16 +111,13 @@ extension PrismEmbed {
}
}
-extension PrismEmbed where EnumCase == AssociatedValue {
- public static var identity: Self {
+public extension PrismEmbed where EnumCase == AssociatedValue {
+ static var identity: Self {
.embedding { $0 }
}
}
public struct Prism {
- private let _extract: PrismExtract
- private let _embed: PrismEmbed
-
public static func on(
extracting path: @escaping (Enum) -> Case?,
embedding associatedValue: @escaping (Case) -> Enum
@@ -207,14 +138,6 @@ public struct Prism {
)
}
- public func embed(associatedValue: Case) -> Enum {
- _embed.embed(associatedValue)
- }
-
- public func tryToExtract(from `enum`: Enum) -> Case? {
- _extract.tryToExtract(`enum`)
- }
-
public static func compose(
_ moreAbstract: Prism,
_ moreSpecific: Prism
@@ -224,10 +147,21 @@ public struct Prism {
embedding: PrismEmbed.compose(moreAbstract._embed, moreSpecific._embed).embed
)
}
+
+ public func embed(associatedValue: Case) -> Enum {
+ _embed.embed(associatedValue)
+ }
+
+ public func tryToExtract(from enum: Enum) -> Case? {
+ _extract.tryToExtract(`enum`)
+ }
+
+ private let _extract: PrismExtract
+ private let _embed: PrismEmbed
}
-extension Prism where Enum == Case {
- public static var identity: Prism {
+public extension Prism where Enum == Case {
+ static var identity: Prism {
.on(
extracting: PrismExtract.identity.tryToExtract,
embedding: PrismEmbed.identity.embed
@@ -243,12 +177,12 @@ public struct LensGet {
}
}
-extension LensGet {
- public static func keyPath(_ keyPath: KeyPath) -> LensGet {
+public extension LensGet {
+ static func keyPath(_ keyPath: KeyPath) -> LensGet {
.extracting { $0[keyPath: keyPath] }
}
- public static func compose(
+ static func compose(
_ moreAbstract: LensGet,
_ moreSpecific: LensGet
) -> LensGet {
@@ -258,8 +192,8 @@ extension LensGet {
}
}
-extension LensGet where Struct == Property {
- public static var identity: Self {
+public extension LensGet where Struct == Property {
+ static var identity: Self {
.extracting { $0 }
}
}
@@ -272,16 +206,13 @@ public struct LensSet {
}
}
-extension LensSet where Struct == Property {
- public static var identity: Self {
+public extension LensSet where Struct == Property {
+ static var identity: Self {
.setting { $0 = $1 }
}
}
public struct Lens {
- private let _extract: LensGet
- private let _set: LensSet
-
public static func on(
extracting path: @escaping (Struct) -> Property,
setting property: @escaping (inout Struct, Property) -> Void
@@ -306,14 +237,6 @@ public struct Lens {
.on(extractingKeyPath: keyPath, setting: { $0[keyPath: keyPath] = $1 })
}
- public func set(struct: inout Struct, with property: Property) {
- _set.set(&`struct`, property)
- }
-
- public func extract(from `struct`: Struct) -> Property {
- _extract.extract(`struct`)
- }
-
public static func compose(
_ moreAbstract: Lens,
_ moreSpecific: Lens
@@ -327,10 +250,22 @@ public struct Lens {
}
)
}
+
+ public func set(struct: inout Struct, with property: Property) {
+ _set.set(&`struct`, property)
+ }
+
+ public func extract(from struct: Struct) -> Property {
+ _extract.extract(`struct`)
+ }
+
+ private let _extract: LensGet
+
+ private let _set: LensSet
}
-extension Lens where Struct == Property {
- public static var identity: Lens {
+public extension Lens where Struct == Property {
+ static var identity: Lens {
.on(extracting: LensGet.identity.extract, setting: LensSet.identity.set)
}
}
diff --git a/Sources/Reducer/Reducer+LiftToCollection.swift b/Sources/Reducer/Reducer+LiftToCollection.swift
index e4fac13..d110172 100644
--- a/Sources/Reducer/Reducer+LiftToCollection.swift
+++ b/Sources/Reducer/Reducer+LiftToCollection.swift
@@ -1,82 +1,11 @@
import Foundation
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
-extension Reducer where StateType: Identifiable {
- /**
- A type-lifting method for collections. The global state of your app is _Whole_, and the `Reducer` handles an element
- that is inside of a collection, which itself is sub-state of the global. Let's call this single element _Part_.
-
- Let's suppose you may want to have a `gpsReducer` that knows about the following `struct`:
- ```
- struct Location {
- let latitude: Double
- let longitude: Double
- }
- ```
-
- Let's call it _Part_. Both, this state and its reducer will be part of an external framework, used by dozens of
- apps. Internally probably the `Reducer` will receive some known `ActionType` and calculate a new location. On the
- main app we have a global state, that we now call _Whole_.
-
- ```
- struct MyGlobalState {
- let title: String?
- let knownLocations: [Location]
- }
- ```
-
- As expected, _Part_ (`Location`) is an element of the array `knownLocations`, which is property of _Whole_
- (`MyGlobalState`). This relationship could be less direct, for example there could be several levels of properties
- until you find the _Part_ in the _Whole_, like `global.firstLevel.secondLevel.knownLocations`, but let's keep it a
- single-level for this example.
-
- To resolve this single element, we not only have to find the path to the array, but we have to find the element
- inside of the array. There are three methods for doing so:
- 1) the element is `Identifiable` (iOS 13 or later)
- 2) the element has a `Hashable` property that makes it unique, so we can find it in the array using this identifier
- 3) using the index of the element in the array
-
- Because our `Store` understands _Whole_ (`MyGlobalState`) and our `gpsReducer` understands _Part_ (`Location`), we
- must `liftToCollection` the `Reducer` to the _Whole_ level, by using:
-
- ```
- let globalStateReducer = gpsReducer.liftToCollection(
- actionMap: \.actionKeyPathToATuple,
- state: \.knownLocations
- )
- // where:
- // globalStateReducer: Reducer
- // ↑ lift
- // gpsReducer: Reducer
- ```
-
- Different from simple `lift` to scalar, this one requires necessarily that you lift the action together with the state.
- That's because your action has to contain the ID or Index of the element we will modify. The `actionMap` KeyPath has to
- give us a tuple of either:
- - `(id, actionToSingleElement)`
- - `(index, actionToSingleElement)`
-
- The id or index is gonna be how we will search the array for the desired element, and only if we find it, we will run
- the `gpsReducer` for that specific element, using the action that has to do with single elements only.
-
- As `Location` doesn't have an `id` property we will have to either use index, implement `Identifiable` protocol or
- give another unique and `Hashable` property.
-
- Now this reducer can be used within our `Store` or even composed with others. It also can be used in other apps as
- long as we have a way to lift it to the world of _Whole_.
-
- - Parameters:
- - actionMap: a read-only key-path from global action into a tuple: (id, local action), but it's optional because
- maybe this reducer shouldn't care about certain actions.
- - stateCollection: a writable key-path from global state that traverses into a local state, by extracting only
- the part that it's relevant for this reducer. This part needs to be a `MutableCollection`.
- - Returns: a `Reducer` that maps actions and states from the original local reducer, which
- is specialised in a single Element, into a more generic and global reducer, to be used in a larger context.
- */
- public func liftToCollection(
- actionForElement: PrismExtract,
+public extension Reducer where State: Identifiable {
+ func liftToCollection(
+ actionForElement: PrismExtract,
stateToCollection: Lens
- ) -> Reducer where CollectionState.Element == StateType {
+ ) -> Reducer where CollectionState.Element == State {
Reducer.reduce { (action: GlobalAction, state: inout GlobalState) in
var collection = stateToCollection.extract(from: state)
@@ -92,84 +21,12 @@ extension Reducer where StateType: Identifiable {
}
}
-extension Reducer {
- /**
- A type-lifting method for collections. The global state of your app is _Whole_, and the `Reducer` handles an element
- that is inside of a collection, which itself is sub-state of the global. Let's call this single element _Part_.
-
- Let's suppose you may want to have a `gpsReducer` that knows about the following `struct`:
- ```
- struct Location {
- let latitude: Double
- let longitude: Double
- }
- ```
-
- Let's call it _Part_. Both, this state and its reducer will be part of an external framework, used by dozens of
- apps. Internally probably the `Reducer` will receive some known `ActionType` and calculate a new location. On the
- main app we have a global state, that we now call _Whole_.
-
- ```
- struct MyGlobalState {
- let title: String?
- let knownLocations: [Location]
- }
- ```
-
- As expected, _Part_ (`Location`) is an element of the array `knownLocations`, which is property of _Whole_
- (`MyGlobalState`). This relationship could be less direct, for example there could be several levels of properties
- until you find the _Part_ in the _Whole_, like `global.firstLevel.secondLevel.knownLocations`, but let's keep it a
- single-level for this example.
-
- To resolve this single element, we not only have to find the path to the array, but we have to find the element
- inside of the array. There are three methods for doing so:
- 1) the element is `Identifiable` (iOS 13 or later)
- 2) the element has a `Hashable` property that makes it unique, so we can find it in the array using this identifier
- 3) using the index of the element in the array
-
- Because our `Store` understands _Whole_ (`MyGlobalState`) and our `gpsReducer` understands _Part_ (`Location`), we
- must `liftToCollection` the `Reducer` to the _Whole_ level, by using:
-
- ```
- let globalStateReducer = gpsReducer.liftToCollection(
- actionMap: \.actionKeyPathToATuple,
- state: \.knownLocations
- )
- // where:
- // globalStateReducer: Reducer
- // ↑ lift
- // gpsReducer: Reducer
- ```
-
- Different from simple `lift` to scalar, this one requires necessarily that you lift the action together with the state.
- That's because your action has to contain the ID or Index of the element we will modify. The `actionMap` KeyPath has to
- give us a tuple of either:
- - `(id, actionToSingleElement)`
- - `(index, actionToSingleElement)`
-
- The id or index is gonna be how we will search the array for the desired element, and only if we find it, we will run
- the `gpsReducer` for that specific element, using the action that has to do with single elements only.
-
- As `Location` doesn't have an `id` property we will have to either use index, implement `Identifiable` protocol or
- give another unique and `Hashable` property.
-
- Now this reducer can be used within our `Store` or even composed with others. It also can be used in other apps as
- long as we have a way to lift it to the world of _Whole_.
-
- - Parameters:
- - actionMap: a read-only key-path from global action into a tuple: (id, local action), but it's optional because
- maybe this reducer shouldn't care about certain actions.
- - stateCollection: a writable key-path from global state that traverses into a local state, by extracting only
- the part that it's relevant for this reducer. This part needs to be a `MutableCollection`.
- - identifier: a key-path to define who is the unique-identifier of the Element (it has to be `Hashable`)
- - Returns: a `Reducer` that maps actions and states from the original local reducer, which
- is specialised in a single Element, into a more generic and global reducer, to be used in a larger context.
- */
- public func liftToCollection(
- actionForElement: PrismExtract,
+public extension Reducer {
+ func liftToCollection(
+ actionForElement: PrismExtract,
stateToCollection: Lens,
- identifier: KeyPath
- ) -> Reducer where CollectionState.Element == StateType {
+ identifier: KeyPath
+ ) -> Reducer where CollectionState.Element == State {
Reducer.reduce { action, state in
var collection = stateToCollection.extract(from: state)
@@ -185,82 +42,11 @@ extension Reducer {
}
}
-extension Reducer {
- /**
- A type-lifting method for collections. The global state of your app is _Whole_, and the `Reducer` handles an element
- that is inside of a collection, which itself is sub-state of the global. Let's call this single element _Part_.
-
- Let's suppose you may want to have a `gpsReducer` that knows about the following `struct`:
- ```
- struct Location {
- let latitude: Double
- let longitude: Double
- }
- ```
-
- Let's call it _Part_. Both, this state and its reducer will be part of an external framework, used by dozens of
- apps. Internally probably the `Reducer` will receive some known `ActionType` and calculate a new location. On the
- main app we have a global state, that we now call _Whole_.
-
- ```
- struct MyGlobalState {
- let title: String?
- let knownLocations: [Location]
- }
- ```
-
- As expected, _Part_ (`Location`) is an element of the array `knownLocations`, which is property of _Whole_
- (`MyGlobalState`). This relationship could be less direct, for example there could be several levels of properties
- until you find the _Part_ in the _Whole_, like `global.firstLevel.secondLevel.knownLocations`, but let's keep it a
- single-level for this example.
-
- To resolve this single element, we not only have to find the path to the array, but we have to find the element
- inside of the array. There are three methods for doing so:
- 1) the element is `Identifiable` (iOS 13 or later)
- 2) the element has a `Hashable` property that makes it unique, so we can find it in the array using this identifier
- 3) using the index of the element in the array
-
- Because our `Store` understands _Whole_ (`MyGlobalState`) and our `gpsReducer` understands _Part_ (`Location`), we
- must `liftToCollection` the `Reducer` to the _Whole_ level, by using:
-
- ```
- let globalStateReducer = gpsReducer.liftToCollection(
- actionMap: \.actionKeyPathToATuple,
- state: \.knownLocations
- )
- // where:
- // globalStateReducer: Reducer
- // ↑ lift
- // gpsReducer: Reducer
- ```
-
- Different from simple `lift` to scalar, this one requires necessarily that you lift the action together with the state.
- That's because your action has to contain the ID or Index of the element we will modify. The `actionMap` KeyPath has to
- give us a tuple of either:
- - `(id, actionToSingleElement)`
- - `(index, actionToSingleElement)`
-
- The id or index is gonna be how we will search the array for the desired element, and only if we find it, we will run
- the `gpsReducer` for that specific element, using the action that has to do with single elements only.
-
- As `Location` doesn't have an `id` property we will have to either use index, implement `Identifiable` protocol or
- give another unique and `Hashable` property.
-
- Now this reducer can be used within our `Store` or even composed with others. It also can be used in other apps as
- long as we have a way to lift it to the world of _Whole_.
-
- - Parameters:
- - actionMap: a read-only key-path from global action into a tuple: (index, local action), but it's optional because
- maybe this reducer shouldn't care about certain actions.
- - stateCollection: a writable key-path from global state that traverses into a local state, by extracting only
- the part that it's relevant for this reducer. This part needs to be a `MutableCollection`.
- - Returns: a `Reducer` that maps actions and states from the original local reducer, which
- is specialised in a single Element, into a more generic and global reducer, to be used in a larger context.
- */
- public func liftToCollection(
- actionForElement: PrismExtract,
+public extension Reducer {
+ func liftToCollection(
+ actionForElement: PrismExtract,
stateToCollection: Lens
- ) -> Reducer where CollectionState.Element == StateType {
+ ) -> Reducer where CollectionState.Element == State {
Reducer.reduce { action, state in
var collection = stateToCollection.extract(from: state)
diff --git a/Sources/Reducer/Reducer.swift b/Sources/Reducer/Reducer.swift
index 922ae4a..7e04f8c 100644
--- a/Sources/Reducer/Reducer.swift
+++ b/Sources/Reducer/Reducer.swift
@@ -1,60 +1,11 @@
-/**
- An entity that calculates the new state when given current state and an incoming action `(Action, inout State) -> Void`.
-
- Create it using the following code:
- ```
- let counterReducer = Reducer.reduce { action, state in
- switch action {
- case .increment:
- state.counter += 1
- case .decrement:
- state.counter -= 1
- case .reset:
- state.counter = 0
- state.lastError = ""
- case .gotError(let message):
- state.lastError = message
- case .print:
- break
- }
- }
- ```
+public struct Reducer {
+ init(reduce: @escaping (Action, inout State) -> Void) {
+ self.reduce = reduce
+ }
- An app triggers several actions over time, either coming from user input (button tap, scroll, pinch gesture), from sensors (CoreLocation, NFC,
- HealthKit), communication protocols (CoreBluetooth, networking, WebSocket), databases (CoreData, Realm), timers and many more.
- An app also starts with an initial state, right after its cold launch.
- For each action that arrives, the state can be modified, and this is exactly what a `Reducer` does: folds all actions that arrived since the app
- launch, plus the initial state, into the current state. One at the time.
- The shape of a `Reducer` could be represented as `(Action, State) -> State`, or given the incoming action and the latest known state, calculate the
- new state.
- For the sake of performance, and keeping the same semantics, the SwiftRex `Reducer` is represented as `(Action, inout State) -> Void`, avoiding
- unnecessary copies and allowing performance tuning for arrays or other big collections.
- A `Reducer` can focus in a small part, and be composed with other reducers. The order of this composition matters, because the state will be modified
- in the order as the reducers were composed, but you should avoid two reducers changing the same domain. If you can't avoid, mind the order.
- A `Reducer` can also focus in a subset of your full AppAction and AppState, and be "lifted" from the subset to the whole, for example it's focused on
- LoginAction and LoginState, then lifted to the whole AppAction and AppState by providing the KeyPath where the subset LoginAction is in the
- AppAction, and where the subset LoginState is in the AppState.
- */
-public struct Reducer {
- /**
- Execute the wrapped reduce function. You must provide the parameters `action: ActionType` (the action to be
- evaluated during the reducing process) and an `inout` version of the latest `state: StateType`, (the current
- state in your single source-of-truth).
- State will be mutated in place (`inout`) and finish with the calculated new state.
- */
- public let reduce: (ActionType, inout StateType) -> Void
+ public let reduce: (Action, inout State) -> Void
- /**
- Reducer initialiser takes only the underlying function `(ActionType, inout StateType) -> Void` that is the reducer
- function itself.
- - Parameters:
- - reduce: a pure function that calculates the new state from an action and the current state.
- */
- public static func reduce(_ reduce: @escaping (ActionType, inout StateType) -> Void) -> Reducer {
+ public static func reduce(_ reduce: @escaping (Action, inout State) -> Void) -> Reducer {
Reducer(reduce: reduce)
}
-
- init(reduce: @escaping (ActionType, inout StateType) -> Void) {
- self.reduce = reduce
- }
}
diff --git a/Tests/ReducerTests/Mocks.swift b/Tests/ReducerTests/Mocks.swift
index 75391a9..2c84bc8 100644
--- a/Tests/ReducerTests/Mocks.swift
+++ b/Tests/ReducerTests/Mocks.swift
@@ -1,18 +1,18 @@
import Foundation
import Reducer
-struct ActionScopedById: Equatable {
+struct ActionScopedById: Equatable {
let id: Int
- let action: ActionType
+ let action: Action
- var tuple: (id: Int, action: ActionType) { (id: id, action: action) }
+ var tuple: (id: Int, action: Action) { (id: id, action: action) }
}
-struct ActionScopedByIndex: Equatable {
+struct ActionScopedByIndex: Equatable {
let index: Int
- let action: ActionType
+ let action: Action
- var tuple: (index: Int, action: ActionType) { (index: index, action: action) }
+ var tuple: (index: Int, action: Action) { (index: index, action: action) }
}
enum AppAction: Equatable {
@@ -69,7 +69,7 @@ enum AppAction: Equatable {
return nil
}
set {
- guard case .scoped = self, let newValue = newValue else { return }
+ guard case .scoped = self, let newValue else { return }
self = .scoped(newValue)
}
}
@@ -102,13 +102,13 @@ struct TestState: Equatable {
}
struct AppState: Equatable {
- let testState: TestState
- var list: [Item]
-
struct Item: Equatable, Identifiable {
let id: Int
var name: String
}
+
+ let testState: TestState
+ var list: [Item]
}
let createNameReducer: () -> Reducer = {
@@ -135,14 +135,15 @@ let createReducerMock: () -> (Reducer, ReducerMock {
+class ReducerMock {
// MARK: - reduce
var reduceCallsCount = 0
+ var reduceReceivedArguments: (action: Action, currentState: State)?
+ var reduceReturnValue: State!
+ var reduceClosure: ((Action, State) -> State)?
+
var reduceCalled: Bool {
reduceCallsCount > 0
}
- var reduceReceivedArguments: (action: ActionType, currentState: StateType)?
- var reduceReturnValue: StateType!
- var reduceClosure: ((ActionType, StateType) -> StateType)?
}
diff --git a/Tests/ReducerTests/ReducerTests.swift b/Tests/ReducerTests/ReducerTests.swift
index 883d1bd..958ac36 100644
--- a/Tests/ReducerTests/ReducerTests.swift
+++ b/Tests/ReducerTests/ReducerTests.swift
@@ -165,7 +165,7 @@ class ReducerTests: XCTestCase {
global.name = string
}
)
- )
+ )
var reduced = original
liftedReducer.reduce(.bar(.charlie), &reduced)
@@ -190,7 +190,7 @@ class ReducerTests: XCTestCase {
global.name = string
}
)
- )
+ )
var reduced = original
liftedReducer.reduce(.foo, &reduced)
diff --git a/codecov.yml b/codecov.yml
deleted file mode 100644
index 67e2ae7..0000000
--- a/codecov.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-ignore:
- - "Tests/**/*"
- - ".build/checkouts/**/*"
-
-fixes:
- - "/Users/travis/build/::"
-
-coverage:
- status:
- project:
- default:
- target: auto
- threshold: 10%
- base: auto
\ No newline at end of file
diff --git a/docs/api/Reducer/Enums.html b/docs/api/Reducer/Enums.html
deleted file mode 100644
index 26e7fc8..0000000
--- a/docs/api/Reducer/Enums.html
+++ /dev/null
@@ -1,106 +0,0 @@
-
-
-
- Enumerations Reference
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
An entity that calculates the new state when given current state and an incoming action (Action, inout State) -> Void.
-
-
An app triggers several actions over time, either coming from user input (button tap, scroll, pinch gesture), from sensors (CoreLocation, NFC,
-HealthKit), communication protocols (CoreBluetooth, networking, WebSocket), databases (CoreData, Realm), timers and many more.
-An app also starts with an initial state, right after its cold launch.
-For each action that arrives, the state can be modified, and this is exactly what a Reducer does: folds all actions that arrived since the app
-launch, plus the initial state, into the current state. One at the time.
-The shape of a Reducer could be represented as (Action, State) -> State, or given the incoming action and the latest known state, calculate the
-new state.
-For the sake of performance, and keeping the same semantics, the SwiftRex Reducer is represented as (Action, inout State) -> Void, avoiding
-unnecessary copies and allowing performance tuning for arrays or other big collections.
-A Reducer can focus in a small part, and be composed with other reducers. The order of this composition matters, because the state will be modified
-in the order as the reducers were composed, but you should avoid two reducers changing the same domain. If you can’t avoid, mind the order.
-A Reducer can also focus in a subset of your full AppAction and AppState, and be “lifted” from the subset to the whole, for example it’s focused on
-LoginAction and LoginState, then lifted to the whole AppAction and AppState by providing the KeyPath where the subset LoginAction is in the
-AppAction, and where the subset LoginState is in the AppState.
An entity that calculates the new state when given current state and an incoming action (Action, inout State) -> Void.
-
-
An app triggers several actions over time, either coming from user input (button tap, scroll, pinch gesture), from sensors (CoreLocation, NFC,
-HealthKit), communication protocols (CoreBluetooth, networking, WebSocket), databases (CoreData, Realm), timers and many more.
-An app also starts with an initial state, right after its cold launch.
-For each action that arrives, the state can be modified, and this is exactly what a Reducer does: folds all actions that arrived since the app
-launch, plus the initial state, into the current state. One at the time.
-The shape of a Reducer could be represented as (Action, State) -> State, or given the incoming action and the latest known state, calculate the
-new state.
-For the sake of performance, and keeping the same semantics, the SwiftRex Reducer is represented as (Action, inout State) -> Void, avoiding
-unnecessary copies and allowing performance tuning for arrays or other big collections.
-A Reducer can focus in a small part, and be composed with other reducers. The order of this composition matters, because the state will be modified
-in the order as the reducers were composed, but you should avoid two reducers changing the same domain. If you can’t avoid, mind the order.
-A Reducer can also focus in a subset of your full AppAction and AppState, and be “lifted” from the subset to the whole, for example it’s focused on
-LoginAction and LoginState, then lifted to the whole AppAction and AppState by providing the KeyPath where the subset LoginAction is in the
-AppAction, and where the subset LoginState is in the AppState.
Execute the wrapped reduce function. You must provide the parameters action: ActionType (the action to be
-evaluated during the reducing process) and an inout version of the latest state: StateType, (the current
-state in your single source-of-truth).
-State will be mutated in place (inout) and finish with the calculated new state.
Composes two or more reducers in series, to be evaluated from the left to the right for each incoming action.
-
-
When composing reducer A with reducer B, when an action X arrives, first it will be forwarded to
-reducer A together with the initial state. This reducer may return a slightly (or completely) changed state from
-that operation, and this state will then be forwarded to reducer B together with the same action X. If you change
-the order, results may vary as you can imagine. Monoids don’t necessarily hold the commutative axiom, although
-sometimes they do. What they necessarily hold is the associativity axiom, which means that if you compose A and B,
-and later C, it’s exactly the same as if you compose A to a previously composed B and C:
-.compose(.compose(A, B), C) == .compose(A, .compose(B, C)). So please don’t worry about surrounding your reducers with parenthesis:
Composes two or more reducers in series, to be evaluated from the top to the bottom for each incoming action.
-
-
When composing reducer A with reducer B, when an action X arrives, first it will be forwarded to
-reducer A together with the initial state. This reducer may return a slightly (or completely) changed state from
-that operation, and this state will then be forwarded to reducer B together with the same action X. If you change
-the order, results may vary as you can imagine. Monoids don’t necessarily hold the commutative axiom, although
-sometimes they do.
No-op reducer. Composing it with any other reducer will not change anything from the other reducer behaviour, regardless if the identity reducer
-is on the left-hand side or the right-hand side or this composition. This is the neutral element in a monoidal composition.
This is useful for composition purposes, for example when you call a function Array.reduce in an array of Reducers and you need a no-op start:
-
[reducer1,reducer2].reduce(.identity){accumulator,nextReducerin
- Reducer.compose(accumulator,nextReducer)
-}
-// .identity won't have any behaviour and the final composition ".identity >>> reducer1, reducer2" will be as if .identity wasn't there.
-
-
-
The implementation of this reducer, as one should expect, simply ignores the action and returns the state unchanged
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is a property of Whole (MyGlobalState). This relationship could be less
-direct, for example there could be several levels of properties until you find the Part in the Whole, like
-global.firstLevel.secondLevel.currentLocation, but let’s keep it a single-level for this example.
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must lift the Reducer to the Whole level, by using:
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
-
-
Same strategy works for the action, as you can guess by the actionGetter parameter. You can provide a function
-that takes a global action (Whole) and returns an optional local action (Part). It’s optional because perhaps
-you want to ignore actions that are not relevant for this reducer.
a way to convert a global action into a local action, but it’s optional because maybe this
- reducer shouldn’t care about certain actions. Because actions are usually enums, you can switch
- over the enum and in case it’s nothing you care about, you simply return nil in the closure. If
- you don’t want to lift this reducer in terms of action, just provide the identity function
- { $0 } as input.
-
-
-
-
-
-
- stateGetter
-
-
-
-
-
a way to read from a global state and extract only the part that it’s relevant for this reducer,
- by traversing the tree of the global state until you find the property you want, for example:
- { $0.currentGame.scoreBoard }
-
-
-
-
-
-
- stateSetter
-
-
-
-
-
a way to write back into the global state once you finished reducing the Part, so now you have
- a new part that was calculated by this reducer and you want to set it into the global state, also
- provided as the first parameter as an inout property:
- { globalState, newScoreBoard in globalState.currentGame.scoreBoard = newScoreBoard }
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<GlobalAction, GlobalState> that maps actions and states from the original specialised
- reducer into a more generic and global reducer, to be used in a larger context.
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is a property of Whole (MyGlobalState). This relationship could be less
-direct, for example there could be several levels of properties until you find the Part in the Whole, like
-global.firstLevel.secondLevel.currentLocation, but let’s keep it a single-level for this example.
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must lift the Reducer to the Whole level, by using:
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
-
-
Same strategy works for the action, as you can guess by the action KeyPath parameter. You can provide a KeyPath
-that takes a global action (Whole) and returns an optional local action (Part). It’s optional because perhaps
-you want to ignore actions that are not relevant for this reducer.
a read-only key-path from global action into a local action, but it’s optional because maybe this
- reducer shouldn’t care about certain actions. Because actions are usually enums, you can switch over
- the enum and in case it’s nothing you care about, you simply return nil in the closure. If you don’t
- want to lift this reducer in terms of action, just remove this parameter from the call.
-
-
-
-
-
-
- state
-
-
-
-
-
a writable key-path from global state that traverses into a local state, by extracting only the part
- that it’s relevant for this reducer. This will also be used to set the new local state into the global
- state once the reducer finishes it’s operation. For example: \.currentGame.scoreBoard.
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<GlobalAction, GlobalState> that maps actions and states from the original specialised
- reducer into a more generic and global reducer, to be used in a larger context.
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is a property of Whole (MyGlobalState). This relationship could be less
-direct, for example there could be several levels of properties until you find the Part in the Whole, like
-global.firstLevel.secondLevel.currentLocation, but let’s keep it a single-level for this example.
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must lift the Reducer to the Whole level, by using:
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
-
-
Same strategy works for the action, as you can guess by the action KeyPath parameter. You can provide a KeyPath
-that takes a global action (Whole) and returns an optional local action (Part). It’s optional because perhaps
-you want to ignore actions that are not relevant for this reducer.
a writable key-path from global state that traverses into a local state, by extracting only the part
- that it’s relevant for this reducer. This will also be used to set the new local state into the global
- state once the reducer finishes it’s operation. For example: \.currentGame.scoreBoard.
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<ActionType, GlobalState> that maps actions and states from the original specialized
- reducer into a more generic and global reducer, to be used in a larger context.
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is a property of Whole (MyGlobalState). This relationship could be less
-direct, for example there could be several levels of properties until you find the Part in the Whole, like
-global.firstLevel.secondLevel.currentLocation, but let’s keep it a single-level for this example.
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must lift the Reducer to the Whole level, by using:
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
-
-
Same strategy works for the action, as you can guess by the action KeyPath parameter. You can provide a KeyPath
-that takes a global action (Whole) and returns an optional local action (Part). It’s optional because perhaps
-you want to ignore actions that are not relevant for this reducer.
a read-only key-path from global action into a local action, but it’s optional because maybe this
- reducer shouldn’t care about certain actions. Because actions are usually enums, you can switch over
- the enum and in case it’s nothing you care about, you simply return nil in the closure. If you don’t
- want to lift this reducer in terms of action, just remove this parameter from the call.
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<GlobalAction, StateType> that maps actions and states from the original specialized
- reducer into a more generic and global reducer, to be used in a larger context.
A type-lifting method for collections. The global state of your app is Whole, and the Reducer handles an element
-that is inside of a collection, which itself is sub-state of the global. Let’s call this single element Part.
-
-
Let’s suppose you may want to have a gpsReducer that knows about the following struct:
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is an element of the array knownLocations, which is property of Whole
-(MyGlobalState). This relationship could be less direct, for example there could be several levels of properties
-until you find the Part in the Whole, like global.firstLevel.secondLevel.knownLocations, but let’s keep it a
-single-level for this example.
-
-
To resolve this single element, we not only have to find the path to the array, but we have to find the element
-inside of the array. There are three methods for doing so:
-1) the element is Identifiable (iOS 13 or later)
-2) the element has a Hashable property that makes it unique, so we can find it in the array using this identifier
-3) using the index of the element in the array
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must liftToCollection the Reducer to the Whole level, by using:
Different from simple lift to scalar, this one requires necessarily that you lift the action together with the state.
-That’s because your action has to contain the ID or Index of the element we will modify. The actionMap KeyPath has to
-give us a tuple of either:
-
-
-
(id, actionToSingleElement)
-
(index, actionToSingleElement)
-
-
-
The id or index is gonna be how we will search the array for the desired element, and only if we find it, we will run
-the gpsReducer for that specific element, using the action that has to do with single elements only.
-
-
As Location doesn’t have an id property we will have to either use index, implement Identifiable protocol or
-give another unique and Hashable property.
-
-
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
a read-only key-path from global action into a tuple: (id, local action), but it’s optional because
- maybe this reducer shouldn’t care about certain actions.
-
-
-
-
-
-
- stateCollection
-
-
-
-
-
a writable key-path from global state that traverses into a local state, by extracting only
- the part that it’s relevant for this reducer. This part needs to be a MutableCollection.
-
-
-
-
-
-
- identifier
-
-
-
-
-
a key-path to define who is the unique-identifier of the Element (it has to be Hashable)
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<GlobalAction, GlobalState> that maps actions and states from the original local reducer, which
- is specialised in a single Element, into a more generic and global reducer, to be used in a larger context.
A type-lifting method for collections. The global state of your app is Whole, and the Reducer handles an element
-that is inside of a collection, which itself is sub-state of the global. Let’s call this single element Part.
-
-
Let’s suppose you may want to have a gpsReducer that knows about the following struct:
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is an element of the array knownLocations, which is property of Whole
-(MyGlobalState). This relationship could be less direct, for example there could be several levels of properties
-until you find the Part in the Whole, like global.firstLevel.secondLevel.knownLocations, but let’s keep it a
-single-level for this example.
-
-
To resolve this single element, we not only have to find the path to the array, but we have to find the element
-inside of the array. There are three methods for doing so:
-1) the element is Identifiable (iOS 13 or later)
-2) the element has a Hashable property that makes it unique, so we can find it in the array using this identifier
-3) using the index of the element in the array
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must liftToCollection the Reducer to the Whole level, by using:
Different from simple lift to scalar, this one requires necessarily that you lift the action together with the state.
-That’s because your action has to contain the ID or Index of the element we will modify. The actionMap KeyPath has to
-give us a tuple of either:
-
-
-
(id, actionToSingleElement)
-
(index, actionToSingleElement)
-
-
-
The id or index is gonna be how we will search the array for the desired element, and only if we find it, we will run
-the gpsReducer for that specific element, using the action that has to do with single elements only.
-
-
As Location doesn’t have an id property we will have to either use index, implement Identifiable protocol or
-give another unique and Hashable property.
-
-
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
a read-only key-path from global action into a tuple: (index, local action), but it’s optional because
- maybe this reducer shouldn’t care about certain actions.
-
-
-
-
-
-
- stateCollection
-
-
-
-
-
a writable key-path from global state that traverses into a local state, by extracting only
- the part that it’s relevant for this reducer. This part needs to be a MutableCollection.
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<GlobalAction, GlobalState> that maps actions and states from the original local reducer, which
- is specialised in a single Element, into a more generic and global reducer, to be used in a larger context.
A type-lifting method for collections. The global state of your app is Whole, and the Reducer handles an element
-that is inside of a collection, which itself is sub-state of the global. Let’s call this single element Part.
-
-
Let’s suppose you may want to have a gpsReducer that knows about the following struct:
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is an element of the array knownLocations, which is property of Whole
-(MyGlobalState). This relationship could be less direct, for example there could be several levels of properties
-until you find the Part in the Whole, like global.firstLevel.secondLevel.knownLocations, but let’s keep it a
-single-level for this example.
-
-
To resolve this single element, we not only have to find the path to the array, but we have to find the element
-inside of the array. There are three methods for doing so:
-1) the element is Identifiable (iOS 13 or later)
-2) the element has a Hashable property that makes it unique, so we can find it in the array using this identifier
-3) using the index of the element in the array
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must liftToCollection the Reducer to the Whole level, by using:
Different from simple lift to scalar, this one requires necessarily that you lift the action together with the state.
-That’s because your action has to contain the ID or Index of the element we will modify. The actionMap KeyPath has to
-give us a tuple of either:
-
-
-
(id, actionToSingleElement)
-
(index, actionToSingleElement)
-
-
-
The id or index is gonna be how we will search the array for the desired element, and only if we find it, we will run
-the gpsReducer for that specific element, using the action that has to do with single elements only.
-
-
As Location doesn’t have an id property we will have to either use index, implement Identifiable protocol or
-give another unique and Hashable property.
-
-
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
a read-only key-path from global action into a tuple: (id, local action), but it’s optional because
- maybe this reducer shouldn’t care about certain actions.
-
-
-
-
-
-
- stateCollection
-
-
-
-
-
a writable key-path from global state that traverses into a local state, by extracting only
- the part that it’s relevant for this reducer. This part needs to be a MutableCollection.
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<GlobalAction, GlobalState> that maps actions and states from the original local reducer, which
- is specialised in a single Element, into a more generic and global reducer, to be used in a larger context.
An entity that calculates the new state when given current state and an incoming action (Action, inout State) -> Void.
-
-
An app triggers several actions over time, either coming from user input (button tap, scroll, pinch gesture), from sensors (CoreLocation, NFC,
-HealthKit), communication protocols (CoreBluetooth, networking, WebSocket), databases (CoreData, Realm), timers and many more.
-An app also starts with an initial state, right after its cold launch.
-For each action that arrives, the state can be modified, and this is exactly what a Reducer does: folds all actions that arrived since the app
-launch, plus the initial state, into the current state. One at the time.
-The shape of a Reducer could be represented as (Action, State) -> State, or given the incoming action and the latest known state, calculate the
-new state.
-For the sake of performance, and keeping the same semantics, the SwiftRex Reducer is represented as (Action, inout State) -> Void, avoiding
-unnecessary copies and allowing performance tuning for arrays or other big collections.
-A Reducer can focus in a small part, and be composed with other reducers. The order of this composition matters, because the state will be modified
-in the order as the reducers were composed, but you should avoid two reducers changing the same domain. If you can’t avoid, mind the order.
-A Reducer can also focus in a subset of your full AppAction and AppState, and be “lifted” from the subset to the whole, for example it’s focused on
-LoginAction and LoginState, then lifted to the whole AppAction and AppState by providing the KeyPath where the subset LoginAction is in the
-AppAction, and where the subset LoginState is in the AppState.
An entity that calculates the new state when given current state and an incoming action (Action, inout State) -> Void.
-
-
An app triggers several actions over time, either coming from user input (button tap, scroll, pinch gesture), from sensors (CoreLocation, NFC,
-HealthKit), communication protocols (CoreBluetooth, networking, WebSocket), databases (CoreData, Realm), timers and many more.
-An app also starts with an initial state, right after its cold launch.
-For each action that arrives, the state can be modified, and this is exactly what a Reducer does: folds all actions that arrived since the app
-launch, plus the initial state, into the current state. One at the time.
-The shape of a Reducer could be represented as (Action, State) -> State, or given the incoming action and the latest known state, calculate the
-new state.
-For the sake of performance, and keeping the same semantics, the SwiftRex Reducer is represented as (Action, inout State) -> Void, avoiding
-unnecessary copies and allowing performance tuning for arrays or other big collections.
-A Reducer can focus in a small part, and be composed with other reducers. The order of this composition matters, because the state will be modified
-in the order as the reducers were composed, but you should avoid two reducers changing the same domain. If you can’t avoid, mind the order.
-A Reducer can also focus in a subset of your full AppAction and AppState, and be “lifted” from the subset to the whole, for example it’s focused on
-LoginAction and LoginState, then lifted to the whole AppAction and AppState by providing the KeyPath where the subset LoginAction is in the
-AppAction, and where the subset LoginState is in the AppState.
Execute the wrapped reduce function. You must provide the parameters action: ActionType (the action to be
-evaluated during the reducing process) and an inout version of the latest state: StateType, (the current
-state in your single source-of-truth).
-State will be mutated in place (inout) and finish with the calculated new state.
Composes two or more reducers in series, to be evaluated from the left to the right for each incoming action.
-
-
When composing reducer A with reducer B, when an action X arrives, first it will be forwarded to
-reducer A together with the initial state. This reducer may return a slightly (or completely) changed state from
-that operation, and this state will then be forwarded to reducer B together with the same action X. If you change
-the order, results may vary as you can imagine. Monoids don’t necessarily hold the commutative axiom, although
-sometimes they do. What they necessarily hold is the associativity axiom, which means that if you compose A and B,
-and later C, it’s exactly the same as if you compose A to a previously composed B and C:
-.compose(.compose(A, B), C) == .compose(A, .compose(B, C)). So please don’t worry about surrounding your reducers with parenthesis:
Composes two or more reducers in series, to be evaluated from the top to the bottom for each incoming action.
-
-
When composing reducer A with reducer B, when an action X arrives, first it will be forwarded to
-reducer A together with the initial state. This reducer may return a slightly (or completely) changed state from
-that operation, and this state will then be forwarded to reducer B together with the same action X. If you change
-the order, results may vary as you can imagine. Monoids don’t necessarily hold the commutative axiom, although
-sometimes they do.
No-op reducer. Composing it with any other reducer will not change anything from the other reducer behaviour, regardless if the identity reducer
-is on the left-hand side or the right-hand side or this composition. This is the neutral element in a monoidal composition.
This is useful for composition purposes, for example when you call a function Array.reduce in an array of Reducers and you need a no-op start:
-
[reducer1,reducer2].reduce(.identity){accumulator,nextReducerin
- Reducer.compose(accumulator,nextReducer)
-}
-// .identity won't have any behaviour and the final composition ".identity >>> reducer1, reducer2" will be as if .identity wasn't there.
-
-
-
The implementation of this reducer, as one should expect, simply ignores the action and returns the state unchanged
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is a property of Whole (MyGlobalState). This relationship could be less
-direct, for example there could be several levels of properties until you find the Part in the Whole, like
-global.firstLevel.secondLevel.currentLocation, but let’s keep it a single-level for this example.
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must lift the Reducer to the Whole level, by using:
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
-
-
Same strategy works for the action, as you can guess by the actionGetter parameter. You can provide a function
-that takes a global action (Whole) and returns an optional local action (Part). It’s optional because perhaps
-you want to ignore actions that are not relevant for this reducer.
a way to convert a global action into a local action, but it’s optional because maybe this
- reducer shouldn’t care about certain actions. Because actions are usually enums, you can switch
- over the enum and in case it’s nothing you care about, you simply return nil in the closure. If
- you don’t want to lift this reducer in terms of action, just provide the identity function
- { $0 } as input.
-
-
-
-
-
-
- stateGetter
-
-
-
-
-
a way to read from a global state and extract only the part that it’s relevant for this reducer,
- by traversing the tree of the global state until you find the property you want, for example:
- { $0.currentGame.scoreBoard }
-
-
-
-
-
-
- stateSetter
-
-
-
-
-
a way to write back into the global state once you finished reducing the Part, so now you have
- a new part that was calculated by this reducer and you want to set it into the global state, also
- provided as the first parameter as an inout property:
- { globalState, newScoreBoard in globalState.currentGame.scoreBoard = newScoreBoard }
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<GlobalAction, GlobalState> that maps actions and states from the original specialised
- reducer into a more generic and global reducer, to be used in a larger context.
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is a property of Whole (MyGlobalState). This relationship could be less
-direct, for example there could be several levels of properties until you find the Part in the Whole, like
-global.firstLevel.secondLevel.currentLocation, but let’s keep it a single-level for this example.
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must lift the Reducer to the Whole level, by using:
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
-
-
Same strategy works for the action, as you can guess by the action KeyPath parameter. You can provide a KeyPath
-that takes a global action (Whole) and returns an optional local action (Part). It’s optional because perhaps
-you want to ignore actions that are not relevant for this reducer.
a read-only key-path from global action into a local action, but it’s optional because maybe this
- reducer shouldn’t care about certain actions. Because actions are usually enums, you can switch over
- the enum and in case it’s nothing you care about, you simply return nil in the closure. If you don’t
- want to lift this reducer in terms of action, just remove this parameter from the call.
-
-
-
-
-
-
- state
-
-
-
-
-
a writable key-path from global state that traverses into a local state, by extracting only the part
- that it’s relevant for this reducer. This will also be used to set the new local state into the global
- state once the reducer finishes it’s operation. For example: \.currentGame.scoreBoard.
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<GlobalAction, GlobalState> that maps actions and states from the original specialised
- reducer into a more generic and global reducer, to be used in a larger context.
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is a property of Whole (MyGlobalState). This relationship could be less
-direct, for example there could be several levels of properties until you find the Part in the Whole, like
-global.firstLevel.secondLevel.currentLocation, but let’s keep it a single-level for this example.
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must lift the Reducer to the Whole level, by using:
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
-
-
Same strategy works for the action, as you can guess by the action KeyPath parameter. You can provide a KeyPath
-that takes a global action (Whole) and returns an optional local action (Part). It’s optional because perhaps
-you want to ignore actions that are not relevant for this reducer.
a writable key-path from global state that traverses into a local state, by extracting only the part
- that it’s relevant for this reducer. This will also be used to set the new local state into the global
- state once the reducer finishes it’s operation. For example: \.currentGame.scoreBoard.
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<ActionType, GlobalState> that maps actions and states from the original specialized
- reducer into a more generic and global reducer, to be used in a larger context.
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is a property of Whole (MyGlobalState). This relationship could be less
-direct, for example there could be several levels of properties until you find the Part in the Whole, like
-global.firstLevel.secondLevel.currentLocation, but let’s keep it a single-level for this example.
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must lift the Reducer to the Whole level, by using:
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
-
-
Same strategy works for the action, as you can guess by the action KeyPath parameter. You can provide a KeyPath
-that takes a global action (Whole) and returns an optional local action (Part). It’s optional because perhaps
-you want to ignore actions that are not relevant for this reducer.
a read-only key-path from global action into a local action, but it’s optional because maybe this
- reducer shouldn’t care about certain actions. Because actions are usually enums, you can switch over
- the enum and in case it’s nothing you care about, you simply return nil in the closure. If you don’t
- want to lift this reducer in terms of action, just remove this parameter from the call.
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<GlobalAction, StateType> that maps actions and states from the original specialized
- reducer into a more generic and global reducer, to be used in a larger context.
A type-lifting method for collections. The global state of your app is Whole, and the Reducer handles an element
-that is inside of a collection, which itself is sub-state of the global. Let’s call this single element Part.
-
-
Let’s suppose you may want to have a gpsReducer that knows about the following struct:
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is an element of the array knownLocations, which is property of Whole
-(MyGlobalState). This relationship could be less direct, for example there could be several levels of properties
-until you find the Part in the Whole, like global.firstLevel.secondLevel.knownLocations, but let’s keep it a
-single-level for this example.
-
-
To resolve this single element, we not only have to find the path to the array, but we have to find the element
-inside of the array. There are three methods for doing so:
-1) the element is Identifiable (iOS 13 or later)
-2) the element has a Hashable property that makes it unique, so we can find it in the array using this identifier
-3) using the index of the element in the array
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must liftToCollection the Reducer to the Whole level, by using:
Different from simple lift to scalar, this one requires necessarily that you lift the action together with the state.
-That’s because your action has to contain the ID or Index of the element we will modify. The actionMap KeyPath has to
-give us a tuple of either:
-
-
-
(id, actionToSingleElement)
-
(index, actionToSingleElement)
-
-
-
The id or index is gonna be how we will search the array for the desired element, and only if we find it, we will run
-the gpsReducer for that specific element, using the action that has to do with single elements only.
-
-
As Location doesn’t have an id property we will have to either use index, implement Identifiable protocol or
-give another unique and Hashable property.
-
-
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
a read-only key-path from global action into a tuple: (id, local action), but it’s optional because
- maybe this reducer shouldn’t care about certain actions.
-
-
-
-
-
-
- stateCollection
-
-
-
-
-
a writable key-path from global state that traverses into a local state, by extracting only
- the part that it’s relevant for this reducer. This part needs to be a MutableCollection.
-
-
-
-
-
-
- identifier
-
-
-
-
-
a key-path to define who is the unique-identifier of the Element (it has to be Hashable)
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<GlobalAction, GlobalState> that maps actions and states from the original local reducer, which
- is specialised in a single Element, into a more generic and global reducer, to be used in a larger context.
A type-lifting method for collections. The global state of your app is Whole, and the Reducer handles an element
-that is inside of a collection, which itself is sub-state of the global. Let’s call this single element Part.
-
-
Let’s suppose you may want to have a gpsReducer that knows about the following struct:
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is an element of the array knownLocations, which is property of Whole
-(MyGlobalState). This relationship could be less direct, for example there could be several levels of properties
-until you find the Part in the Whole, like global.firstLevel.secondLevel.knownLocations, but let’s keep it a
-single-level for this example.
-
-
To resolve this single element, we not only have to find the path to the array, but we have to find the element
-inside of the array. There are three methods for doing so:
-1) the element is Identifiable (iOS 13 or later)
-2) the element has a Hashable property that makes it unique, so we can find it in the array using this identifier
-3) using the index of the element in the array
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must liftToCollection the Reducer to the Whole level, by using:
Different from simple lift to scalar, this one requires necessarily that you lift the action together with the state.
-That’s because your action has to contain the ID or Index of the element we will modify. The actionMap KeyPath has to
-give us a tuple of either:
-
-
-
(id, actionToSingleElement)
-
(index, actionToSingleElement)
-
-
-
The id or index is gonna be how we will search the array for the desired element, and only if we find it, we will run
-the gpsReducer for that specific element, using the action that has to do with single elements only.
-
-
As Location doesn’t have an id property we will have to either use index, implement Identifiable protocol or
-give another unique and Hashable property.
-
-
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
a read-only key-path from global action into a tuple: (index, local action), but it’s optional because
- maybe this reducer shouldn’t care about certain actions.
-
-
-
-
-
-
- stateCollection
-
-
-
-
-
a writable key-path from global state that traverses into a local state, by extracting only
- the part that it’s relevant for this reducer. This part needs to be a MutableCollection.
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<GlobalAction, GlobalState> that maps actions and states from the original local reducer, which
- is specialised in a single Element, into a more generic and global reducer, to be used in a larger context.
A type-lifting method for collections. The global state of your app is Whole, and the Reducer handles an element
-that is inside of a collection, which itself is sub-state of the global. Let’s call this single element Part.
-
-
Let’s suppose you may want to have a gpsReducer that knows about the following struct:
Let’s call it Part. Both, this state and its reducer will be part of an external framework, used by dozens of
-apps. Internally probably the Reducer will receive some known ActionType and calculate a new location. On the
-main app we have a global state, that we now call Whole.
As expected, Part (Location) is an element of the array knownLocations, which is property of Whole
-(MyGlobalState). This relationship could be less direct, for example there could be several levels of properties
-until you find the Part in the Whole, like global.firstLevel.secondLevel.knownLocations, but let’s keep it a
-single-level for this example.
-
-
To resolve this single element, we not only have to find the path to the array, but we have to find the element
-inside of the array. There are three methods for doing so:
-1) the element is Identifiable (iOS 13 or later)
-2) the element has a Hashable property that makes it unique, so we can find it in the array using this identifier
-3) using the index of the element in the array
-
-
Because our Store understands Whole (MyGlobalState) and our gpsReducer understands Part (Location), we
-must liftToCollection the Reducer to the Whole level, by using:
Different from simple lift to scalar, this one requires necessarily that you lift the action together with the state.
-That’s because your action has to contain the ID or Index of the element we will modify. The actionMap KeyPath has to
-give us a tuple of either:
-
-
-
(id, actionToSingleElement)
-
(index, actionToSingleElement)
-
-
-
The id or index is gonna be how we will search the array for the desired element, and only if we find it, we will run
-the gpsReducer for that specific element, using the action that has to do with single elements only.
-
-
As Location doesn’t have an id property we will have to either use index, implement Identifiable protocol or
-give another unique and Hashable property.
-
-
Now this reducer can be used within our Store or even composed with others. It also can be used in other apps as
-long as we have a way to lift it to the world of Whole.
a read-only key-path from global action into a tuple: (id, local action), but it’s optional because
- maybe this reducer shouldn’t care about certain actions.
-
-
-
-
-
-
- stateCollection
-
-
-
-
-
a writable key-path from global state that traverses into a local state, by extracting only
- the part that it’s relevant for this reducer. This part needs to be a MutableCollection.
-
-
-
-
-
-
-
-
Return Value
-
a Reducer<GlobalAction, GlobalState> that maps actions and states from the original local reducer, which
- is specialised in a single Element, into a more generic and global reducer, to be used in a larger context.
- Unidirectional Dataflow for your favourite reactive framework
-
-
-
-
-
-
-
-
-
-
-
-
If you’ve got questions, about SwiftRex or redux and Functional Programming in general, please Join our Slack Channel.
-
SwiftRex
-
-
This is part of “SwiftRex library”. Please read the library documentation to have full context about what Reducer is used for.
-
-
SwiftRex is a framework that combines Unidirectional Dataflow architecture and reactive programming (Combine, RxSwift or ReactiveSwift), providing a central state Store for the whole state of your app, of which your SwiftUI Views or UIViewControllers can observe and react to, as well as dispatching events coming from the user interactions.
-
-
This pattern, also known as “Redux”, allows us to rethink our app as a single pure function that receives user events as input and returns UI changes in response. The benefits of this workflow will hopefully become clear soon.
Reducer is a pure function wrapped in a monoid container, that takes an action and the current state to calculate the new state.
-
-
The MiddlewareProtocol pipeline can do two things: dispatch outgoing actions and handling incoming actions. But what they can NOT do is changing the app state. Middlewares have read-only access to the up-to-date state of our apps, but when mutations are required we use the MutableReduceFunction function:
-
(ActionType,inoutStateType)->Void
-
-
-
Which has the same semantics (but better performance) than old ReduceFunction:
-
(ActionType,StateType)->StateType
-
-
-
Given an action and the current state (as a mutable inout), it calculates the new state and changes it:
-
initial state is 42
-action: increment
-reducer: increment 42 => new state 43
-
-current state is 43
-action: decrement
-reducer: decrement 43 => new state 42
-
-current state is 42
-action: half
-reducer: half 42 => new state 21
-
-
-
The function is reducing all the actions in a cached state, and that happens incrementally for each new incoming action.
-
-
It’s important to understand that reducer is a synchronous operations that calculates a new state without any kind of side-effect (including non-obvious ones as creating Date(), using DispatchQueue or Locale.current), so never add properties to the Reducer structs or call any external function. If you are tempted to do that, please create a middleware and dispatch actions with Dates or Locales from it.
-
-
Reducers are also responsible for keeping the consistency of a state, so it’s always good to do a final sanity check before changing the state, like for example check other dependant properties that must be changed together.
-
-
Once the reducer function executes, the store will update its single source-of-truth with the new calculated state, and propagate it to all its subscribers, that will react to the new state and update Views, for example.
-
-
This function is wrapped in a struct to overcome some Swift limitations, for example, allowing us to compose multiple reducers into one (monoid operation, where two or more reducers become a single one) or lifting reducers from local types to global types.
-
-
The ability to lift reducers allow us to write fine-grained “sub-reducer” that will handle only a subset of the state and/or action, place it in different frameworks and modules, and later plugged into a bigger state and action handler by providing a way to map state and actions between the global and local ones. For more information about that, please check Lifting.
Please notice from the example above the following good practices:
-
-
-
No DispatchQueue, threading, operation queue, promises, reactive code in there.
-
All you need to implement this function is provided by the arguments action and currentState, don’t use any other variable coming from global scope, not even for reading purposes. If you need something else, it should either be in the state or come in the action payload.
-
Do not start side-effects, requests, I/O, database calls.
-
Avoid default when writing switch/case statements. That way the compiler will help you more.
-
Make the action and the state generic parameters as much specialised as you can. If volume state is part of a bigger state, you should not be tempted to pass the whole big state into this reducer. Make it short, brief and specialised, this also helps preventing default case or having to re-assign properties that are never mutated by this reducer.
An app can be a complex product, performing several activities that not necessarily are related. For example, the same app may need to perform a request to a weather API, check the current user location using CLLocation and read preferences from UserDefaults.
-
-
Although these activities are combined to create the full experience, they can be isolated from each other in order to avoid URLSession logic and CLLocation logic in the same place, competing for the same resources and potentially causing race conditions. Also, testing these parts in isolation is often easier and leads to more significant tests.
-
-
Ideally we should organise our AppState and AppAction to account for these parts as isolated trees. In the example above, we could have 3 different properties in our AppState and 3 different enum cases in our AppAction to group state and actions related to the weather API, to the user location and to the UserDefaults access.
-
-
This gets even more helpful in case we split our app in 3 types of Reducer and 3 types of MiddlewareProtocol, and each of them work not on the full AppState and AppAction, but in the 3 paths we grouped in our model. The first pair of Reducer and MiddlewareProtocol would be generic over WeatherState and WeatherAction, the second pair over LocationState and LocationAction and the third pair over RepositoryState and RepositoryAction. They could even be in different frameworks, so the compiler will forbid us from coupling Weather API code with CLLocation code, which is great as this enforces better practices and unlocks code reusability. Maybe our CLLocation middleware/reducer can be useful in a completely different app that checks for public transport routes.
-
-
But at some point we want to put these 3 different types of entities together, and the StoreType of our app “speaks” AppAction and AppState, not the subsets used by the specialised handlers.
Given a reducer that is generic over WeatherAction and WeatherState, we can “lift” it to the global types AppAction and AppState by telling this reducer how to find in the global tree the properties that it needs. That would be \AppAction.weather and \AppState.weather. The same can be done for the middleware, and for the other 2 reducers and middlewares of our app.
-
-
When all of them are lifted to a common type, they can be combined together using Reducer.compose(reducer1, reducer2, reducer3...) function, or the DSL form:
IMPORTANT: Because enums in Swift don’t have KeyPath as structs do, we strongly recommend reading Action Enum Properties document and implementing properties for each case, either manually or using code generators, so later you avoid writing lots and lots of error-prone switch/case. We also offer some templates to help you on that.
-
-
-
Let’s explore how to lift reducers and middlewares.
-
Lifting Reducer
-
-
Reducer has AppAction INPUT, AppState INPUT and AppState OUTPUT, because it can only handle actions (never dispatch them), read the state and write the state.
.lift(
- actionGetter:{(action:AppAction)->ReducerAction?/* type 1 */in
- // prism3 has associated value of ReducerAction,
- // and whole thing is Optional because Prism is always optional
- action.prism1?.prism2?.prism3
- },
- stateGetter:{(state:AppState)->ReducerState/* type 2 */in
- // property2: ReducerState
- state.property1.property2
- },
- stateSetter:{(state:inoutAppState,newValue:ReducerState/* type 2 */)->Voidin
- // property2: ReducerState
- state.property1.property2=newValue
- }
-)
-
-
-
Steps:
-
-
-
Start plugging the 2 types from the Reducer into the 3 closure headers.
-
For type 1, find a prism that resolves from AppAction into the matching type. BE SURE TO RUN SOURCERY AND HAVING ALL ENUM CASES COVERED BY PRISM
-
For type 2 on the stateGetter closure, find lenses (property getters) that resolve from AppState into the matching type.
-
For type 2 on the stateSetter closure, find lenses (property setters) that can change the global state receive to the newValue received. Be sure that everything is writeable.
Execute the wrapped reduce function. You must provide the parameters action: ActionType (the action to be","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV6reduceyAByxq_Gyx_q_ztcFZ":{"name":"reduce(_:)","abstract":"
Reducer initialiser takes only the underlying function (ActionType, inout StateType) -> Void that is the reducer","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV7composeyAByxq_GAD_ADdtFZ":{"name":"compose(_:_:)","abstract":"
Composes two or more reducers in series, to be evaluated from the left to the right for each incoming action.
No-op reducer. Composing it with any other reducer will not change anything from the other reducer behaviour, regardless if the identity reducer","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF":{"name":"lift(actionGetter:stateGetter:stateSetter:)","abstract":"
A type-lifting method. The global state of your app is Whole, and the Reducer handles Part, that is a","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF":{"name":"lift(action:state:)","abstract":"
A type-lifting method. The global state of your app is Whole, and the Reducer handles Part, that is a","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV4lift5stateAByxqd__Gs15WritableKeyPathCyqd__q_G_tlF":{"name":"lift(state:)","abstract":"
A type-lifting method. The global state of your app is Whole, and the Reducer handles Part, that is a","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV4lift6actionAByqd__q_Gs7KeyPathCyqd__xSgG_tlF":{"name":"lift(action:)","abstract":"
A type-lifting method. The global state of your app is Whole, and the Reducer handles Part, that is a","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF":{"name":"liftToCollection(action:stateCollection:identifier:)","abstract":"
A type-lifting method for collections. The global state of your app is Whole, and the Reducer handles an element","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF":{"name":"liftToCollection(action:stateCollection:)","abstract":"
A type-lifting method for collections. The global state of your app is Whole, and the Reducer handles an element","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF":{"name":"liftToCollection(action:stateCollection:)","abstract":"
A type-lifting method for collections. The global state of your app is Whole, and the Reducer handles an element","parent_name":"Reducer"},"Structs/Reducer.html":{"name":"Reducer","abstract":"
An entity that calculates the new state when given current state and an incoming action (Action, inout State) -> Void.
- Unidirectional Dataflow for your favourite reactive framework
-
-
-
-
-
-
-
-
-
-
-
-
If you’ve got questions, about SwiftRex or redux and Functional Programming in general, please Join our Slack Channel.
-
SwiftRex
-
-
This is part of “SwiftRex library”. Please read the library documentation to have full context about what Reducer is used for.
-
-
SwiftRex is a framework that combines Unidirectional Dataflow architecture and reactive programming (Combine, RxSwift or ReactiveSwift), providing a central state Store for the whole state of your app, of which your SwiftUI Views or UIViewControllers can observe and react to, as well as dispatching events coming from the user interactions.
-
-
This pattern, also known as “Redux”, allows us to rethink our app as a single pure function that receives user events as input and returns UI changes in response. The benefits of this workflow will hopefully become clear soon.
Reducer is a pure function wrapped in a monoid container, that takes an action and the current state to calculate the new state.
-
-
The MiddlewareProtocol pipeline can do two things: dispatch outgoing actions and handling incoming actions. But what they can NOT do is changing the app state. Middlewares have read-only access to the up-to-date state of our apps, but when mutations are required we use the MutableReduceFunction function:
-
(ActionType,inoutStateType)->Void
-
-
-
Which has the same semantics (but better performance) than old ReduceFunction:
-
(ActionType,StateType)->StateType
-
-
-
Given an action and the current state (as a mutable inout), it calculates the new state and changes it:
-
initial state is 42
-action: increment
-reducer: increment 42 => new state 43
-
-current state is 43
-action: decrement
-reducer: decrement 43 => new state 42
-
-current state is 42
-action: half
-reducer: half 42 => new state 21
-
-
-
The function is reducing all the actions in a cached state, and that happens incrementally for each new incoming action.
-
-
It’s important to understand that reducer is a synchronous operations that calculates a new state without any kind of side-effect (including non-obvious ones as creating Date(), using DispatchQueue or Locale.current), so never add properties to the Reducer structs or call any external function. If you are tempted to do that, please create a middleware and dispatch actions with Dates or Locales from it.
-
-
Reducers are also responsible for keeping the consistency of a state, so it’s always good to do a final sanity check before changing the state, like for example check other dependant properties that must be changed together.
-
-
Once the reducer function executes, the store will update its single source-of-truth with the new calculated state, and propagate it to all its subscribers, that will react to the new state and update Views, for example.
-
-
This function is wrapped in a struct to overcome some Swift limitations, for example, allowing us to compose multiple reducers into one (monoid operation, where two or more reducers become a single one) or lifting reducers from local types to global types.
-
-
The ability to lift reducers allow us to write fine-grained “sub-reducer” that will handle only a subset of the state and/or action, place it in different frameworks and modules, and later plugged into a bigger state and action handler by providing a way to map state and actions between the global and local ones. For more information about that, please check Lifting.
Please notice from the example above the following good practices:
-
-
-
No DispatchQueue, threading, operation queue, promises, reactive code in there.
-
All you need to implement this function is provided by the arguments action and currentState, don’t use any other variable coming from global scope, not even for reading purposes. If you need something else, it should either be in the state or come in the action payload.
-
Do not start side-effects, requests, I/O, database calls.
-
Avoid default when writing switch/case statements. That way the compiler will help you more.
-
Make the action and the state generic parameters as much specialised as you can. If volume state is part of a bigger state, you should not be tempted to pass the whole big state into this reducer. Make it short, brief and specialised, this also helps preventing default case or having to re-assign properties that are never mutated by this reducer.
An app can be a complex product, performing several activities that not necessarily are related. For example, the same app may need to perform a request to a weather API, check the current user location using CLLocation and read preferences from UserDefaults.
-
-
Although these activities are combined to create the full experience, they can be isolated from each other in order to avoid URLSession logic and CLLocation logic in the same place, competing for the same resources and potentially causing race conditions. Also, testing these parts in isolation is often easier and leads to more significant tests.
-
-
Ideally we should organise our AppState and AppAction to account for these parts as isolated trees. In the example above, we could have 3 different properties in our AppState and 3 different enum cases in our AppAction to group state and actions related to the weather API, to the user location and to the UserDefaults access.
-
-
This gets even more helpful in case we split our app in 3 types of Reducer and 3 types of MiddlewareProtocol, and each of them work not on the full AppState and AppAction, but in the 3 paths we grouped in our model. The first pair of Reducer and MiddlewareProtocol would be generic over WeatherState and WeatherAction, the second pair over LocationState and LocationAction and the third pair over RepositoryState and RepositoryAction. They could even be in different frameworks, so the compiler will forbid us from coupling Weather API code with CLLocation code, which is great as this enforces better practices and unlocks code reusability. Maybe our CLLocation middleware/reducer can be useful in a completely different app that checks for public transport routes.
-
-
But at some point we want to put these 3 different types of entities together, and the StoreType of our app “speaks” AppAction and AppState, not the subsets used by the specialised handlers.
Given a reducer that is generic over WeatherAction and WeatherState, we can “lift” it to the global types AppAction and AppState by telling this reducer how to find in the global tree the properties that it needs. That would be \AppAction.weather and \AppState.weather. The same can be done for the middleware, and for the other 2 reducers and middlewares of our app.
-
-
When all of them are lifted to a common type, they can be combined together using Reducer.compose(reducer1, reducer2, reducer3...) function, or the DSL form:
IMPORTANT: Because enums in Swift don’t have KeyPath as structs do, we strongly recommend reading Action Enum Properties document and implementing properties for each case, either manually or using code generators, so later you avoid writing lots and lots of error-prone switch/case. We also offer some templates to help you on that.
-
-
-
Let’s explore how to lift reducers and middlewares.
-
Lifting Reducer
-
-
Reducer has AppAction INPUT, AppState INPUT and AppState OUTPUT, because it can only handle actions (never dispatch them), read the state and write the state.
.lift(
- actionGetter:{(action:AppAction)->ReducerAction?/* type 1 */in
- // prism3 has associated value of ReducerAction,
- // and whole thing is Optional because Prism is always optional
- action.prism1?.prism2?.prism3
- },
- stateGetter:{(state:AppState)->ReducerState/* type 2 */in
- // property2: ReducerState
- state.property1.property2
- },
- stateSetter:{(state:inoutAppState,newValue:ReducerState/* type 2 */)->Voidin
- // property2: ReducerState
- state.property1.property2=newValue
- }
-)
-
-
-
Steps:
-
-
-
Start plugging the 2 types from the Reducer into the 3 closure headers.
-
For type 1, find a prism that resolves from AppAction into the matching type. BE SURE TO RUN SOURCERY AND HAVING ALL ENUM CASES COVERED BY PRISM
-
For type 2 on the stateGetter closure, find lenses (property getters) that resolve from AppState into the matching type.
-
For type 2 on the stateSetter closure, find lenses (property setters) that can change the global state receive to the newValue received. Be sure that everything is writeable.
Execute the wrapped reduce function. You must provide the parameters action: ActionType (the action to be","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV6reduceyAByxq_Gyx_q_ztcFZ":{"name":"reduce(_:)","abstract":"
Reducer initialiser takes only the underlying function (ActionType, inout StateType) -> Void that is the reducer","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV7composeyAByxq_GAD_ADdtFZ":{"name":"compose(_:_:)","abstract":"
Composes two or more reducers in series, to be evaluated from the left to the right for each incoming action.
No-op reducer. Composing it with any other reducer will not change anything from the other reducer behaviour, regardless if the identity reducer","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF":{"name":"lift(actionGetter:stateGetter:stateSetter:)","abstract":"
A type-lifting method. The global state of your app is Whole, and the Reducer handles Part, that is a","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF":{"name":"lift(action:state:)","abstract":"
A type-lifting method. The global state of your app is Whole, and the Reducer handles Part, that is a","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV4lift5stateAByxqd__Gs15WritableKeyPathCyqd__q_G_tlF":{"name":"lift(state:)","abstract":"
A type-lifting method. The global state of your app is Whole, and the Reducer handles Part, that is a","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV4lift6actionAByqd__q_Gs7KeyPathCyqd__xSgG_tlF":{"name":"lift(action:)","abstract":"
A type-lifting method. The global state of your app is Whole, and the Reducer handles Part, that is a","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF":{"name":"liftToCollection(action:stateCollection:identifier:)","abstract":"
A type-lifting method for collections. The global state of your app is Whole, and the Reducer handles an element","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF":{"name":"liftToCollection(action:stateCollection:)","abstract":"
A type-lifting method for collections. The global state of your app is Whole, and the Reducer handles an element","parent_name":"Reducer"},"Structs/Reducer.html#/s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF":{"name":"liftToCollection(action:stateCollection:)","abstract":"
A type-lifting method for collections. The global state of your app is Whole, and the Reducer handles an element","parent_name":"Reducer"},"Structs/Reducer.html":{"name":"Reducer","abstract":"
An entity that calculates the new state when given current state and an incoming action (Action, inout State) -> Void.
"}}
\ No newline at end of file
diff --git a/docs/api/Reducer/undocumented.json b/docs/api/Reducer/undocumented.json
deleted file mode 100644
index b637641..0000000
--- a/docs/api/Reducer/undocumented.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "warnings": [
-
- ],
- "source_directory": "/Users/luiz.barbosa/code/SwiftRex/Reducer"
-}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/css/documentation-topic.3bca6578.css b/docs/docc/Reducer.doccarchive/css/documentation-topic.3bca6578.css
deleted file mode 100644
index 3b8635a..0000000
--- a/docs/docc/Reducer.doccarchive/css/documentation-topic.3bca6578.css
+++ /dev/null
@@ -1,9 +0,0 @@
-/*!
- * This source file is part of the Swift.org open source project
- *
- * Copyright (c) 2021 Apple Inc. and the Swift project authors
- * Licensed under Apache License v2.0 with Runtime Library Exception
- *
- * See https://swift.org/LICENSE.txt for license information
- * See https://swift.org/CONTRIBUTORS.txt for Swift project authors
- */.betainfo[data-v-fe7602da]{font-size:.94118rem;padding:3rem 0;background-color:var(--color-fill-secondary)}.full-width-container .betainfo-container[data-v-fe7602da]{max-width:920px;margin-left:auto;margin-right:auto;padding-left:80px;padding-right:80px;box-sizing:border-box}@media only screen and (min-width:1251px){.full-width-container .betainfo-container[data-v-fe7602da]{box-sizing:unset;padding-left:120px;padding-right:120px;margin-left:0}}@media only screen and (max-width:735px){.full-width-container .betainfo-container[data-v-fe7602da]{width:auto;padding-left:20px;padding-right:20px}}.static-width-container .betainfo-container[data-v-fe7602da]{margin-left:auto;margin-right:auto;width:980px}@media only screen and (max-width:1250px){.static-width-container .betainfo-container[data-v-fe7602da]{width:692px}}@media only screen and (max-width:735px){.static-width-container .betainfo-container[data-v-fe7602da]{width:87.5%}}.betainfo-label[data-v-fe7602da]{font-weight:600;font-size:.94118rem}.betainfo-content[data-v-fe7602da] p{margin-bottom:10px}.contenttable+.betainfo[data-v-fe7602da]{background-color:var(--color-fill)}.summary-section[data-v-3aa6f694]:last-of-type{margin-right:0}@media only screen and (max-width:735px){.summary-section[data-v-3aa6f694]{margin-right:0}}.title[data-v-6796f6ea]{color:#fff;font-size:.82353rem;margin-right:.5rem;text-rendering:optimizeLegibility}.documentation-hero--disabled .title[data-v-6796f6ea]{color:var(--colors-text,var(--color-text))}.language[data-v-0de98d61]{padding-bottom:10px;justify-content:flex-end}.language-list[data-v-0de98d61],.language[data-v-0de98d61]{font-size:.82353rem;line-height:1.42857;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;margin-top:0;display:flex;align-items:center}.language-option.swift[data-v-0de98d61]{padding-right:10px;border-right:1px solid var(--color-fill-gray-tertiary)}.language-option.objc[data-v-0de98d61]{padding-left:10px}.language-option.active[data-v-0de98d61],.language-option.router-link-exact-active[data-v-0de98d61]{color:#ccc}.documentation-hero--disabled .language-option.active[data-v-0de98d61],.documentation-hero--disabled .language-option.router-link-exact-active[data-v-0de98d61]{color:var(--colors-secondary-label,var(--color-secondary-label))}.NavigatorLeafIcon[data-v-031bfabc]{width:1em;height:1em;margin-right:7px;flex:0 0 auto;color:var(--color-figure-gray-secondary)}.NavigatorLeafIcon svg[data-v-031bfabc]{width:100%;height:100%}.documentation-hero[data-v-14076498]{background:#000;color:#fff;overflow:hidden;text-align:left;position:relative}.documentation-hero[data-v-14076498]:before{content:"";background:#2a2a2a;position:absolute;width:100%;left:0;top:-50%;height:150%;right:0}.documentation-hero[data-v-14076498]:after{background:transparent;opacity:.7;width:100%;position:absolute;content:"";height:100%;left:0;top:0}.documentation-hero .icon[data-v-14076498]{position:absolute;margin-top:10px;margin-right:25px;right:0;width:250px;height:calc(100% - 20px);box-sizing:border-box}@media only screen and (max-width:735px){.documentation-hero .icon[data-v-14076498]{display:none}}.documentation-hero .background-icon[data-v-14076498]{color:#161616;display:block;width:250px;height:auto;opacity:1;position:absolute;top:50%;left:0;transform:translateY(-50%);max-height:100%}.documentation-hero .background-icon[data-v-14076498] svg{width:100%;height:100%}.documentation-hero__content[data-v-14076498]{padding-top:2.35294rem;padding-bottom:40px;position:relative;z-index:1}.full-width-container .documentation-hero__content[data-v-14076498]{max-width:920px;margin-left:auto;margin-right:auto;padding-left:80px;padding-right:80px;box-sizing:border-box}@media only screen and (min-width:1251px){.full-width-container .documentation-hero__content[data-v-14076498]{box-sizing:unset;padding-left:120px;padding-right:120px;margin-left:0}}@media only screen and (max-width:735px){.full-width-container .documentation-hero__content[data-v-14076498]{width:auto;padding-left:20px;padding-right:20px}}.static-width-container .documentation-hero__content[data-v-14076498]{margin-left:auto;margin-right:auto;width:980px}@media only screen and (max-width:1250px){.static-width-container .documentation-hero__content[data-v-14076498]{width:692px}}@media only screen and (max-width:735px){.static-width-container .documentation-hero__content[data-v-14076498]{width:87.5%}}.documentation-hero__above-content[data-v-14076498]{position:relative;z-index:1}.documentation-hero--disabled[data-v-14076498]{background:none;color:var(--colors-text,var(--color-text))}.documentation-hero--disabled[data-v-14076498]:after,.documentation-hero--disabled[data-v-14076498]:before{content:none}.short-hero[data-v-14076498]{padding-top:3.52941rem;padding-bottom:3.52941rem}.extra-bottom-padding[data-v-14076498]{padding-bottom:3.82353rem}.theme-dark[data-v-14076498] a:not(.button-cta){color:#09f}[data-v-002affcc] .code-listing{background:var(--background,var(--color-code-background));color:var(--text,var(--color-code-plain));border-color:var(--colors-grid,var(--color-grid));border-width:1px;border-style:solid}[data-v-002affcc]+.code-listing,[data-v-002affcc] .code-listing+*{margin-top:1.6em}[data-v-002affcc] .code-listing pre{padding:8px 14px;padding-right:0}[data-v-002affcc] .code-listing pre>code{font-size:.88235rem;line-height:1.66667;font-weight:400;font-family:Menlo,monospace}[data-v-002affcc] *+aside,[data-v-002affcc] *+figure,[data-v-002affcc]+.endpoint-example,[data-v-002affcc] .endpoint-example+*,[data-v-002affcc] aside+*,[data-v-002affcc] figure+*{margin-top:1.6em}[data-v-002affcc] img{display:block;margin:1.6em auto;max-width:100%}[data-v-002affcc] ol,[data-v-002affcc] ul{margin-top:.8em;margin-left:2rem}[data-v-002affcc] ol li:not(:first-child),[data-v-002affcc] ul li:not(:first-child){margin-top:.8em}@media only screen and (max-width:735px){[data-v-002affcc] ol,[data-v-002affcc] ul{margin-left:1.25rem}}[data-v-002affcc]+dl,[data-v-002affcc] dl+*,[data-v-002affcc] dt:not(:first-child){margin-top:.8em}[data-v-002affcc] dd{margin-left:2em}.abstract[data-v-702ec04e]{font-size:1.23529rem;line-height:1.38095;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:735px){.abstract[data-v-702ec04e]{font-size:1.11765rem;line-height:1.42105;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}[data-v-702ec04e] p:last-child{margin-bottom:0}.container[data-v-5a07ba83]{padding-bottom:40px}.full-width-container .container[data-v-5a07ba83]{max-width:920px;margin-left:auto;margin-right:auto;padding-left:80px;padding-right:80px;box-sizing:border-box}@media only screen and (min-width:1251px){.full-width-container .container[data-v-5a07ba83]{box-sizing:unset;padding-left:120px;padding-right:120px;margin-left:0}}@media only screen and (max-width:735px){.full-width-container .container[data-v-5a07ba83]{width:auto;padding-left:20px;padding-right:20px}}.static-width-container .container[data-v-5a07ba83]{margin-left:auto;margin-right:auto;width:980px}@media only screen and (max-width:1250px){.static-width-container .container[data-v-5a07ba83]{width:692px}}@media only screen and (max-width:735px){.static-width-container .container[data-v-5a07ba83]{width:87.5%}}.title[data-v-5a07ba83]{font-size:1.88235rem;line-height:1.125;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;padding-top:40px;border-top-color:var(--color-grid);border-top-style:solid;border-top-width:1px}@media only screen and (max-width:1250px){.title[data-v-5a07ba83]{font-size:1.64706rem;line-height:1.14286;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){.title[data-v-5a07ba83]{font-size:1.41176rem;line-height:1.16667;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.title+.contenttable-section[data-v-627ab5f4]{margin-top:0}.contenttable-section[data-v-627ab5f4]{align-items:baseline;padding-top:2.353rem}.contenttable-section[data-v-627ab5f4]:last-child{margin-bottom:0}[data-v-627ab5f4] .title{font-size:1.41176rem;line-height:1.16667;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:1250px){[data-v-627ab5f4] .title{font-size:1.23529rem;line-height:1.19048;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){.contenttable-section[data-v-627ab5f4]{align-items:unset;border-top:none;display:inherit;margin:0}.section-content[data-v-627ab5f4],.section-title[data-v-627ab5f4]{padding:0}[data-v-627ab5f4] .title{margin:0 0 2.353rem 0;padding-bottom:.5rem}}.badge[data-v-5a8ba4e0]{--badge-color:var(--color-badge-default);--badge-dark-color:var(--color-badge-dark-default);font-size:.70588rem;line-height:1.33333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;display:inline-block;padding:2px 10px;white-space:nowrap;background:none;border-radius:3px;margin-left:10px;border:1px solid var(--badge-color);color:var(--badge-color)}.theme-dark .badge[data-v-5a8ba4e0]{--badge-color:var(--badge-dark-color)}.badge-deprecated[data-v-5a8ba4e0]{--badge-color:var(--color-badge-deprecated);--badge-dark-color:var(--color-badge-dark-deprecated)}.badge-beta[data-v-5a8ba4e0]{--badge-color:var(--color-badge-beta);--badge-dark-color:var(--color-badge-dark-beta)}.topic-icon-wrapper[data-v-4d1e7968]{display:flex;align-items:center;justify-content:center;height:1.47059rem;flex:0 0 1.294rem;width:1.294rem;margin-right:1rem}.topic-icon[data-v-4d1e7968]{height:.88235rem;transform:scale(1);-webkit-transform:scale(1);overflow:visible}.topic-icon.curly-brackets-icon[data-v-4d1e7968]{height:1rem}.token-method[data-v-5caf1b5b]{font-weight:700}.token-keyword[data-v-5caf1b5b]{color:var(--syntax-keyword,var(--color-syntax-keywords))}.token-number[data-v-5caf1b5b]{color:var(--syntax-number,var(--color-syntax-numbers))}.token-string[data-v-5caf1b5b]{color:var(--syntax-string,var(--color-syntax-strings))}.token-attribute[data-v-5caf1b5b]{color:var(--syntax-attribute,var(--color-syntax-keywords))}.token-internalParam[data-v-5caf1b5b]{color:var(--color-syntax-param-internal-name)}.type-identifier-link[data-v-5caf1b5b]{color:var(--syntax-type,var(--color-syntax-other-type-names))}.token-removed[data-v-5caf1b5b]{background-color:var(--color-highlight-red)}.token-added[data-v-5caf1b5b]{background-color:var(--color-highlight-green)}.decorator[data-v-06ec7395],.label[data-v-06ec7395]{color:var(--colors-secondary-label,var(--color-secondary-label))}.label[data-v-06ec7395]{font-size:1rem;line-height:1.47059;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.empty-token[data-v-06ec7395]{font-size:0}.empty-token[data-v-06ec7395]:after{content:"\00a0";font-size:1rem}.conditional-constraints[data-v-1548fd90] code{color:var(--colors-secondary-label,var(--color-secondary-label))}.abstract[data-v-3152d122],.link-block[data-v-3152d122] .badge{margin-left:2.294rem}.link-block .badge+.badge[data-v-3152d122]{margin-left:1rem}.link[data-v-3152d122]{display:flex}.link-block .badge[data-v-3152d122]{margin-top:.5rem}.link-block.has-inline-element[data-v-3152d122]{display:flex;align-items:flex-start;flex-flow:row wrap}.link-block.has-inline-element .badge[data-v-3152d122]{margin-left:1rem;margin-top:0}.link-block .has-adjacent-elements[data-v-3152d122]{padding-top:5px;padding-bottom:5px;display:inline-flex}.link-block[data-v-3152d122],.link[data-v-3152d122]{box-sizing:inherit}.link-block.changed[data-v-3152d122],.link.changed[data-v-3152d122]{padding-right:1rem;padding-left:2.17647rem;padding-top:8px;padding-bottom:8px;display:inline-flex;width:100%;box-sizing:border-box}.link-block.changed.changed[data-v-3152d122],.link.changed.changed[data-v-3152d122]{padding-right:1rem}@media only screen and (max-width:735px){.link-block.changed[data-v-3152d122],.link.changed[data-v-3152d122]{padding-left:0;padding-right:0}.link-block.changed.changed[data-v-3152d122],.link.changed.changed[data-v-3152d122]{padding-right:17px;padding-left:2.17647rem}}@media only screen and (max-width:735px){.link-block.changed[data-v-3152d122],.link.changed[data-v-3152d122]{padding-left:0;padding-right:0}}.abstract .topic-required[data-v-3152d122]:not(:first-child){margin-top:4px}.topic-required[data-v-3152d122]{font-size:.8em}.deprecated[data-v-3152d122]{text-decoration:line-through}.conditional-constraints[data-v-3152d122]{font-size:.82353rem;margin-top:4px}.section-content>.content[data-v-eb97add6],.topic[data-v-eb97add6]{margin-top:15px}.datalist dd{padding-left:2rem}.datalist dt{font-weight:600;padding-left:1rem;padding-top:1.64706rem}.datalist dt:first-of-type{padding-top:0}.source[data-v-e2e09a16]{background:var(--background,var(--color-code-background));border-color:var(--color-grid);color:var(--text,var(--color-code-plain));border-radius:4px;border-style:solid;border-width:1px;padding:8px 14px;speak:literal-punctuation;line-height:25px}.source.has-multiple-lines[data-v-e2e09a16]{border-radius:4px}.source>code[data-v-e2e09a16]{font-size:.88235rem;line-height:1.66667;font-weight:400;font-family:Menlo,monospace;display:block}.platforms[data-v-c5ecdd3e]{font-size:.82353rem;line-height:1.42857;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;margin-bottom:.45rem;margin-top:1.6em}.changed .platforms[data-v-c5ecdd3e]{padding-left:.588rem}.platforms[data-v-c5ecdd3e]:first-of-type{margin-top:1rem}.source[data-v-c5ecdd3e]{margin:14px 0}.platforms+.source[data-v-c5ecdd3e]{margin:0}.changed.declaration-group[data-v-c5ecdd3e]{background:var(--background,var(--color-code-background))}.changed .source[data-v-c5ecdd3e]{background:none;border:none;margin-top:0;margin-bottom:0;margin-left:2.17647rem;padding-left:0}.declaration-diff[data-v-b3e21c4a]{background:var(--background,var(--color-code-background))}.declaration-diff-version[data-v-b3e21c4a]{padding-left:.588rem;padding-left:2.17647rem;font-size:1rem;line-height:1.52941;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--color-figure-gray-secondary);margin:0}.declaration-diff-current[data-v-b3e21c4a]{padding-top:8px;padding-bottom:5px}.declaration-diff-previous[data-v-b3e21c4a]{padding-top:5px;padding-bottom:8px;background-color:var(--color-changes-modified-previous-background);border-radius:0 0 4px 4px;position:relative}.conditional-constraints[data-v-e39c4ee4]{margin:1.17647rem 0 3rem 0}.type[data-v-791bac44]:first-letter{text-transform:capitalize}.detail-type[data-v-61ef551b]{font-weight:600;padding-left:1rem;padding-top:1.64706rem}.detail-type[data-v-61ef551b]:first-child{padding-top:0}@media only screen and (max-width:735px){.detail-type[data-v-61ef551b]{padding-left:0}}.detail-content[data-v-61ef551b]{padding-left:2rem}@media only screen and (max-width:735px){.detail-content[data-v-61ef551b]{padding-left:0}}.param-name[data-v-7bb7c035]{font-weight:600;padding-left:1rem;padding-top:1.64706rem}.param-name[data-v-7bb7c035]:first-child{padding-top:0}@media only screen and (max-width:735px){.param-name[data-v-7bb7c035]{padding-left:0}}.param-content[data-v-7bb7c035]{padding-left:2rem}@media only screen and (max-width:735px){.param-content[data-v-7bb7c035]{padding-left:0}}.param-content[data-v-7bb7c035] dt{font-weight:600}.param-content[data-v-7bb7c035] dd{margin-left:1em}.parameters-table[data-v-2d54624a] .change-added,.parameters-table[data-v-2d54624a] .change-removed{display:inline-block;max-width:100%}.parameters-table[data-v-2d54624a] .change-removed,.parameters-table[data-v-2d54624a] .token-removed{text-decoration:line-through}.param[data-v-2d54624a]{font-size:.88235rem;box-sizing:border-box}.param.changed[data-v-2d54624a]{display:flex;flex-flow:row wrap;padding-right:1rem;padding-left:2.17647rem;padding-top:8px;padding-bottom:8px;display:inline-flex;width:100%;box-sizing:border-box}.param.changed.changed[data-v-2d54624a]{padding-right:1rem}@media only screen and (max-width:735px){.param.changed[data-v-2d54624a]{padding-left:0;padding-right:0}.param.changed.changed[data-v-2d54624a]{padding-right:17px;padding-left:2.17647rem}}@media only screen and (max-width:735px){.param.changed[data-v-2d54624a]{padding-left:0;padding-right:0}}.param.changed+.param.changed[data-v-2d54624a]{margin-top:.82353rem}.changed .param-content[data-v-2d54624a],.changed .param-symbol[data-v-2d54624a]{padding-top:2px;padding-bottom:2px}@media only screen and (max-width:735px){.changed .param-content[data-v-2d54624a]{padding-top:0}.changed .param-symbol[data-v-2d54624a]{padding-bottom:0}}.param-symbol[data-v-2d54624a]{text-align:right}@media only screen and (max-width:735px){.param-symbol[data-v-2d54624a]{text-align:left}}.param-symbol[data-v-2d54624a] .type-identifier-link{color:var(--color-link)}.param+.param[data-v-2d54624a]{margin-top:1.64706rem}.param+.param[data-v-2d54624a]:first-child{margin-top:0}.param-content[data-v-2d54624a]{padding-left:1rem;padding-left:2.17647rem}@media only screen and (max-width:735px){.param-content[data-v-2d54624a]{padding-left:0;padding-right:0}}.property-metadata[data-v-8590589e]{color:var(--color-figure-gray-secondary)}.property-text{font-weight:700}.property-metadata[data-v-0a648a1e]{color:var(--color-figure-gray-secondary)}.property-name[data-v-1b54be82]{font-weight:700}.property-name.deprecated[data-v-1b54be82]{text-decoration:line-through}.property-deprecated[data-v-1b54be82]{margin-left:0}.content[data-v-1b54be82],.content[data-v-1b54be82] p:first-child{display:inline}.response-mimetype[data-v-2faa6020]{color:var(--color-figure-gray-secondary)}.part-name[data-v-1b311f59]{font-weight:700}.content[data-v-1b311f59],.content[data-v-1b311f59] p:first-child{display:inline}.param-name[data-v-5accae2c]{font-weight:700}.param-name.deprecated[data-v-5accae2c]{text-decoration:line-through}.param-deprecated[data-v-5accae2c]{margin-left:0}.content[data-v-5accae2c],.content[data-v-5accae2c] p:first-child{display:inline}.response-name[data-v-57796e8c],.response-reason[data-v-57796e8c]{font-weight:700}@media only screen and (max-width:735px){.response-reason[data-v-57796e8c]{display:none}}.response-name>code>.reason[data-v-57796e8c]{display:none}@media only screen and (max-width:735px){.response-name>code>.reason[data-v-57796e8c]{display:initial}}[data-v-0e405a2d] h2{font-size:1.88235rem;line-height:1.125;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:1250px){[data-v-0e405a2d] h2{font-size:1.64706rem;line-height:1.14286;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){[data-v-0e405a2d] h2{font-size:1.41176rem;line-height:1.16667;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.primary-content.with-border[data-v-0e405a2d]:before{border-top-color:var(--colors-grid,var(--color-grid));border-top-style:solid;border-top-width:1px;content:"";display:block}.primary-content[data-v-0e405a2d]>*{margin-bottom:40px;margin-top:40px}.primary-content[data-v-0e405a2d]>:first-child{margin-top:2.353rem}.relationships-list[data-v-6497632e]{list-style:none}.relationships-list.column[data-v-6497632e]{margin-left:0;margin-top:15px}.relationships-list.inline[data-v-6497632e]{display:flex;flex-direction:row;flex-wrap:wrap;margin-top:15px;margin-left:0}.relationships-list.inline li[data-v-6497632e]:not(:last-child):after{content:",\00a0"}.relationships-list.changed[data-v-6497632e]{padding-right:1rem;padding-left:2.17647rem;padding-top:8px;padding-bottom:8px;display:inline-flex;width:100%;box-sizing:border-box}.relationships-list.changed.changed[data-v-6497632e]{padding-right:1rem}@media only screen and (max-width:735px){.relationships-list.changed[data-v-6497632e]{padding-left:0;padding-right:0}.relationships-list.changed.changed[data-v-6497632e]{padding-right:17px;padding-left:2.17647rem}}@media only screen and (max-width:735px){.relationships-list.changed[data-v-6497632e]{padding-left:0;padding-right:0}}.relationships-list.changed[data-v-6497632e]:after{margin-top:.61765rem}.relationships-list.changed.column[data-v-6497632e]{display:block;box-sizing:border-box}.relationships-item[data-v-6497632e],.relationships-list[data-v-6497632e]{box-sizing:inherit}.conditional-constraints[data-v-6497632e]{font-size:.82353rem;margin:.17647rem 0 .58824rem 1.17647rem}.availability[data-v-4df209be]{display:flex;flex-flow:row wrap;gap:10px;margin-top:20px}.badge[data-v-4df209be]{margin:0}.technology[data-v-4df209be]{display:inline-flex;align-items:center}.tech-icon[data-v-4df209be]{height:12px;padding-right:5px;fill:var(--badge-color)}.theme-dark .tech-icon[data-v-4df209be]{fill:var(--badge-color)}.beta[data-v-4df209be]{color:var(--color-badge-beta)}.theme-dark .beta[data-v-4df209be]{color:var(--color-badge-dark-beta)}.deprecated[data-v-4df209be]{color:var(--color-badge-deprecated)}.theme-dark .deprecated[data-v-4df209be]{color:var(--color-badge-dark-deprecated)}.changed[data-v-4df209be]{padding-left:26px}.changed[data-v-4df209be]:after{content:none}.changed[data-v-4df209be]:before{background-image:url(../img/modified-icon.f496e73d.svg);background-repeat:no-repeat;bottom:0;content:" ";margin:auto;margin-right:8px;position:absolute;top:0;width:16px;height:16px;left:5px}@media screen{[data-color-scheme=dark] .changed[data-v-4df209be]:before{background-image:url(../img/modified-icon.f496e73d.svg)}}@media screen and (prefers-color-scheme:dark){[data-color-scheme=auto] .changed[data-v-4df209be]:before{background-image:url(../img/modified-icon.f496e73d.svg)}}.theme-dark .changed[data-v-4df209be]:before{background-image:url(../img/modified-icon.f496e73d.svg)}.changed-added[data-v-4df209be]{border-color:var(--color-changes-added)}.changed-added[data-v-4df209be]:before{background-image:url(../img/added-icon.d6f7e47d.svg)}@media screen{[data-color-scheme=dark] .changed-added[data-v-4df209be]:before{background-image:url(../img/added-icon.d6f7e47d.svg)}}@media screen and (prefers-color-scheme:dark){[data-color-scheme=auto] .changed-added[data-v-4df209be]:before{background-image:url(../img/added-icon.d6f7e47d.svg)}}.theme-dark .changed-added[data-v-4df209be]:before{background-image:url(../img/added-icon.d6f7e47d.svg)}.changed-deprecated[data-v-4df209be]{border-color:var(--color-changes-deprecated)}.changed-deprecated[data-v-4df209be]:before{background-image:url(../img/deprecated-icon.015b4f17.svg)}@media screen{[data-color-scheme=dark] .changed-deprecated[data-v-4df209be]:before{background-image:url(../img/deprecated-icon.015b4f17.svg)}}@media screen and (prefers-color-scheme:dark){[data-color-scheme=auto] .changed-deprecated[data-v-4df209be]:before{background-image:url(../img/deprecated-icon.015b4f17.svg)}}.theme-dark .changed-deprecated[data-v-4df209be]:before{background-image:url(../img/deprecated-icon.015b4f17.svg)}.changed-modified[data-v-4df209be]{border-color:var(--color-changes-modified)}.eyebrow[data-v-2e777455]{font-size:1.23529rem;line-height:1.19048;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:#ccc;display:block;margin-bottom:1.17647rem}@media only screen and (max-width:735px){.eyebrow[data-v-2e777455]{font-size:1.11765rem;line-height:1.21053;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.documentation-hero--disabled .eyebrow[data-v-2e777455]{color:var(--colors-secondary-label,var(--color-secondary-label))}.title[data-v-2e777455]{font-size:2.35294rem;line-height:1.1;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:#fff;margin-bottom:.70588rem}@media only screen and (max-width:1250px){.title[data-v-2e777455]{font-size:1.88235rem;line-height:1.125;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){.title[data-v-2e777455]{font-size:1.64706rem;line-height:1.14286;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.documentation-hero--disabled .title[data-v-2e777455]{color:var(--colors-header-text,var(--color-header-text))}small[data-v-2e777455]{font-size:1.41176rem;line-height:1.16667;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;padding-left:10px}@media only screen and (max-width:1250px){small[data-v-2e777455]{font-size:1.23529rem;line-height:1.19048;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}small[data-v-2e777455]:before{content:attr(data-tag-name)}small.Beta[data-v-2e777455]{color:var(--color-badge-beta)}.theme-dark small.Beta[data-v-2e777455]{color:var(--color-badge-dark-beta)}small.Deprecated[data-v-2e777455]{color:var(--color-badge-deprecated)}.theme-dark small.Deprecated[data-v-2e777455]{color:var(--color-badge-dark-deprecated)}.doc-topic[data-v-a877f03c]{display:flex;flex-direction:column;height:100%}#main[data-v-a877f03c]{outline-style:none;height:100%}@media only screen and (min-width:1920px){.full-width-container #main[data-v-a877f03c]{border-right:1px solid var(--color-grid)}}.container[data-v-a877f03c]{outline-style:none}.full-width-container .container[data-v-a877f03c]{max-width:920px;margin-left:auto;margin-right:auto;padding-left:80px;padding-right:80px;box-sizing:border-box}@media only screen and (min-width:1251px){.full-width-container .container[data-v-a877f03c]{box-sizing:unset;padding-left:120px;padding-right:120px;margin-left:0}}@media only screen and (max-width:735px){.full-width-container .container[data-v-a877f03c]{width:auto;padding-left:20px;padding-right:20px}}.static-width-container .container[data-v-a877f03c]{margin-left:auto;margin-right:auto;width:980px}@media only screen and (max-width:1250px){.static-width-container .container[data-v-a877f03c]{width:692px}}@media only screen and (max-width:735px){.static-width-container .container[data-v-a877f03c]{width:87.5%}}.description[data-v-a877f03c]{margin-bottom:2.353rem}.description[data-v-a877f03c]:empty{display:none}.description.after-enhanced-hero[data-v-a877f03c]{margin-top:2.353rem}.description[data-v-a877f03c] .content+*{margin-top:.8em}[data-v-a877f03c] .documentation-hero+.contenttable .container>.title{border-top:none}.sample-download[data-v-a877f03c]{margin-top:20px}[data-v-a877f03c] h3{font-size:1.64706rem;line-height:1.14286;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:1250px){[data-v-a877f03c] h3{font-size:1.41176rem;line-height:1.16667;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){[data-v-a877f03c] h3{font-size:1.23529rem;line-height:1.19048;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}[data-v-a877f03c] h4{font-size:1.41176rem;line-height:1.16667;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:1250px){[data-v-a877f03c] h4{font-size:1.23529rem;line-height:1.19048;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}[data-v-a877f03c] h5{font-size:1.29412rem;line-height:1.18182;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:1250px){[data-v-a877f03c] h5{font-size:1.17647rem;line-height:1.2;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){[data-v-a877f03c] h5{font-size:1.05882rem;line-height:1.44444;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}[data-v-a877f03c] h6{font-size:1rem;line-height:1.47059;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.adjustable-sidebar-width[data-v-453b0e76]{display:flex}@media only screen and (max-width:1023px){.adjustable-sidebar-width[data-v-453b0e76]{display:block;position:relative}}.sidebar[data-v-453b0e76]{position:relative}@media only screen and (max-width:1023px){.sidebar[data-v-453b0e76]{position:static}}.aside[data-v-453b0e76]{width:250px;position:relative;height:100%;max-width:100vw}.aside.no-transition[data-v-453b0e76]{transition:none!important}@media only screen and (max-width:1023px){.aside[data-v-453b0e76]{width:100%!important;overflow:hidden;min-width:0;max-width:100%;height:calc(var(--app-height) - var(--top-offset-mobile));position:fixed;top:var(--top-offset-mobile);bottom:0;z-index:9997;transform:translateX(-100%);transition:transform .15s ease-in}.aside[data-v-453b0e76] .aside-animated-child{opacity:0}.aside.force-open[data-v-453b0e76]{transform:translateX(0)}.aside.force-open[data-v-453b0e76] .aside-animated-child{--index:0;opacity:1;transition:opacity .15s linear;transition-delay:calc(var(--index)*0.15s + .15s)}.aside.has-mobile-top-offset[data-v-453b0e76]{border-top:1px solid var(--color-fill-gray-tertiary)}}.content[data-v-453b0e76]{display:flex;flex-flow:column;min-width:0;flex:1 1 auto;height:100%}.resize-handle[data-v-453b0e76]{position:absolute;cursor:col-resize;top:0;bottom:0;right:0;width:5px;height:100%;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:1;transition:background-color .15s;transform:translateX(50%)}@media only screen and (max-width:1023px){.resize-handle[data-v-453b0e76]{display:none}}.resize-handle[data-v-453b0e76]:hover{background:var(--color-fill-gray-tertiary)}.navigator-card-inner[data-v-7a09780d]{--nav-card-inner-vertical-offset:0px;position:sticky;top:var(--nav-height);height:calc(var(--app-height) - var(--nav-height) - var(--nav-card-inner-vertical-offset));display:flex;flex-flow:column}@media only screen and (max-width:1023px){.navigator-card-inner[data-v-7a09780d]{position:static;height:100%}}.highlight[data-v-d75876e2]{display:inline}.highlight[data-v-d75876e2] .match{font-weight:600;background:var(--color-fill-light-blue-secondary)}.navigator-card-item[data-v-6fb0778e]{height:32px;display:flex;align-items:center}.fromkeyboard .navigator-card-item[data-v-6fb0778e]:focus-within{margin:5px;height:22px;outline:4px solid var(--color-focus-color);outline-offset:1px}.fromkeyboard .navigator-card-item:focus-within .depth-spacer[data-v-6fb0778e]{margin-left:-5px}.depth-spacer[data-v-6fb0778e]{width:calc(var(--nesting-index)*15px + 25px);height:32px;position:relative;flex:0 0 auto}.fromkeyboard .depth-spacer[data-v-6fb0778e]:focus{margin:-5px}.head-wrapper[data-v-6fb0778e]{padding:0 20px 0 10px;position:relative;display:flex;align-items:center;flex:1;min-width:0;height:100%}@supports (padding:max(0px)){.head-wrapper[data-v-6fb0778e]{padding-left:max(10px,env(safe-area-inset-left));padding-right:max(20px,env(safe-area-inset-right))}}.head-wrapper.active[data-v-6fb0778e]{background:var(--color-fill-gray-quaternary)}.head-wrapper.is-group .leaf-link[data-v-6fb0778e]{color:var(--color-figure-gray-secondary);font-weight:600}.head-wrapper.is-group .leaf-link[data-v-6fb0778e]:after{display:none}.hover .head-wrapper[data-v-6fb0778e]:not(.is-group){background:var(--color-navigator-item-hover)}.head-wrapper .navigator-icon[data-v-6fb0778e]{display:flex;flex:0 0 auto}.head-wrapper .navigator-icon.changed[data-v-6fb0778e]{border:none;width:1em;height:1em;margin-right:7px;z-index:0}.head-wrapper .navigator-icon.changed[data-v-6fb0778e]:after{top:50%;left:50%;right:auto;bottom:auto;transform:translate(-50%,-50%);background-image:url(../img/modified-icon.f496e73d.svg);margin:0}@media screen{[data-color-scheme=dark] .head-wrapper .navigator-icon.changed[data-v-6fb0778e]:after{background-image:url(../img/modified-icon.f496e73d.svg)}}@media screen and (prefers-color-scheme:dark){[data-color-scheme=auto] .head-wrapper .navigator-icon.changed[data-v-6fb0778e]:after{background-image:url(../img/modified-icon.f496e73d.svg)}}.head-wrapper .navigator-icon.changed-added[data-v-6fb0778e]:after{background-image:url(../img/added-icon.d6f7e47d.svg)}@media screen{[data-color-scheme=dark] .head-wrapper .navigator-icon.changed-added[data-v-6fb0778e]:after{background-image:url(../img/added-icon.d6f7e47d.svg)}}@media screen and (prefers-color-scheme:dark){[data-color-scheme=auto] .head-wrapper .navigator-icon.changed-added[data-v-6fb0778e]:after{background-image:url(../img/added-icon.d6f7e47d.svg)}}.head-wrapper .navigator-icon.changed-deprecated[data-v-6fb0778e]:after{background-image:url(../img/deprecated-icon.015b4f17.svg)}@media screen{[data-color-scheme=dark] .head-wrapper .navigator-icon.changed-deprecated[data-v-6fb0778e]:after{background-image:url(../img/deprecated-icon.015b4f17.svg)}}@media screen and (prefers-color-scheme:dark){[data-color-scheme=auto] .head-wrapper .navigator-icon.changed-deprecated[data-v-6fb0778e]:after{background-image:url(../img/deprecated-icon.015b4f17.svg)}}.head-wrapper .leaf-link[data-v-6fb0778e]{color:var(--color-figure-gray);text-overflow:ellipsis;overflow:hidden;white-space:nowrap;max-width:100%;display:inline;vertical-align:middle;font-size:.82353rem;line-height:1.28571;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.fromkeyboard .head-wrapper .leaf-link[data-v-6fb0778e]:focus{outline:none}.head-wrapper .leaf-link[data-v-6fb0778e]:hover{text-decoration:none}.head-wrapper .leaf-link.bolded[data-v-6fb0778e]{font-weight:600}.head-wrapper .leaf-link[data-v-6fb0778e]:after{content:"";position:absolute;top:0;left:0;right:0;bottom:0}.extended-content[data-v-6fb0778e]{font-size:.82353rem;line-height:1.42857;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--color-figure-gray-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tree-toggle[data-v-6fb0778e]{overflow:hidden;position:absolute;width:100%;height:100%;padding-right:5px;box-sizing:border-box;z-index:1;display:flex;align-items:center;justify-content:flex-end}.title-container[data-v-6fb0778e]{min-width:0;display:flex;align-items:center}.chevron[data-v-6fb0778e]{width:10px}.chevron.animating[data-v-6fb0778e]{transition:transform .15s ease-in}.chevron.rotate[data-v-6fb0778e]{transform:rotate(90deg)}.tag[data-v-3b809bfa]{display:inline-block;padding-right:.58824rem}.tag[data-v-3b809bfa]:focus{outline:none}.tag button[data-v-3b809bfa]{color:var(--color-figure-gray);background-color:var(--color-fill-tertiary);font-size:.82353rem;line-height:1.28571;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;border-radius:.82353rem;padding:.23529rem .58824rem;white-space:nowrap;border:1px solid transparent}@media (hover:hover){.tag button[data-v-3b809bfa]:hover{transition:background-color .2s,color .2s;background-color:var(--color-fill-blue);color:#fff}}.tag button[data-v-3b809bfa]:focus:active{background-color:var(--color-fill-blue);color:#fff}.fromkeyboard .tag button[data-v-3b809bfa]:focus,.tag button.focus[data-v-3b809bfa],.tag button[data-v-3b809bfa]:focus{box-shadow:0 0 0 4px var(--color-focus-color);outline:none;border-color:var(--color-focus-border-color)}.tags[data-v-4b231516]{position:relative;margin:0;list-style:none;box-sizing:border-box;transition:padding-right .8s,padding-bottom .8s,max-height 1s,opacity 1s;padding:0}.tags .scroll-wrapper[data-v-4b231516]{overflow-x:auto;overflow-y:hidden;-ms-overflow-style:none;scrollbar-color:var(--color-figure-gray-tertiary) transparent;scrollbar-width:thin}.tags .scroll-wrapper[data-v-4b231516]::-webkit-scrollbar{height:0}@supports not ((-webkit-touch-callout:none) or (scrollbar-width:none) or (-ms-overflow-style:none)){.tags .scroll-wrapper.scrolling[data-v-4b231516]{--scrollbar-height:11px;padding-top:var(--scrollbar-height);height:calc(var(--scroll-target-height) - var(--scrollbar-height));display:flex;align-items:center}}.tags .scroll-wrapper.scrolling[data-v-4b231516]::-webkit-scrollbar{height:11px}.tags .scroll-wrapper.scrolling[data-v-4b231516]::-webkit-scrollbar-thumb{border-radius:10px;background-color:var(--color-figure-gray-tertiary);border:2px solid transparent;background-clip:padding-box}.tags .scroll-wrapper.scrolling[data-v-4b231516]::-webkit-scrollbar-track-piece:end{margin-right:8px}.tags .scroll-wrapper.scrolling[data-v-4b231516]::-webkit-scrollbar-track-piece:start{margin-left:8px}.tags ul[data-v-4b231516]{margin:0;padding:0;display:flex}.filter[data-v-3b91e60a]{--input-vertical-padding:.76471rem;--input-height:1.64706rem;--input-border-color:var(--color-fill-gray-secondary);--input-text:var(--color-fill-gray-secondary);position:relative;box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0);border-radius:5px}.fromkeyboard .filter[data-v-3b91e60a]:focus{outline:none}.filter__top-wrapper[data-v-3b91e60a]{display:flex}.filter__filter-button[data-v-3b91e60a]{position:relative;margin-left:.58824rem;z-index:1;cursor:text;margin-right:.17647rem}@media only screen and (max-width:735px){.filter__filter-button[data-v-3b91e60a]{margin-right:.41176rem}}.filter__filter-button .svg-icon[data-v-3b91e60a]{fill:var(--input-text);display:block;height:21px}.filter__filter-button.blue[data-v-3b91e60a]>*{fill:var(--color-figure-blue);color:var(--color-figure-blue)}.filter.focus .filter__wrapper[data-v-3b91e60a]{box-shadow:0 0 0 3pt var(--color-focus-color);--input-border-color:var(--color-fill-blue)}.filter__wrapper[data-v-3b91e60a]{border:1px solid var(--input-border-color);background:var(--color-fill);border-radius:4px}.filter__wrapper--reversed[data-v-3b91e60a]{display:flex;flex-direction:column-reverse}.filter__suggested-tags[data-v-3b91e60a]{border-top:1px solid var(--color-fill-gray-tertiary);z-index:1;overflow:hidden}.filter__suggested-tags[data-v-3b91e60a] ul{padding:var(--input-vertical-padding) .52941rem;border:1px solid transparent;border-bottom-left-radius:3px;border-bottom-right-radius:3px}.fromkeyboard .filter__suggested-tags[data-v-3b91e60a] ul:focus{outline:none;box-shadow:0 0 0 5px var(--color-focus-color)}.filter__wrapper--reversed .filter__suggested-tags[data-v-3b91e60a]{border-bottom:1px solid var(--color-fill-gray-tertiary);border-top:none}.filter__selected-tags[data-v-3b91e60a]{z-index:1;padding-left:4px;margin:-4px 0}@media only screen and (max-width:735px){.filter__selected-tags[data-v-3b91e60a]{padding-left:0}}.filter__selected-tags[data-v-3b91e60a] ul{padding:4px}@media only screen and (max-width:735px){.filter__selected-tags[data-v-3b91e60a] ul{padding-right:.41176rem}}.filter__selected-tags[data-v-3b91e60a] ul .tag:last-child{padding-right:0}.filter__delete-button[data-v-3b91e60a]{position:relative;margin:0;z-index:1;border-radius:100%}.fromkeyboard .filter__delete-button[data-v-3b91e60a]:focus{box-shadow:0 0 0 4px var(--color-focus-color);outline:none}.filter__delete-button .clear-rounded-icon[data-v-3b91e60a]{height:.94118rem;width:.94118rem;fill:var(--input-text);display:block}.filter__delete-button-wrapper[data-v-3b91e60a]{display:flex;align-items:center;padding:0 10px;border-top-right-radius:4px;border-bottom-right-radius:4px}.filter__input-label[data-v-3b91e60a]{position:relative;flex-grow:1;height:var(--input-height);padding:var(--input-vertical-padding) 0}.filter__input-label[data-v-3b91e60a]:after{content:attr(data-value);visibility:hidden;width:auto;white-space:nowrap;min-width:130px;display:block;text-indent:.41176rem}@media only screen and (max-width:735px){.filter__input-label[data-v-3b91e60a]:after{text-indent:.17647rem}}.filter__input-box-wrapper[data-v-3b91e60a]{overflow-y:hidden;-ms-overflow-style:none;scrollbar-color:var(--color-figure-gray-tertiary) transparent;scrollbar-width:thin;display:flex;overflow-x:auto;align-items:center;cursor:text;flex:1}.filter__input-box-wrapper[data-v-3b91e60a]::-webkit-scrollbar{height:0}@supports not ((-webkit-touch-callout:none) or (scrollbar-width:none) or (-ms-overflow-style:none)){.filter__input-box-wrapper.scrolling[data-v-3b91e60a]{--scrollbar-height:11px;padding-top:var(--scrollbar-height);height:calc(var(--scroll-target-height) - var(--scrollbar-height));display:flex;align-items:center}}.filter__input-box-wrapper.scrolling[data-v-3b91e60a]::-webkit-scrollbar{height:11px}.filter__input-box-wrapper.scrolling[data-v-3b91e60a]::-webkit-scrollbar-thumb{border-radius:10px;background-color:var(--color-figure-gray-tertiary);border:2px solid transparent;background-clip:padding-box}.filter__input-box-wrapper.scrolling[data-v-3b91e60a]::-webkit-scrollbar-track-piece:end{margin-right:8px}.filter__input-box-wrapper.scrolling[data-v-3b91e60a]::-webkit-scrollbar-track-piece:start{margin-left:8px}.filter__input[data-v-3b91e60a]{font-size:1.23529rem;line-height:1.38095;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--color-text);height:var(--input-height);border:none;width:100%;position:absolute;background:transparent;z-index:1;text-indent:.41176rem}@media only screen and (max-width:735px){.filter__input[data-v-3b91e60a]{font-size:1.11765rem;line-height:1.42105;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;text-indent:.17647rem}}.filter__input[data-v-3b91e60a]:focus{outline:none}.filter__input[placeholder][data-v-3b91e60a]::-moz-placeholder{color:var(--input-text);opacity:1}.filter__input[placeholder][data-v-3b91e60a]::placeholder{color:var(--input-text);opacity:1}.filter__input[placeholder][data-v-3b91e60a]:-ms-input-placeholder{color:var(--input-text)}.filter__input[placeholder][data-v-3b91e60a]::-ms-input-placeholder{color:var(--input-text)}.vue-recycle-scroller{position:relative}.vue-recycle-scroller.direction-vertical:not(.page-mode){overflow-y:auto}.vue-recycle-scroller.direction-horizontal:not(.page-mode){overflow-x:auto}.vue-recycle-scroller.direction-horizontal{display:-webkit-box;display:-ms-flexbox;display:flex}.vue-recycle-scroller__slot{-webkit-box-flex:1;-ms-flex:auto 0 0px;flex:auto 0 0}.vue-recycle-scroller__item-wrapper{-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;position:relative}.vue-recycle-scroller.ready .vue-recycle-scroller__item-view{position:absolute;top:0;left:0;will-change:transform}.vue-recycle-scroller.direction-vertical .vue-recycle-scroller__item-wrapper{width:100%}.vue-recycle-scroller.direction-horizontal .vue-recycle-scroller__item-wrapper{height:100%}.vue-recycle-scroller.ready.direction-vertical .vue-recycle-scroller__item-view{width:100%}.vue-recycle-scroller.ready.direction-horizontal .vue-recycle-scroller__item-view{height:100%}.resize-observer[data-v-b329ee4c]{border:none;background-color:transparent;opacity:0}.resize-observer[data-v-b329ee4c],.resize-observer[data-v-b329ee4c] object{position:absolute;top:0;left:0;z-index:-1;width:100%;height:100%;pointer-events:none;display:block;overflow:hidden}.navigator-card[data-v-d21551d4]{--card-vertical-spacing:8px;display:flex;flex-direction:column;flex:1 1 auto;min-height:0}.navigator-card .navigator-card-full-height[data-v-d21551d4]{height:100%}.navigator-card .navigator-card-inner[data-v-d21551d4]{--nav-card-inner-vertical-offset:71px}.navigator-card .head-wrapper[data-v-d21551d4]{position:relative}.navigator-card .navigator-head[data-v-d21551d4]{padding:10px 20px;background:var(--color-fill-secondary);border-bottom:1px solid var(--color-grid);display:flex;align-items:center;box-sizing:border-box}.navigator-card .navigator-head .badge[data-v-d21551d4]{margin-top:0}.navigator-card .navigator-head.router-link-exact-active[data-v-d21551d4]{background:var(--color-fill-tertiary)}.navigator-card .navigator-head.router-link-exact-active .card-link[data-v-d21551d4]{font-weight:700}.navigator-card .navigator-head[data-v-d21551d4]:hover{background:var(--color-navigator-item-hover);text-decoration:none}@media only screen and (max-width:1023px){.navigator-card .navigator-head[data-v-d21551d4]{justify-content:center;height:3.05882rem;padding:14px 20px}}@media only screen and (max-width:767px){.navigator-card .navigator-head[data-v-d21551d4]{height:2.82353rem;padding:12px 20px}}@supports (padding:max(0px)){.navigator-card .navigator-head[data-v-d21551d4]{padding-left:max(20px,env(safe-area-inset-left));padding-right:max(20px,env(safe-area-inset-right))}}.navigator-card .card-icon[data-v-d21551d4]{width:19px;height:19px}.no-items-wrapper[data-v-d21551d4]{color:var(--color-figure-gray-tertiary);font-size:.82353rem;line-height:1.42857;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;padding:var(--card-vertical-spacing) 20px}.close-card-mobile[data-v-d21551d4]{display:none;position:absolute;z-index:1;color:var(--color-link);align-items:center;justify-content:center}@media only screen and (max-width:1023px){.close-card-mobile[data-v-d21551d4]{display:flex;left:0;height:100%;padding-left:1.29412rem;padding-right:1.29412rem}@supports (padding:max(0px)){.close-card-mobile[data-v-d21551d4]{padding-left:max(1.29412rem,env(safe-area-inset-left))}}}@media only screen and (max-width:767px){.close-card-mobile[data-v-d21551d4]{padding-left:.94118rem;padding-right:.94118rem}}.close-card-mobile .close-icon[data-v-d21551d4]{width:19px;height:19px}.card-body[data-v-d21551d4]{padding-right:0;flex:1 1 auto;min-height:0}@media only screen and (max-width:1023px){.card-body[data-v-d21551d4]{--card-vertical-spacing:0px;padding-top:71px}}.card-link[data-v-d21551d4]{color:var(--color-text);font-size:.82353rem;line-height:1.42857;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:600}.navigator-filter[data-v-d21551d4]{box-sizing:border-box;padding:15px 30px;border-top:1px solid var(--color-grid);height:71px;display:flex;align-items:flex-end}@supports (padding:max(0px)){.navigator-filter[data-v-d21551d4]{padding-left:max(30px,env(safe-area-inset-left));padding-right:max(30px,env(safe-area-inset-right))}}@media only screen and (max-width:1023px){.navigator-filter[data-v-d21551d4]{border:none;padding:10px 20px;align-items:flex-start;height:62px}@supports (padding:max(0px)){.navigator-filter[data-v-d21551d4]{padding-left:max(20px,env(safe-area-inset-left));padding-right:max(20px,env(safe-area-inset-right))}}}.navigator-filter .input-wrapper[data-v-d21551d4]{position:relative;flex:1;min-width:0}.navigator-filter .filter-component[data-v-d21551d4]{--input-vertical-padding:10px;--input-height:20px;--input-border-color:var(--color-grid);--input-text:var(--color-figure-gray-secondary)}.navigator-filter .filter-component[data-v-d21551d4] .filter__input{font-size:1rem;line-height:1.47059;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.scroller[data-v-d21551d4]{height:100%;box-sizing:border-box;padding:var(--card-vertical-spacing) 0;padding-bottom:calc(var(--top-offset, 0px) + var(--card-vertical-spacing));transition:padding-bottom .15s ease-in}@media only screen and (max-width:1023px){.scroller[data-v-d21551d4]{padding-bottom:10em}}.scroller[data-v-d21551d4] .vue-recycle-scroller__item-wrapper{transform:translateZ(0)}.filter-wrapper[data-v-d21551d4]{position:sticky;bottom:0;background:var(--color-fill)}@media only screen and (max-width:1023px){.filter-wrapper[data-v-d21551d4]{position:absolute;top:3.05882rem;bottom:auto;width:100%}}@media only screen and (max-width:767px){.filter-wrapper[data-v-d21551d4]{top:2.82353rem}}@-webkit-keyframes fadeout-data-v-60936b56{0%{opacity:1}to{opacity:0}}@keyframes fadeout-data-v-60936b56{0%{opacity:1}to{opacity:0}}path[data-v-60936b56]{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:fadeout-data-v-60936b56;animation-name:fadeout-data-v-60936b56;fill:currentColor}path[data-v-60936b56]:first-of-type{-webkit-animation-delay:0ms;animation-delay:0ms}path[data-v-60936b56]:nth-of-type(2){-webkit-animation-delay:-125ms;animation-delay:-125ms}path[data-v-60936b56]:nth-of-type(3){-webkit-animation-delay:-.25s;animation-delay:-.25s}path[data-v-60936b56]:nth-of-type(4){-webkit-animation-delay:-375ms;animation-delay:-375ms}path[data-v-60936b56]:nth-of-type(5){-webkit-animation-delay:-.5s;animation-delay:-.5s}path[data-v-60936b56]:nth-of-type(6){-webkit-animation-delay:-625ms;animation-delay:-625ms}path[data-v-60936b56]:nth-of-type(7){-webkit-animation-delay:-.75s;animation-delay:-.75s}path[data-v-60936b56]:nth-of-type(8){-webkit-animation-delay:-875ms;animation-delay:-875ms}.navigator[data-v-0ea7ca2b]{--nav-height:3.05882rem;height:100%;display:flex;flex-flow:column}@media only screen and (min-width:1920px){.navigator[data-v-0ea7ca2b]{border-left:1px solid var(--color-grid)}}@media only screen and (max-width:1023px){.navigator[data-v-0ea7ca2b]{position:static;transition:none}}.loading-placeholder[data-v-0ea7ca2b]{align-items:center;color:var(--color-figure-gray-secondary);justify-content:center}.loading-spinner[data-v-0ea7ca2b]{--spinner-size:40px;--spinner-delay:1s;height:var(--spinner-size);width:var(--spinner-size)}.loading-spinner.delay-visibility-enter-active[data-v-0ea7ca2b]{transition:visibility var(--spinner-delay);visibility:hidden}.hierarchy-collapsed-items[data-v-74906830]{position:relative;display:inline-flex;align-items:center;margin-left:.17647rem}.hierarchy-collapsed-items .hierarchy-item-icon[data-v-74906830]{width:9px;height:15px;margin-right:.17647rem;display:flex;justify-content:center;font-size:1em;align-self:baseline}.nav--in-breakpoint-range .hierarchy-collapsed-items[data-v-74906830]{display:none}.hierarchy-collapsed-items .toggle[data-v-74906830]{background:var(--color-nav-hierarchy-collapse-background);border-color:var(--color-nav-hierarchy-collapse-borders);border-radius:4px;border-style:solid;border-width:0;font-weight:600;height:1.11765rem;text-align:center;width:2.11765rem;display:flex;align-items:center;justify-content:center}.theme-dark .hierarchy-collapsed-items .toggle[data-v-74906830]{background:var(--color-nav-dark-hierarchy-collapse-background)}.hierarchy-collapsed-items .toggle.focused[data-v-74906830],.hierarchy-collapsed-items .toggle[data-v-74906830]:active,.hierarchy-collapsed-items .toggle[data-v-74906830]:focus{box-shadow:0 0 0 4px var(--color-focus-color);outline:none}.indicator[data-v-74906830]{width:1em;height:1em;display:flex;align-items:center}.indicator .toggle-icon[data-v-74906830]{width:100%}.dropdown[data-v-74906830]{background:var(--color-nav-hierarchy-collapse-background);border-color:var(--color-nav-hierarchy-collapse-borders);border-radius:4px;border-style:solid;box-shadow:0 1px 4px -1px var(--color-figure-gray-secondary);border-width:0;padding:0 .5rem;position:absolute;z-index:42;top:calc(100% + .41176rem)}.theme-dark .dropdown[data-v-74906830]{background:var(--color-nav-dark-hierarchy-collapse-background);border-color:var(--color-nav-dark-hierarchy-collapse-borders)}.dropdown.collapsed[data-v-74906830]{opacity:0;transform:translate3d(0,-.41176rem,0);transition:opacity .25s ease,transform .25s ease,visibility 0s linear .25s;visibility:hidden}.dropdown[data-v-74906830]:not(.collapsed){opacity:1;transform:none;transition:opacity .25s ease,transform .25s ease,visibility 0s linear 0s;visibility:visible}.nav--in-breakpoint-range .dropdown[data-v-74906830]:not(.collapsed){display:none}.dropdown[data-v-74906830]:before{border-bottom-color:var(--color-nav-hierarchy-collapse-background);border-bottom-style:solid;border-bottom-width:.5rem;border-left-color:transparent;border-left-style:solid;border-left-width:.5rem;border-right-color:transparent;border-right-style:solid;border-right-width:.5rem;content:"";left:1.26471rem;position:absolute;top:-.44118rem}.theme-dark .dropdown[data-v-74906830]:before{border-bottom-color:var(--color-nav-dark-hierarchy-collapse-background)}.dropdown-item[data-v-74906830]{border-top-color:var(--color-nav-hierarchy-collapse-borders);border-top-style:solid;border-top-width:1px}.theme-dark .dropdown-item[data-v-74906830]{border-top-color:var(--color-nav-dark-hierarchy-collapse-borders)}.dropdown-item[data-v-74906830]:first-child{border-top:none}.nav-menu-link[data-v-74906830]{max-width:57.64706rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;padding:.75rem 1rem}.hierarchy-item[data-v-382bf39e]{display:flex;align-items:center;margin-left:.17647rem}.hierarchy-item[data-v-382bf39e] .hierarchy-item-icon{width:9px;height:15px;margin-right:.17647rem;display:flex;justify-content:center;font-size:1em;align-self:baseline}.nav--in-breakpoint-range .hierarchy-item[data-v-382bf39e] .hierarchy-item-icon{display:none}.nav--in-breakpoint-range .hierarchy-item[data-v-382bf39e]{border-top:1px solid var(--color-nav-hierarchy-item-borders);display:flex;align-items:center}.theme-dark.nav--in-breakpoint-range .hierarchy-item[data-v-382bf39e]{border-top-color:var(--color-nav-dark-hierarchy-item-borders)}.nav--in-breakpoint-range .hierarchy-item[data-v-382bf39e]:first-of-type{border-top:none}.hierarchy-item.collapsed[data-v-382bf39e]{display:none}.nav--in-breakpoint-range .hierarchy-item.collapsed[data-v-382bf39e]{display:inline-block}.item[data-v-382bf39e]{display:inline-block;vertical-align:middle}.nav--in-breakpoint-range .item[data-v-382bf39e]{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;height:100%;line-height:2.47059rem}@media only screen and (min-width:768px){.hierarchy-item:first-child:last-child .item[data-v-382bf39e],.hierarchy-item:first-child:last-child~.hierarchy-item .item[data-v-382bf39e]{max-width:45rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.has-badge .hierarchy-item:first-child:last-child .item[data-v-382bf39e],.has-badge .hierarchy-item:first-child:last-child~.hierarchy-item .item[data-v-382bf39e],.hierarchy-item:first-child:nth-last-child(2) .item[data-v-382bf39e],.hierarchy-item:first-child:nth-last-child(2)~.hierarchy-item .item[data-v-382bf39e]{max-width:36rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.has-badge .hierarchy-item:first-child:nth-last-child(2) .item[data-v-382bf39e],.has-badge .hierarchy-item:first-child:nth-last-child(2)~.hierarchy-item .item[data-v-382bf39e]{max-width:28.8rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hierarchy-item:first-child:nth-last-child(3) .item[data-v-382bf39e],.hierarchy-item:first-child:nth-last-child(3)~.hierarchy-item .item[data-v-382bf39e]{max-width:27rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.has-badge .hierarchy-item:first-child:nth-last-child(3) .item[data-v-382bf39e],.has-badge .hierarchy-item:first-child:nth-last-child(3)~.hierarchy-item .item[data-v-382bf39e]{max-width:21.6rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hierarchy-item:first-child:nth-last-child(4) .item[data-v-382bf39e],.hierarchy-item:first-child:nth-last-child(4)~.hierarchy-item .item[data-v-382bf39e]{max-width:18rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.has-badge .hierarchy-item:first-child:nth-last-child(4) .item[data-v-382bf39e],.has-badge .hierarchy-item:first-child:nth-last-child(4)~.hierarchy-item .item[data-v-382bf39e]{max-width:14.4rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hierarchy-item:first-child:nth-last-child(5) .item[data-v-382bf39e],.hierarchy-item:first-child:nth-last-child(5)~.hierarchy-item .item[data-v-382bf39e]{max-width:9rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.has-badge .hierarchy-item:first-child:nth-last-child(5) .item[data-v-382bf39e],.has-badge .hierarchy-item:first-child:nth-last-child(5)~.hierarchy-item .item[data-v-382bf39e]{max-width:7.2rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hierarchy-collapsed-items~.hierarchy-item .item[data-v-382bf39e]{max-width:10.8rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hierarchy-collapsed-items~.hierarchy-item:last-child .item[data-v-382bf39e]{max-width:none}.has-badge .hierarchy-collapsed-items~.hierarchy-item .item[data-v-382bf39e]{max-width:8.64rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}.hierarchy[data-v-30132cb0]{justify-content:flex-start;min-width:0;margin-right:80px}.nav--in-breakpoint-range .hierarchy[data-v-30132cb0]{margin-right:0}.hierarchy .root-hierarchy .item[data-v-30132cb0]{max-width:10rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nav-menu-setting-label[data-v-126c8e14]{margin-right:.35294rem;white-space:nowrap}.language-dropdown[data-v-126c8e14]{-webkit-text-size-adjust:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;background-color:transparent;box-sizing:inherit;padding:0 11px 0 4px;margin-left:-4px;font-size:.82353rem;line-height:1.28571;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;cursor:pointer;position:relative;z-index:1}@media only screen and (max-width:1023px){.language-dropdown[data-v-126c8e14]{font-size:.82353rem;line-height:1.5;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.language-dropdown[data-v-126c8e14]:focus{outline:none}.fromkeyboard .language-dropdown[data-v-126c8e14]:focus{outline:4px solid var(--color-focus-color);outline-offset:1px}.language-sizer[data-v-126c8e14]{position:absolute;opacity:0;pointer-events:none;padding:0}.language-toggle-container[data-v-126c8e14]{display:flex;align-items:center;padding-right:.17647rem;position:relative}.nav--in-breakpoint-range .language-toggle-container[data-v-126c8e14]{display:none}.language-toggle-container .toggle-icon[data-v-126c8e14]{width:.6em;height:.6em;position:absolute;right:7px}.language-toggle-label[data-v-126c8e14]{margin-right:2px}.language-toggle.nav-menu-toggle-label[data-v-126c8e14]{margin-right:6px}.language-list[data-v-126c8e14]{display:inline-block;margin-top:0}.language-list-container[data-v-126c8e14]{display:none}.language-list-item[data-v-126c8e14],.nav--in-breakpoint-range .language-list-container[data-v-126c8e14]{display:inline-block}.language-list-item[data-v-126c8e14]:not(:first-child){border-left:1px solid #424242;margin-left:6px;padding-left:6px}[data-v-cbd98416] .nav-menu{line-height:1.5;padding-top:0}[data-v-cbd98416] .nav-menu,[data-v-cbd98416] .nav-menu-settings{font-size:.82353rem;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}[data-v-cbd98416] .nav-menu-settings{line-height:1.28571}@media only screen and (max-width:1023px){[data-v-cbd98416] .nav-menu-settings{font-size:.82353rem;line-height:1.5;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (min-width:1024px){[data-v-cbd98416] .nav-menu-settings{margin-left:.58824rem}}.nav--in-breakpoint-range[data-v-cbd98416] .nav-menu-settings:not([data-previous-menu-children-count="0"]) .nav-menu-setting:first-child{border-top:1px solid #b0b0b0;display:flex;align-items:center}[data-v-cbd98416] .nav-menu-settings .nav-menu-setting{display:flex;align-items:center;color:var(--color-nav-current-link);margin-left:0}[data-v-cbd98416] .nav-menu-settings .nav-menu-setting:first-child:not(:only-child){margin-right:.58824rem}.nav--in-breakpoint-range[data-v-cbd98416] .nav-menu-settings .nav-menu-setting:first-child:not(:only-child){margin-right:0}.theme-dark[data-v-cbd98416] .nav-menu-settings .nav-menu-setting{color:var(--color-nav-dark-current-link)}.nav--in-breakpoint-range[data-v-cbd98416] .nav-menu-settings .nav-menu-setting:not(:first-child){border-top:1px solid #424242}.documentation-nav[data-v-cbd98416] .nav-title{font-size:.82353rem;line-height:1.5;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:1023px){.documentation-nav[data-v-cbd98416] .nav-title{padding-top:0}}.documentation-nav[data-v-cbd98416] .nav-title .nav-title-link.inactive{height:auto;color:var(--color-figure-gray-secondary-alt)}.theme-dark.documentation-nav .nav-title .nav-title-link.inactive[data-v-cbd98416]{color:#b0b0b0}.sidenav-toggle[data-v-cbd98416]{margin-left:-14px;margin-right:-14px;padding-left:14px;padding-right:14px}.sidenav-toggle .sidenav-icon[data-v-cbd98416]{display:flex;width:19px;height:19px}.doc-topic-view[data-v-6c414c34]{--delay:1s;display:flex;flex-flow:column;background:var(--colors-text-background,var(--color-text-background))}.doc-topic-view .delay-hiding-leave-active[data-v-6c414c34]{transition:display var(--delay)}.doc-topic-aside[data-v-6c414c34]{height:100%;box-sizing:border-box;border-right:1px solid var(--color-grid)}@media only screen and (max-width:1023px){.doc-topic-aside[data-v-6c414c34]{background:var(--color-fill);border-right:none}.animating .doc-topic-aside[data-v-6c414c34]{border-right:1px solid var(--color-grid)}}.topic-wrapper[data-v-6c414c34]{flex:1 1 auto;width:100%}.full-width-container[data-v-6c414c34]{max-width:1920px;margin-left:auto;margin-right:auto}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/css/documentation-topic~topic~tutorials-overview.82acfe22.css b/docs/docc/Reducer.doccarchive/css/documentation-topic~topic~tutorials-overview.82acfe22.css
deleted file mode 100644
index 68c7acd..0000000
--- a/docs/docc/Reducer.doccarchive/css/documentation-topic~topic~tutorials-overview.82acfe22.css
+++ /dev/null
@@ -1,9 +0,0 @@
-/*!
- * This source file is part of the Swift.org open source project
- *
- * Copyright (c) 2021 Apple Inc. and the Swift project authors
- * Licensed under Apache License v2.0 with Runtime Library Exception
- *
- * See https://swift.org/LICENSE.txt for license information
- * See https://swift.org/CONTRIBUTORS.txt for Swift project authors
- */.svg-icon[data-v-0137d411]{fill:var(--colors-svg-icon-fill-light,var(--color-svg-icon));transform:scale(1);-webkit-transform:scale(1);overflow:visible}.theme-dark .svg-icon[data-v-0137d411]{fill:var(--colors-svg-icon-fill-dark,var(--color-svg-icon))}.svg-icon.icon-inline[data-v-0137d411]{display:inline-block;vertical-align:middle;fill:currentColor}.svg-icon.icon-inline[data-v-0137d411] .svg-icon-stroke{stroke:currentColor}[data-v-0137d411] .svg-icon-stroke{stroke:var(--colors-svg-icon-fill-light,var(--color-svg-icon))}.theme-dark[data-v-0137d411] .svg-icon-stroke{stroke:var(--colors-svg-icon-fill-dark,var(--color-svg-icon))}.label[data-v-5117d474]{font-size:.70588rem;line-height:1.33333;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.label+[data-v-5117d474]{margin-top:.4em}.deprecated .label[data-v-5117d474]{color:var(--color-aside-deprecated)}.experiment .label[data-v-5117d474]{color:var(--color-aside-experiment)}.important .label[data-v-5117d474]{color:var(--color-aside-important)}.note .label[data-v-5117d474]{color:var(--color-aside-note)}.tip .label[data-v-5117d474]{color:var(--color-aside-tip)}.warning .label[data-v-5117d474]{color:var(--color-aside-warning)}.doc-topic aside[data-v-5117d474]{border-radius:4px;padding:.94118rem;border:0 solid;border-left-width:6px}.doc-topic aside.deprecated[data-v-5117d474]{background-color:var(--color-aside-deprecated-background);border-color:var(--color-aside-deprecated-border);box-shadow:0 0 0 0 var(--color-aside-deprecated-border) inset,0 0 0 0 var(--color-aside-deprecated-border)}.doc-topic aside.experiment[data-v-5117d474]{background-color:var(--color-aside-experiment-background);border-color:var(--color-aside-experiment-border);box-shadow:0 0 0 0 var(--color-aside-experiment-border) inset,0 0 0 0 var(--color-aside-experiment-border)}.doc-topic aside.important[data-v-5117d474]{background-color:var(--color-aside-important-background);border-color:var(--color-aside-important-border);box-shadow:0 0 0 0 var(--color-aside-important-border) inset,0 0 0 0 var(--color-aside-important-border)}.doc-topic aside.note[data-v-5117d474]{background-color:var(--color-aside-note-background);border-color:var(--color-aside-note-border);box-shadow:0 0 0 0 var(--color-aside-note-border) inset,0 0 0 0 var(--color-aside-note-border)}.doc-topic aside.tip[data-v-5117d474]{background-color:var(--color-aside-tip-background);border-color:var(--color-aside-tip-border);box-shadow:0 0 0 0 var(--color-aside-tip-border) inset,0 0 0 0 var(--color-aside-tip-border)}.doc-topic aside.warning[data-v-5117d474]{background-color:var(--color-aside-warning-background);border-color:var(--color-aside-warning-border);box-shadow:0 0 0 0 var(--color-aside-warning-border) inset,0 0 0 0 var(--color-aside-warning-border)}.doc-topic aside .label[data-v-5117d474]{font-size:1rem;line-height:1.52941;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.file-icon[data-v-7c381064]{position:relative;align-items:flex-end;height:24px;margin:0 .5rem 0 1rem}.filename[data-v-c8c40662]{color:var(--text,var(--colors-secondary-label,var(--color-secondary-label)));font-size:.94118rem;line-height:1.1875;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;margin-top:1rem}@media only screen and (max-width:735px){.filename[data-v-c8c40662]{font-size:.82353rem;line-height:1.42857;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;margin-top:0}}.filename>a[data-v-c8c40662],.filename>span[data-v-c8c40662]{display:flex;align-items:center;line-height:normal}a[data-v-c8c40662]{color:var(--url,var(--color-link))}.code-line-container[data-v-df963650]{display:flex}.code-number[data-v-df963650]{padding:0 1rem 0 8px;text-align:right;min-width:2em;color:#666;-webkit-user-select:none;-moz-user-select:none;user-select:none}.code-number[data-v-df963650]:before{content:attr(data-line-number)}.highlighted[data-v-df963650]{background:var(--line-highlight,var(--color-code-line-highlight));border-left:4px solid var(--color-code-line-highlight-border)}.highlighted .code-number[data-v-df963650]{padding-left:4px}pre[data-v-df963650]{padding:14px 0;display:flex;overflow:unset;-webkit-overflow-scrolling:touch;white-space:pre;word-wrap:normal;height:100%}@media only screen and (max-width:735px){pre[data-v-df963650]{padding-top:.82353rem}}code[data-v-df963650]{display:flex;flex-direction:column;white-space:pre;word-wrap:normal;flex-grow:9999}.code-line-container[data-v-df963650]{flex-shrink:0;padding-right:14px}.code-listing[data-v-df963650],.container-general[data-v-df963650]{display:flex}.code-listing[data-v-df963650]{flex-direction:column;min-height:100%;border-radius:4px;overflow:auto}.code-listing.single-line[data-v-df963650]{border-radius:4px}.container-general[data-v-df963650],pre[data-v-df963650]{flex-grow:1}code[data-v-05f4a5b7]{speak-punctuation:code}code[data-v-d68ae420]{width:100%}.container-general[data-v-d68ae420]{display:flex;flex-flow:row wrap}.container-general .code-line[data-v-d68ae420]{flex:1 0 auto}.code-line-container[data-v-d68ae420]{align-items:center;display:flex;border-left:4px solid transparent;counter-increment:linenumbers;padding-right:14px}.code-number[data-v-d68ae420]{font-size:.70588rem;line-height:1.5;font-weight:400;font-family:Menlo,monospace;padding:0 1rem 0 8px;text-align:right;min-width:2.01em;-webkit-user-select:none;-moz-user-select:none;user-select:none}.code-number[data-v-d68ae420]:before{content:counter(linenumbers)}.code-line[data-v-d68ae420]{display:flex}pre[data-v-d68ae420]{padding:14px 0;display:flex;flex-flow:row wrap;overflow:auto;-webkit-overflow-scrolling:touch;white-space:pre;word-wrap:normal}@media only screen and (max-width:735px){pre[data-v-d68ae420]{padding-top:.82353rem}}.collapsible-code-listing[data-v-d68ae420]{background:var(--background,var(--color-code-background));border-color:var(--colors-grid,var(--color-grid));color:var(--text,var(--color-code-plain));border-radius:4px;border-style:solid;border-width:1px;counter-reset:linenumbers;font-size:15px}.collapsible-code-listing.single-line[data-v-d68ae420]{border-radius:4px}.collapsible[data-v-d68ae420]{background:var(--color-code-collapsible-background);color:var(--color-code-collapsible-text)}.collapsed[data-v-d68ae420]:before{content:"⋯";display:inline-block;font-family:monospace;font-weight:700;height:100%;line-height:1;text-align:right;width:2.3rem}.collapsed .code-line-container[data-v-d68ae420]{height:0;visibility:hidden}.row[data-v-be73599c]{box-sizing:border-box;display:flex;flex-flow:row wrap}.col[data-v-2ee3ad8b]{box-sizing:border-box;flex:none}.xlarge-1[data-v-2ee3ad8b]{flex-basis:8.33333%;max-width:8.33333%}.xlarge-2[data-v-2ee3ad8b]{flex-basis:16.66667%;max-width:16.66667%}.xlarge-3[data-v-2ee3ad8b]{flex-basis:25%;max-width:25%}.xlarge-4[data-v-2ee3ad8b]{flex-basis:33.33333%;max-width:33.33333%}.xlarge-5[data-v-2ee3ad8b]{flex-basis:41.66667%;max-width:41.66667%}.xlarge-6[data-v-2ee3ad8b]{flex-basis:50%;max-width:50%}.xlarge-7[data-v-2ee3ad8b]{flex-basis:58.33333%;max-width:58.33333%}.xlarge-8[data-v-2ee3ad8b]{flex-basis:66.66667%;max-width:66.66667%}.xlarge-9[data-v-2ee3ad8b]{flex-basis:75%;max-width:75%}.xlarge-10[data-v-2ee3ad8b]{flex-basis:83.33333%;max-width:83.33333%}.xlarge-11[data-v-2ee3ad8b]{flex-basis:91.66667%;max-width:91.66667%}.xlarge-12[data-v-2ee3ad8b]{flex-basis:100%;max-width:100%}.xlarge-centered[data-v-2ee3ad8b]{margin-left:auto;margin-right:auto}.xlarge-uncentered[data-v-2ee3ad8b]{margin-left:0;margin-right:0}.large-1[data-v-2ee3ad8b]{flex-basis:8.33333%;max-width:8.33333%}.large-2[data-v-2ee3ad8b]{flex-basis:16.66667%;max-width:16.66667%}.large-3[data-v-2ee3ad8b]{flex-basis:25%;max-width:25%}.large-4[data-v-2ee3ad8b]{flex-basis:33.33333%;max-width:33.33333%}.large-5[data-v-2ee3ad8b]{flex-basis:41.66667%;max-width:41.66667%}.large-6[data-v-2ee3ad8b]{flex-basis:50%;max-width:50%}.large-7[data-v-2ee3ad8b]{flex-basis:58.33333%;max-width:58.33333%}.large-8[data-v-2ee3ad8b]{flex-basis:66.66667%;max-width:66.66667%}.large-9[data-v-2ee3ad8b]{flex-basis:75%;max-width:75%}.large-10[data-v-2ee3ad8b]{flex-basis:83.33333%;max-width:83.33333%}.large-11[data-v-2ee3ad8b]{flex-basis:91.66667%;max-width:91.66667%}.large-12[data-v-2ee3ad8b]{flex-basis:100%;max-width:100%}.large-centered[data-v-2ee3ad8b]{margin-left:auto;margin-right:auto}.large-uncentered[data-v-2ee3ad8b]{margin-left:0;margin-right:0}@media only screen and (max-width:1250px){.medium-1[data-v-2ee3ad8b]{flex-basis:8.33333%;max-width:8.33333%}.medium-2[data-v-2ee3ad8b]{flex-basis:16.66667%;max-width:16.66667%}.medium-3[data-v-2ee3ad8b]{flex-basis:25%;max-width:25%}.medium-4[data-v-2ee3ad8b]{flex-basis:33.33333%;max-width:33.33333%}.medium-5[data-v-2ee3ad8b]{flex-basis:41.66667%;max-width:41.66667%}.medium-6[data-v-2ee3ad8b]{flex-basis:50%;max-width:50%}.medium-7[data-v-2ee3ad8b]{flex-basis:58.33333%;max-width:58.33333%}.medium-8[data-v-2ee3ad8b]{flex-basis:66.66667%;max-width:66.66667%}.medium-9[data-v-2ee3ad8b]{flex-basis:75%;max-width:75%}.medium-10[data-v-2ee3ad8b]{flex-basis:83.33333%;max-width:83.33333%}.medium-11[data-v-2ee3ad8b]{flex-basis:91.66667%;max-width:91.66667%}.medium-12[data-v-2ee3ad8b]{flex-basis:100%;max-width:100%}.medium-centered[data-v-2ee3ad8b]{margin-left:auto;margin-right:auto}.medium-uncentered[data-v-2ee3ad8b]{margin-left:0;margin-right:0}}@media only screen and (max-width:735px){.small-1[data-v-2ee3ad8b]{flex-basis:8.33333%;max-width:8.33333%}.small-2[data-v-2ee3ad8b]{flex-basis:16.66667%;max-width:16.66667%}.small-3[data-v-2ee3ad8b]{flex-basis:25%;max-width:25%}.small-4[data-v-2ee3ad8b]{flex-basis:33.33333%;max-width:33.33333%}.small-5[data-v-2ee3ad8b]{flex-basis:41.66667%;max-width:41.66667%}.small-6[data-v-2ee3ad8b]{flex-basis:50%;max-width:50%}.small-7[data-v-2ee3ad8b]{flex-basis:58.33333%;max-width:58.33333%}.small-8[data-v-2ee3ad8b]{flex-basis:66.66667%;max-width:66.66667%}.small-9[data-v-2ee3ad8b]{flex-basis:75%;max-width:75%}.small-10[data-v-2ee3ad8b]{flex-basis:83.33333%;max-width:83.33333%}.small-11[data-v-2ee3ad8b]{flex-basis:91.66667%;max-width:91.66667%}.small-12[data-v-2ee3ad8b]{flex-basis:100%;max-width:100%}.small-centered[data-v-2ee3ad8b]{margin-left:auto;margin-right:auto}.small-uncentered[data-v-2ee3ad8b]{margin-left:0;margin-right:0}}.tabnav[data-v-42371214]{margin:.88235rem 0 1.47059rem 0}.tabnav-items[data-v-42371214]{display:inline-block;margin:0;text-align:center}.tabnav-item[data-v-723a9588]{border-bottom:1px solid;border-color:var(--colors-tabnav-item-border-color,var(--color-tabnav-item-border-color));display:inline-block;list-style:none;padding-left:1.76471rem;margin:0;outline:none}.tabnav-item[data-v-723a9588]:first-child{padding-left:0}.tabnav-item[data-v-723a9588]:nth-child(n+1){margin:0}.tabnav-link[data-v-723a9588]{color:var(--colors-secondary-label,var(--color-secondary-label));font-size:1rem;line-height:1;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;padding:9px 0 11px;margin-top:2px;margin-bottom:4px;text-align:left;text-decoration:none;display:block;position:relative;z-index:0}.tabnav-link[data-v-723a9588]:hover{text-decoration:none}.tabnav-link[data-v-723a9588]:focus{outline-offset:-1px}.tabnav-link[data-v-723a9588]:after{content:"";position:absolute;bottom:-5px;left:0;width:100%;border:1px solid transparent}.tabnav-link.active[data-v-723a9588]{color:var(--colors-text,var(--color-text));cursor:default;z-index:10}.tabnav-link.active[data-v-723a9588]:after{border-bottom-color:var(--colors-text,var(--color-text))}.controls[data-v-6197ce3f]{margin-top:5px;font-size:14px;display:flex;justify-content:flex-end}.controls a[data-v-6197ce3f]{color:var(--colors-text,var(--color-text));display:flex;align-items:center}.controls .control-icon[data-v-6197ce3f]{width:1.05em;margin-right:.3em}[data-v-7be42fb4] figcaption+*{margin-top:1rem}.caption[data-v-0bcb8b58]{font-size:.82353rem;line-height:1.5;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}[data-v-0bcb8b58] p{display:inline-block}[data-v-3a939631] img{max-width:100%}*+.table-wrapper,.table-wrapper+*{margin-top:1.6em}.nav-menu-items[data-v-67c1c0a5]{display:flex;justify-content:flex-end}.nav--in-breakpoint-range .nav-menu-items[data-v-67c1c0a5]{display:block;opacity:0;padding:1rem 1.88235rem 1.64706rem 1.88235rem;transform:translate3d(0,-50px,0);transition:transform 1s cubic-bezier(.07,1.06,.27,.95) .5s,opacity .7s cubic-bezier(.07,1.06,.27,.95) .2s}.nav--is-open.nav--in-breakpoint-range .nav-menu-items[data-v-67c1c0a5]{opacity:1;transform:translateZ(0);transition-delay:.2s,.4s}.nav--in-breakpoint-range .nav-menu-items[data-v-67c1c0a5]:not(:only-child):not(:last-child){padding-bottom:0}.nav--in-breakpoint-range .nav-menu-items[data-v-67c1c0a5]:not(:only-child):last-child{padding-top:0}.table-wrapper[data-v-358dcd5e]{overflow:auto;-webkit-overflow-scrolling:touch}[data-v-358dcd5e] th{font-weight:600}[data-v-358dcd5e] td,[data-v-358dcd5e] th{border-color:var(--color-fill-gray-tertiary);border-style:solid;border-width:1px 0;padding:.58824rem}.nav[data-v-be9ec8e8]{position:sticky;top:0;width:100%;height:3.05882rem;z-index:9997;--nav-padding:1.29412rem;color:var(--color-nav-color)}@media only screen and (max-width:767px){.nav[data-v-be9ec8e8]{min-width:320px;height:2.82353rem}}.theme-dark.nav[data-v-be9ec8e8]{background:none;color:var(--color-nav-dark-color)}.nav__wrapper[data-v-be9ec8e8]{position:absolute;top:0;left:0;width:100%;height:auto;min-height:100%;z-index:1}.nav__background[data-v-be9ec8e8]{position:absolute;left:0;top:0;width:100%;height:100%;z-index:1;transition:background-color 0s ease-in}.nav__background[data-v-be9ec8e8]:after{background-color:var(--color-nav-keyline)}.nav--no-bg-transition .nav__background[data-v-be9ec8e8]{transition:none!important}.nav--solid-background .nav__background[data-v-be9ec8e8]{background-color:var(--color-nav-solid-background);-webkit-backdrop-filter:none;backdrop-filter:none}.nav--is-open.nav--solid-background .nav__background[data-v-be9ec8e8],.nav--is-sticking.nav--solid-background .nav__background[data-v-be9ec8e8]{background-color:var(--color-nav-solid-background)}.nav--is-open.theme-dark.nav--solid-background .nav__background[data-v-be9ec8e8],.nav--is-sticking.theme-dark.nav--solid-background .nav__background[data-v-be9ec8e8],.theme-dark.nav--solid-background .nav__background[data-v-be9ec8e8]{background-color:var(--color-nav-dark-solid-background)}.nav--in-breakpoint-range .nav__background[data-v-be9ec8e8]{min-height:2.82353rem;transition:background-color 0s ease .7s}.nav--is-sticking .nav__background[data-v-be9ec8e8]{background-color:var(--color-nav-expanded);max-height:none;transition:background-color 0s ease;transition-property:background-color,-webkit-backdrop-filter;transition-property:background-color,backdrop-filter;transition-property:background-color,backdrop-filter,-webkit-backdrop-filter}.nav--is-sticking .nav__background[data-v-be9ec8e8]:after{background-color:var(--color-nav-sticking-expanded-keyline)}@supports ((-webkit-backdrop-filter:initial) or (backdrop-filter:initial)){.nav--is-sticking .nav__background[data-v-be9ec8e8]{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:var(--color-nav-uiblur-stuck)}}.theme-dark.nav--is-sticking .nav__background[data-v-be9ec8e8]{background-color:var(--color-nav-dark-stuck)}@supports ((-webkit-backdrop-filter:initial) or (backdrop-filter:initial)){.theme-dark.nav--is-sticking .nav__background[data-v-be9ec8e8]{background-color:var(--color-nav-dark-uiblur-stuck)}}.nav--is-open .nav__background[data-v-be9ec8e8]{background-color:var(--color-nav-expanded);max-height:none;transition:background-color 0s ease;transition-property:background-color,-webkit-backdrop-filter;transition-property:background-color,backdrop-filter;transition-property:background-color,backdrop-filter,-webkit-backdrop-filter}.nav--is-open .nav__background[data-v-be9ec8e8]:after{background-color:var(--color-nav-sticking-expanded-keyline)}@supports ((-webkit-backdrop-filter:initial) or (backdrop-filter:initial)){.nav--is-open .nav__background[data-v-be9ec8e8]{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:var(--color-nav-uiblur-expanded)}}.theme-dark.nav--is-open .nav__background[data-v-be9ec8e8]{background-color:var(--color-nav-dark-expanded)}@supports ((-webkit-backdrop-filter:initial) or (backdrop-filter:initial)){.theme-dark.nav--is-open .nav__background[data-v-be9ec8e8]{background-color:var(--color-nav-dark-uiblur-expanded)}}.theme-dark .nav__background[data-v-be9ec8e8]:after{background-color:var(--color-nav-dark-keyline)}.nav--is-open.theme-dark .nav__background[data-v-be9ec8e8]:after,.nav--is-sticking.theme-dark .nav__background[data-v-be9ec8e8]:after{background-color:var(--color-nav-dark-sticking-expanded-keyline)}.nav__background[data-v-be9ec8e8]:after{content:"";display:block;position:absolute;top:100%;left:50%;transform:translateX(-50%);width:980px;height:1px;z-index:1}@media only screen and (max-width:1023px){.nav__background[data-v-be9ec8e8]:after{width:100%}}.nav--noborder .nav__background[data-v-be9ec8e8]:after{display:none}.nav--is-sticking.nav--noborder .nav__background[data-v-be9ec8e8]:after{display:block}.nav--fullwidth-border .nav__background[data-v-be9ec8e8]:after,.nav--is-open .nav__background[data-v-be9ec8e8]:after,.nav--is-sticking .nav__background[data-v-be9ec8e8]:after,.nav--solid-background .nav__background[data-v-be9ec8e8]:after{width:100%}.nav-overlay[data-v-be9ec8e8]{position:fixed;left:0;right:0;top:0;display:block;opacity:0}.nav--is-open .nav-overlay[data-v-be9ec8e8]{background-color:rgba(51,51,51,.4);transition:opacity .7s cubic-bezier(.07,1.06,.27,.95) .2s;bottom:0;opacity:1}.nav-wrapper[data-v-be9ec8e8]{position:absolute;top:0;left:0;width:100%;height:auto;min-height:100%;z-index:1}.pre-title[data-v-be9ec8e8],.pre-title[data-v-be9ec8e8]:empty{display:none}.nav--in-breakpoint-range .pre-title[data-v-be9ec8e8]{display:flex;padding:0}.nav-content[data-v-be9ec8e8]{display:flex;padding:0 var(--nav-padding);max-width:980px;margin:0 auto;position:relative;z-index:2;justify-content:space-between}.nav--is-wide-format .nav-content[data-v-be9ec8e8]{box-sizing:border-box;max-width:1920px;margin-left:auto;margin-right:auto}@supports (padding:calc(max(0px))){.nav-content[data-v-be9ec8e8]{padding-left:calc(max(var(--nav-padding), env(safe-area-inset-left)));padding-right:calc(max(var(--nav-padding), env(safe-area-inset-right)))}}@media only screen and (max-width:767px){.nav-content[data-v-be9ec8e8]{padding:0 0 0 .94118rem}}.nav--in-breakpoint-range .nav-content[data-v-be9ec8e8]{display:grid;grid-template-columns:auto 1fr auto;grid-auto-rows:minmax(-webkit-min-content,-webkit-max-content);grid-auto-rows:minmax(min-content,max-content);grid-template-areas:"pre-title title actions" "menu menu menu"}.nav-menu[data-v-be9ec8e8]{font-size:.70588rem;line-height:1;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;flex:1 1 auto;display:flex;padding-top:10px;min-width:0}@media only screen and (max-width:767px){.nav-menu[data-v-be9ec8e8]{font-size:.82353rem;line-height:1;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.nav--in-breakpoint-range .nav-menu[data-v-be9ec8e8]{font-size:.82353rem;line-height:1;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;padding-top:0;grid-area:menu}.nav-menu-tray[data-v-be9ec8e8]{width:100%;max-width:100%;align-items:center;display:flex;justify-content:space-between}.nav--in-breakpoint-range .nav-menu-tray[data-v-be9ec8e8]{display:block;overflow:hidden;pointer-events:none;visibility:hidden;max-height:0;transition:max-height .4s ease-in 0s,visibility 0s linear 1s}.nav--is-open.nav--in-breakpoint-range .nav-menu-tray[data-v-be9ec8e8]{max-height:calc(100vh - 5.64706rem);overflow-y:auto;-webkit-overflow-scrolling:touch;pointer-events:auto;visibility:visible;transition-delay:.2s,0s}.nav--is-transitioning.nav--is-open.nav--in-breakpoint-range .nav-menu-tray[data-v-be9ec8e8]{overflow-y:hidden}.nav--is-sticking.nav--is-open.nav--in-breakpoint-range .nav-menu-tray[data-v-be9ec8e8]{max-height:calc(100vh - 2.82353rem)}.nav-actions[data-v-be9ec8e8]{display:flex;align-items:center}.nav--in-breakpoint-range .nav-actions[data-v-be9ec8e8]{grid-area:actions;justify-content:flex-end}@media only screen and (max-width:767px){.nav-actions[data-v-be9ec8e8]{padding-right:.94118rem}}.nav-title[data-v-be9ec8e8]{height:3.05882rem;font-size:1.11765rem;line-height:1.42105;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;cursor:default;display:flex;align-items:center;white-space:nowrap;box-sizing:border-box}@media only screen and (max-width:767px){.nav-title[data-v-be9ec8e8]{padding-top:0;height:2.82353rem;width:90%}}.nav--in-breakpoint-range .nav-title[data-v-be9ec8e8]{grid-area:title}.nav--is-wide-format.nav--in-breakpoint-range .nav-title[data-v-be9ec8e8]{width:100%;justify-content:center}.nav-title[data-v-be9ec8e8] span{height:100%;line-height:normal}.nav-title a[data-v-be9ec8e8]{display:inline-block;letter-spacing:inherit;line-height:normal;margin:0;text-decoration:none;white-space:nowrap}.nav-title a[data-v-be9ec8e8]:hover{text-decoration:none}@media only screen and (max-width:767px){.nav-title a[data-v-be9ec8e8]{display:flex}}.nav-title[data-v-be9ec8e8],.nav-title a[data-v-be9ec8e8]{color:var(--color-figure-gray);transition:color 0s ease-in}.nav--is-open.theme-dark .nav-title[data-v-be9ec8e8],.nav--is-open.theme-dark .nav-title a[data-v-be9ec8e8],.nav--is-sticking.theme-dark .nav-title[data-v-be9ec8e8],.nav--is-sticking.theme-dark .nav-title a[data-v-be9ec8e8],.theme-dark .nav-title[data-v-be9ec8e8],.theme-dark .nav-title a[data-v-be9ec8e8]{color:var(--color-nav-dark-link-color)}.nav-ax-toggle[data-v-be9ec8e8]{display:none;position:absolute;top:0;left:0;width:1px;height:1px;z-index:10}.nav-ax-toggle[data-v-be9ec8e8]:focus{outline-offset:-6px;width:100%;height:100%}.nav--in-breakpoint-range .nav-ax-toggle[data-v-be9ec8e8]{display:block}.nav-menucta[data-v-be9ec8e8]{cursor:pointer;display:none;align-items:center;overflow:hidden;width:1.17647rem;-webkit-tap-highlight-color:transparent;height:2.82353rem}.nav--in-breakpoint-range .nav-menucta[data-v-be9ec8e8]{display:flex}.nav-menucta-chevron[data-v-be9ec8e8]{display:block;position:relative;width:100%;height:.70588rem;transition:transform .3s linear}.nav-menucta-chevron[data-v-be9ec8e8]:after,.nav-menucta-chevron[data-v-be9ec8e8]:before{content:"";display:block;position:absolute;top:.58824rem;width:.70588rem;height:.05882rem;transition:transform .3s linear;background:var(--color-figure-gray)}.nav-menucta-chevron[data-v-be9ec8e8]:before{right:50%;border-radius:.5px 0 0 .5px}.nav-menucta-chevron[data-v-be9ec8e8]:after{left:50%;border-radius:0 .5px .5px 0}.nav-menucta-chevron[data-v-be9ec8e8]:before{transform-origin:100% 100%;transform:rotate(40deg) scaleY(1.5)}.nav-menucta-chevron[data-v-be9ec8e8]:after{transform-origin:0 100%;transform:rotate(-40deg) scaleY(1.5)}.nav--is-open .nav-menucta-chevron[data-v-be9ec8e8]{transform:scaleY(-1)}.theme-dark .nav-menucta-chevron[data-v-be9ec8e8]:after,.theme-dark .nav-menucta-chevron[data-v-be9ec8e8]:before{background:var(--color-nav-dark-link-color)}[data-v-be9ec8e8] .nav-menu-link{color:var(--color-nav-link-color)}[data-v-be9ec8e8] .nav-menu-link:hover{color:var(--color-nav-link-color-hover);text-decoration:none}.theme-dark[data-v-be9ec8e8] .nav-menu-link{color:var(--color-nav-dark-link-color)}.theme-dark[data-v-be9ec8e8] .nav-menu-link:hover{color:var(--color-nav-dark-link-color-hover)}[data-v-be9ec8e8] .nav-menu-link.current{color:var(--color-nav-current-link);cursor:default}[data-v-be9ec8e8] .nav-menu-link.current:hover{color:var(--color-nav-current-link)}.theme-dark[data-v-be9ec8e8] .nav-menu-link.current,.theme-dark[data-v-be9ec8e8] .nav-menu-link.current:hover{color:var(--color-nav-dark-current-link)}s[data-v-eb91ce54]:after,s[data-v-eb91ce54]:before{position:absolute;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(0 0 99.9% 99.9%);clip-path:inset(0 0 99.9% 99.9%);overflow:hidden;height:1px;width:1px;padding:0;border:0}s[data-v-eb91ce54]:before{content:" [start of stricken text] "}s[data-v-eb91ce54]:after{content:" [end of stricken text] "}.nav-menu-item[data-v-66cbfe4c]{margin-left:1.41176rem;list-style:none;min-width:0}.nav--in-breakpoint-range .nav-menu-item[data-v-66cbfe4c]{margin-left:0;width:100%;min-height:2.47059rem}.nav--in-breakpoint-range .nav-menu-item[data-v-66cbfe4c]:first-child .nav-menu-link{border-top:0}.nav--in-breakpoint-range .nav-menu-item--animated[data-v-66cbfe4c]{opacity:0;transform:none;transition:.5s ease;transition-property:transform,opacity}.nav--is-open.nav--in-breakpoint-range .nav-menu-item--animated[data-v-66cbfe4c]{opacity:1;transform:translateZ(0);transition-delay:0s}.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="0"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="1"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="2"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="3"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="4"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="5"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="6"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:first-child,.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(2),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(3),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(4),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(5),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(6),.nav--is-open.nav--in-breakpoint-range [data-previous-menu-children-count="7"] .nav-menu-item--animated[data-v-66cbfe4c]:nth-child(7){transition-delay:0s}.button-cta[data-v-494ad9c8]{border-radius:var(--style-button-borderRadius,4px);background:var(--colors-button-light-background,var(--color-button-background));color:var(--colors-button-text,var(--color-button-text));cursor:pointer;min-width:1.76471rem;padding:.23529rem .88235rem;text-align:center;white-space:nowrap;display:inline-block;font-size:1rem;line-height:1.47059;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.button-cta[data-v-494ad9c8]:active{background:var(--colors-button-light-backgroundActive,var(--color-button-background-active));outline:none}.button-cta[data-v-494ad9c8]:hover:not([disabled]){background:var(--colors-button-light-backgroundHover,var(--color-button-background-hover));text-decoration:none}.button-cta[data-v-494ad9c8]:disabled{opacity:.32;cursor:default}.fromkeyboard .button-cta[data-v-494ad9c8]:focus{box-shadow:0 0 0 4px var(--color-focus-color);outline:none}.button-cta.is-dark[data-v-494ad9c8]{background:var(--colors-button-dark-background,#06f)}.button-cta.is-dark[data-v-494ad9c8]:active{background:var(--colors-button-dark-backgroundActive,var(--color-button-background-active))}.button-cta.is-dark[data-v-494ad9c8]:hover:not([disabled]){background:var(--colors-button-dark-backgroundHover,var(--color-button-background-hover))}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/css/index.12bb178a.css b/docs/docc/Reducer.doccarchive/css/index.12bb178a.css
deleted file mode 100644
index 381df10..0000000
--- a/docs/docc/Reducer.doccarchive/css/index.12bb178a.css
+++ /dev/null
@@ -1,9 +0,0 @@
-/*!
- * This source file is part of the Swift.org open source project
- *
- * Copyright (c) 2021 Apple Inc. and the Swift project authors
- * Licensed under Apache License v2.0 with Runtime Library Exception
- *
- * See https://swift.org/LICENSE.txt for license information
- * See https://swift.org/CONTRIBUTORS.txt for Swift project authors
- */.color-scheme-toggle[data-v-4472ec1e]{--toggle-color-fill:var(--color-button-background);--toggle-color-text:var(--color-fill-blue);font-size:.70588rem;line-height:1.33333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;border:1px solid var(--toggle-color-fill);border-radius:var(--toggle-border-radius-outer,4px);display:inline-flex;padding:1px}@media screen{[data-color-scheme=dark] .color-scheme-toggle[data-v-4472ec1e]{--toggle-color-text:var(--color-figure-blue)}}@media screen and (prefers-color-scheme:dark){[data-color-scheme=auto] .color-scheme-toggle[data-v-4472ec1e]{--toggle-color-text:var(--color-figure-blue)}}input[data-v-4472ec1e]{position:absolute;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(0 0 99.9% 99.9%);clip-path:inset(0 0 99.9% 99.9%);overflow:hidden;height:1px;width:1px;padding:0;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.text[data-v-4472ec1e]{border:1px solid transparent;border-radius:var(--toggle-border-radius-inner,2px);color:var(--toggle-color-text);display:inline-block;text-align:center;padding:1px 6px;min-width:42px;box-sizing:border-box}.text[data-v-4472ec1e]:hover{cursor:pointer}input:checked+.text[data-v-4472ec1e]{--toggle-color-text:var(--color-button-text);background:var(--toggle-color-fill);border-color:var(--toggle-color-fill)}.footer[data-v-72f2e2dc]{border-top:1px solid var(--color-grid)}.row[data-v-72f2e2dc]{margin-left:auto;margin-right:auto;width:980px;display:flex;flex-direction:row-reverse;padding:20px 0}@media only screen and (max-width:1250px){.row[data-v-72f2e2dc]{width:692px}}@media only screen and (max-width:735px){.row[data-v-72f2e2dc]{width:87.5%;width:100%;padding:20px .94118rem;box-sizing:border-box}}.InitialLoadingPlaceholder[data-v-35c356b6]{background:var(--colors-loading-placeholder-background,var(--color-loading-placeholder-background));height:100vh;width:100%}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;background-color:var(--colors-text-background,var(--color-text-background));height:100%}abbr,blockquote,body,button,dd,dl,dt,fieldset,figure,form,h1,h2,h3,h4,h5,h6,hgroup,input,legend,li,ol,p,pre,ul{margin:0;padding:0}address,caption,code,figcaption,pre,th{font-size:1em;font-weight:400;font-style:normal}fieldset,iframe,img{border:0}caption,th{text-align:left}table{border-collapse:collapse;border-spacing:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}button{background:none;border:0;box-sizing:content-box;color:inherit;cursor:pointer;font:inherit;line-height:inherit;overflow:visible;vertical-align:inherit}button:disabled{cursor:default}:focus{outline:4px solid var(--color-focus-color);outline-offset:1px}::-moz-focus-inner{border:0;padding:0}@media print{#content,#main,body{color:#000}a,a:link,a:visited{color:#000;text-decoration:none}.hide,.noprint{display:none}}body{height:100%;min-width:320px}html{font:var(--typography-html-font,17px "Helvetica Neue","Helvetica","Arial",sans-serif);quotes:"“" "”"}body{font-size:1rem;line-height:1.47059;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;background-color:var(--color-text-background);color:var(--colors-text,var(--color-text));font-style:normal;word-wrap:break-word}body,button,input,select,textarea{font-synthesis:none;-moz-font-feature-settings:"kern";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;direction:ltr;text-align:left}h1,h2,h3,h4,h5,h6{color:var(--colors-header-text,var(--color-header-text))}h1+*,h2+*,h3+*,h4+*,h5+*,h6+*{margin-top:.8em}h1+h1,h1+h2,h1+h3,h1+h4,h1+h5,h1+h6,h2+h1,h2+h2,h2+h3,h2+h4,h2+h5,h2+h6,h3+h1,h3+h2,h3+h3,h3+h4,h3+h5,h3+h6,h4+h1,h4+h2,h4+h3,h4+h4,h4+h5,h4+h6,h5+h1,h5+h2,h5+h3,h5+h4,h5+h5,h5+h6,h6+h1,h6+h2,h6+h3,h6+h4,h6+h5,h6+h6{margin-top:.4em}ol+h1,ol+h2,ol+h3,ol+h4,ol+h5,ol+h6,p+h1,p+h2,p+h3,p+h4,p+h5,p+h6,ul+h1,ul+h2,ul+h3,ul+h4,ul+h5,ul+h6{margin-top:1.6em}ol+*,p+*,ul+*{margin-top:.8em}ol,ul{margin-left:1.17647em}ol ol,ol ul,ul ol,ul ul{margin-top:0;margin-bottom:0}nav ol,nav ul{margin:0;list-style:none}li li{font-size:1em}a{color:var(--colors-link,var(--color-link))}a:link,a:visited{text-decoration:none}a:hover{text-decoration:underline}a:active{text-decoration:none}p+a{display:inline-block}b,strong{font-weight:600}cite,dfn,em,i{font-style:italic}sup{font-size:.6em;vertical-align:top;position:relative;bottom:-.2em}h1 sup,h2 sup,h3 sup{font-size:.4em}sup a{vertical-align:inherit;color:inherit}sup a:hover{color:var(--figure-blue);text-decoration:none}sub{line-height:1}abbr{border:0}pre{overflow:auto;-webkit-overflow-scrolling:auto;white-space:pre;word-wrap:normal}code{font-family:Menlo,monospace;font-weight:inherit;letter-spacing:0}.syntax-comment{color:var(--syntax-comment,var(--color-syntax-comments))}.syntax-quote{color:var(--syntax-quote,var(--color-syntax-comments))}.syntax-keyword{color:var(--syntax-keyword,var(--color-syntax-keywords))}.syntax-literal{color:var(--syntax-literal,var(--color-syntax-keywords))}.syntax-selector-tag{color:var(--syntax-selector-tag,var(--color-syntax-keywords))}.syntax-string{color:var(--syntax-string,var(--color-syntax-strings))}.syntax-bullet{color:var(--syntax-bullet,var(--color-syntax-characters))}.syntax-meta{color:var(--syntax-meta,var(--color-syntax-characters))}.syntax-number{color:var(--syntax-number,var(--color-syntax-characters))}.syntax-symbol{color:var(--syntax-symbol,var(--color-syntax-characters))}.syntax-tag{color:var(--syntax-tag,var(--color-syntax-characters))}.syntax-attr{color:var(--syntax-attr,var(--color-syntax-other-type-names))}.syntax-built_in{color:var(--syntax-built_in,var(--color-syntax-other-type-names))}.syntax-builtin-name{color:var(--syntax-builtin-name,var(--color-syntax-other-type-names))}.syntax-class{color:var(--syntax-class,var(--color-syntax-other-type-names))}.syntax-params{color:var(--syntax-params,var(--color-syntax-other-type-names))}.syntax-section{color:var(--syntax-section,var(--color-syntax-other-type-names))}.syntax-title{color:var(--syntax-title,var(--color-syntax-other-type-names))}.syntax-type{color:var(--syntax-type,var(--color-syntax-other-type-names))}.syntax-attribute{color:var(--syntax-attribute,var(--color-syntax-plain-text))}.syntax-identifier{color:var(--syntax-identifier,var(--color-syntax-plain-text))}.syntax-subst{color:var(--syntax-subst,var(--color-syntax-plain-text))}.syntax-doctag,.syntax-strong{font-weight:700}.syntax-emphasis,.syntax-link{font-style:italic}[data-syntax=swift] .syntax-meta{color:var(--syntax-meta,var(--color-syntax-keywords))}[data-syntax=swift] .syntax-class,[data-syntax=swift] .syntax-keyword+.syntax-params,[data-syntax=swift] .syntax-params+.syntax-params{color:unset}[data-syntax=json] .syntax-attr{color:var(--syntax-attr,var(--color-syntax-strings))}#skip-nav{position:absolute;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(0 0 99.9% 99.9%);clip-path:inset(0 0 99.9% 99.9%);overflow:hidden;height:1px;width:1px;padding:0;border:0}#skip-nav:active,#skip-nav:focus{position:relative;float:left;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;color:var(--color-figure-blue);font-size:1em;padding:0 10px;z-index:100000;top:0;left:0;height:44px;line-height:44px;-webkit-clip-path:unset;clip-path:unset}.nav--in-breakpoint-range #skip-nav{display:none}.visuallyhidden{position:absolute;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(0 0 99.9% 99.9%);clip-path:inset(0 0 99.9% 99.9%);overflow:hidden;height:1px;width:1px;padding:0;border:0}.changed{border:1px solid var(--color-changes-modified);border-radius:4px;position:relative}.changed.has-multiple-lines,.has-multiple-lines .changed{border-radius:4px}.changed:after{left:8px;background-image:url(../img/modified-icon.f496e73d.svg);background-repeat:no-repeat;bottom:0;content:" ";margin:auto;margin-right:8px;position:absolute;top:0;width:1.17647rem;height:1.17647rem;margin-top:.61765rem;z-index:2}@media screen{[data-color-scheme=dark] .changed:after{background-image:url(../img/modified-icon.f496e73d.svg)}}@media screen and (prefers-color-scheme:dark){[data-color-scheme=auto] .changed:after{background-image:url(../img/modified-icon.f496e73d.svg)}}.changed-added{border-color:var(--color-changes-added)}.changed-added:after{background-image:url(../img/added-icon.d6f7e47d.svg)}@media screen{[data-color-scheme=dark] .changed-added:after{background-image:url(../img/added-icon.d6f7e47d.svg)}}@media screen and (prefers-color-scheme:dark){[data-color-scheme=auto] .changed-added:after{background-image:url(../img/added-icon.d6f7e47d.svg)}}.changed-deprecated{border-color:var(--color-changes-deprecated)}.changed-deprecated:after{background-image:url(../img/deprecated-icon.015b4f17.svg)}@media screen{[data-color-scheme=dark] .changed-deprecated:after{background-image:url(../img/deprecated-icon.015b4f17.svg)}}@media screen and (prefers-color-scheme:dark){[data-color-scheme=auto] .changed-deprecated:after{background-image:url(../img/deprecated-icon.015b4f17.svg)}}.changed.link-block:after,.changed.relationships-item:after,.link-block .changed:after{margin-top:10px}.change-added,.change-removed{padding:2px 0}.change-removed{background-color:var(--color-highlight-red)}.change-added{background-color:var(--color-highlight-green)}body{color-scheme:light dark}body[data-color-scheme=light]{color-scheme:light}body[data-color-scheme=dark]{color-scheme:dark}body{--color-fill:#fff;--color-fill-secondary:#f7f7f7;--color-fill-tertiary:#f0f0f0;--color-fill-quaternary:#282828;--color-fill-blue:#00f;--color-fill-light-blue-secondary:#d1d1ff;--color-fill-gray:#ccc;--color-fill-gray-secondary:#f5f5f5;--color-fill-gray-tertiary:#f0f0f0;--color-fill-gray-quaternary:#f0f0f0;--color-fill-green-secondary:#f0fff0;--color-fill-orange-secondary:#fffaf6;--color-fill-red-secondary:#fff0f5;--color-figure-blue:#36f;--color-figure-gray:#000;--color-figure-gray-secondary:#666;--color-figure-gray-secondary-alt:#666;--color-figure-gray-tertiary:#666;--color-figure-green:green;--color-figure-light-gray:#666;--color-figure-orange:#c30;--color-figure-red:red;--color-tutorials-teal:#000;--color-article-background:var(--color-fill-tertiary);--color-article-body-background:var(--color-fill);--color-aside-deprecated:var(--color-figure-gray);--color-aside-deprecated-background:var(--color-fill-orange-secondary);--color-aside-deprecated-border:var(--color-figure-orange);--color-aside-experiment:var(--color-figure-gray);--color-aside-experiment-background:var(--color-fill-gray-secondary);--color-aside-experiment-border:var(--color-figure-light-gray);--color-aside-important:var(--color-figure-gray);--color-aside-important-background:var(--color-fill-gray-secondary);--color-aside-important-border:var(--color-figure-light-gray);--color-aside-note:var(--color-figure-gray);--color-aside-note-background:var(--color-fill-gray-secondary);--color-aside-note-border:var(--color-figure-light-gray);--color-aside-tip:var(--color-figure-gray);--color-aside-tip-background:var(--color-fill-gray-secondary);--color-aside-tip-border:var(--color-figure-light-gray);--color-aside-warning:var(--color-figure-gray);--color-aside-warning-background:var(--color-fill-red-secondary);--color-aside-warning-border:var(--color-figure-red);--color-badge-default:var(--color-figure-light-gray);--color-badge-beta:var(--color-figure-gray-tertiary);--color-badge-deprecated:var(--color-figure-orange);--color-badge-dark-default:#fff;--color-badge-dark-beta:#b0b0b0;--color-badge-dark-deprecated:#f60;--color-button-background:var(--color-fill-blue);--color-button-background-active:#36f;--color-button-background-hover:var(--color-figure-blue);--color-button-text:#fff;--color-call-to-action-background:var(--color-fill-secondary);--color-changes-added:var(--color-figure-light-gray);--color-changes-added-hover:var(--color-figure-light-gray);--color-changes-deprecated:var(--color-figure-light-gray);--color-changes-deprecated-hover:var(--color-figure-light-gray);--color-changes-modified:var(--color-figure-light-gray);--color-changes-modified-hover:var(--color-figure-light-gray);--color-changes-modified-previous-background:var(--color-fill);--color-code-background:var(--color-fill-secondary);--color-code-collapsible-background:var(--color-fill-tertiary);--color-code-collapsible-text:var(--color-figure-gray-secondary-alt);--color-code-line-highlight:rgba(51,102,255,0.08);--color-code-line-highlight-border:var(--color-figure-blue);--color-code-plain:var(--color-figure-gray);--color-dropdown-background:hsla(0,0%,100%,0.8);--color-dropdown-border:#ccc;--color-dropdown-option-text:#666;--color-dropdown-text:#000;--color-dropdown-dark-background:hsla(0,0%,100%,0.1);--color-dropdown-dark-border:hsla(0,0%,94.1%,0.2);--color-dropdown-dark-option-text:#ccc;--color-dropdown-dark-text:#fff;--color-eyebrow:var(--color-figure-gray-secondary);--color-focus-border-color:var(--color-fill-blue);--color-focus-color:rgba(0,125,250,0.6);--color-form-error:var(--color-figure-red);--color-form-error-background:var(--color-fill-red-secondary);--color-form-valid:var(--color-figure-green);--color-form-valid-background:var(--color-fill-green-secondary);--color-generic-modal-background:var(--color-fill);--color-grid:var(--color-fill-gray);--color-header-text:var(--color-figure-gray);--color-hero-eyebrow:#ccc;--color-link:var(--color-figure-blue);--color-loading-placeholder-background:var(--color-fill);--color-nav-color:#666;--color-nav-current-link:rgba(0,0,0,0.6);--color-nav-expanded:#fff;--color-nav-hierarchy-collapse-background:#f0f0f0;--color-nav-hierarchy-collapse-borders:#ccc;--color-nav-hierarchy-item-borders:#ccc;--color-nav-keyline:rgba(0,0,0,0.2);--color-nav-link-color:#000;--color-nav-link-color-hover:#36f;--color-nav-outlines:#ccc;--color-nav-rule:hsla(0,0%,94.1%,0.5);--color-nav-solid-background:#fff;--color-nav-sticking-expanded-keyline:rgba(0,0,0,0.1);--color-nav-stuck:hsla(0,0%,100%,0.9);--color-nav-uiblur-expanded:hsla(0,0%,100%,0.9);--color-nav-uiblur-stuck:hsla(0,0%,100%,0.7);--color-nav-root-subhead:var(--color-tutorials-teal);--color-nav-dark-border-top-color:hsla(0,0%,100%,0.4);--color-nav-dark-color:#b0b0b0;--color-nav-dark-current-link:hsla(0,0%,100%,0.6);--color-nav-dark-expanded:#2a2a2a;--color-nav-dark-hierarchy-collapse-background:#424242;--color-nav-dark-hierarchy-collapse-borders:#666;--color-nav-dark-hierarchy-item-borders:#424242;--color-nav-dark-keyline:rgba(66,66,66,0.95);--color-nav-dark-link-color:#fff;--color-nav-dark-link-color-hover:#09f;--color-nav-dark-outlines:#575757;--color-nav-dark-rule:#575757;--color-nav-dark-solid-background:#000;--color-nav-dark-sticking-expanded-keyline:rgba(66,66,66,0.7);--color-nav-dark-stuck:rgba(42,42,42,0.9);--color-nav-dark-uiblur-expanded:rgba(42,42,42,0.9);--color-nav-dark-uiblur-stuck:rgba(42,42,42,0.7);--color-nav-dark-root-subhead:#fff;--color-runtime-preview-background:var(--color-fill-tertiary);--color-runtime-preview-disabled-text:hsla(0,0%,40%,0.6);--color-runtime-preview-text:var(--color-figure-gray-secondary);--color-secondary-label:var(--color-figure-gray-secondary);--color-step-background:var(--color-fill-secondary);--color-step-caption:var(--color-figure-gray-secondary);--color-step-focused:var(--color-figure-light-gray);--color-step-text:var(--color-figure-gray-secondary);--color-svg-icon:#666;--color-syntax-attributes:#947100;--color-syntax-characters:#272ad8;--color-syntax-comments:#707f8c;--color-syntax-documentation-markup:#506375;--color-syntax-documentation-markup-keywords:#506375;--color-syntax-heading:#ba2da2;--color-syntax-keywords:#ad3da4;--color-syntax-marks:#000;--color-syntax-numbers:#272ad8;--color-syntax-other-class-names:#703daa;--color-syntax-other-constants:#4b21b0;--color-syntax-other-declarations:#047cb0;--color-syntax-other-function-and-method-names:#4b21b0;--color-syntax-other-instance-variables-and-globals:#703daa;--color-syntax-other-preprocessor-macros:#78492a;--color-syntax-other-type-names:#703daa;--color-syntax-param-internal-name:#404040;--color-syntax-plain-text:#000;--color-syntax-preprocessor-statements:#78492a;--color-syntax-project-class-names:#3e8087;--color-syntax-project-constants:#2d6469;--color-syntax-project-function-and-method-names:#2d6469;--color-syntax-project-instance-variables-and-globals:#3e8087;--color-syntax-project-preprocessor-macros:#78492a;--color-syntax-project-type-names:#3e8087;--color-syntax-strings:#d12f1b;--color-syntax-type-declarations:#03638c;--color-syntax-urls:#1337ff;--color-tabnav-item-border-color:var(--color-fill-gray);--color-text:var(--color-figure-gray);--color-text-background:var(--color-fill);--color-tutorial-assessments-background:var(--color-fill-secondary);--color-tutorial-background:var(--color-fill);--color-tutorial-navbar-dropdown-background:var(--color-fill);--color-tutorial-navbar-dropdown-border:var(--color-fill-gray);--color-tutorial-quiz-border-active:var(--color-figure-blue);--color-tutorials-overview-background:#161616;--color-tutorials-overview-content:#fff;--color-tutorials-overview-content-alt:#fff;--color-tutorials-overview-eyebrow:#ccc;--color-tutorials-overview-icon:#b0b0b0;--color-tutorials-overview-link:#09f;--color-tutorials-overview-navigation-link:#ccc;--color-tutorials-overview-navigation-link-active:#fff;--color-tutorials-overview-navigation-link-hover:#fff;--color-tutorial-hero-text:#fff;--color-tutorial-hero-background:#000;--color-navigator-item-hover:rgba(0,0,255,0.05)}@media screen{body[data-color-scheme=dark]{--color-fill:#000;--color-fill-secondary:#161616;--color-fill-tertiary:#2a2a2a;--color-fill-blue:#06f;--color-fill-light-blue-secondary:#004ec4;--color-fill-gray:#575757;--color-fill-gray-secondary:#222;--color-fill-gray-tertiary:#424242;--color-fill-gray-quaternary:#424242;--color-fill-green-secondary:#030;--color-fill-orange-secondary:#472400;--color-fill-red-secondary:#300;--color-figure-blue:#09f;--color-figure-gray:#fff;--color-figure-gray-secondary:#ccc;--color-figure-gray-secondary-alt:#b0b0b0;--color-figure-gray-tertiary:#b0b0b0;--color-figure-green:#090;--color-figure-light-gray:#b0b0b0;--color-figure-orange:#f60;--color-figure-red:#f33;--color-tutorials-teal:#fff;--color-article-body-background:#111;--color-badge-default:var(--color-badge-dark-default);--color-button-background-active:#06f;--color-code-line-highlight:rgba(0,153,255,0.08);--color-dropdown-background:var(--color-dropdown-dark-background);--color-dropdown-border:var(--color-dropdown-dark-border);--color-dropdown-option-text:var(--color-dropdown-dark-option-text);--color-dropdown-text:var(--color-dropdown-dark-text);--color-nav-color:var(--color-nav-dark-color);--color-nav-current-link:var(--color-nav-dark-current-link);--color-nav-expanded:var(--color-nav-dark-expanded);--color-nav-hierarchy-collapse-background:var(--color-nav-dark-hierarchy-collapse-background);--color-nav-hierarchy-collapse-borders:var(--color-nav-dark-hierarchy-collapse-borders);--color-nav-hierarchy-item-borders:var(--color-nav-dark-hierarchy-item-borders);--color-nav-keyline:var(--color-nav-dark-keyline);--color-nav-link-color:var(--color-nav-dark-link-color);--color-nav-link-color-hover:var(--color-nav-dark-link-color-hover);--color-nav-outlines:var(--color-nav-dark-outlines);--color-nav-rule:var(--color-nav-dark-rule);--color-nav-solid-background:var(--color-nav-dark-solid-background);--color-nav-sticking-expanded-keyline:var(--color-nav-dark-sticking-expanded-keyline);--color-nav-stuck:var(--color-nav-dark-stuck);--color-nav-uiblur-expanded:var(--color-nav-dark-uiblur-expanded);--color-nav-uiblur-stuck:var(--color-nav-dark-uiblur-stuck);--color-runtime-preview-disabled-text:hsla(0,0%,80%,0.6);--color-syntax-attributes:#cc9768;--color-syntax-characters:#d9c97c;--color-syntax-comments:#7f8c98;--color-syntax-documentation-markup:#7f8c98;--color-syntax-documentation-markup-keywords:#a3b1bf;--color-syntax-keywords:#ff7ab2;--color-syntax-marks:#fff;--color-syntax-numbers:#d9c97c;--color-syntax-other-class-names:#dabaff;--color-syntax-other-constants:#a7ebdd;--color-syntax-other-declarations:#4eb0cc;--color-syntax-other-function-and-method-names:#b281eb;--color-syntax-other-instance-variables-and-globals:#b281eb;--color-syntax-other-preprocessor-macros:#ffa14f;--color-syntax-other-type-names:#dabaff;--color-syntax-param-internal-name:#bfbfbf;--color-syntax-plain-text:#fff;--color-syntax-preprocessor-statements:#ffa14f;--color-syntax-project-class-names:#acf2e4;--color-syntax-project-constants:#78c2b3;--color-syntax-project-function-and-method-names:#78c2b3;--color-syntax-project-instance-variables-and-globals:#78c2b3;--color-syntax-project-preprocessor-macros:#ffa14f;--color-syntax-project-type-names:#acf2e4;--color-syntax-strings:#ff8170;--color-syntax-type-declarations:#6bdfff;--color-syntax-urls:#69f;--color-tutorial-background:var(--color-fill-tertiary);--color-navigator-item-hover:rgba(0,102,255,0.5)}}@media screen and (prefers-color-scheme:dark){body[data-color-scheme=auto]{--color-fill:#000;--color-fill-secondary:#161616;--color-fill-tertiary:#2a2a2a;--color-fill-blue:#06f;--color-fill-light-blue-secondary:#004ec4;--color-fill-gray:#575757;--color-fill-gray-secondary:#222;--color-fill-gray-tertiary:#424242;--color-fill-gray-quaternary:#424242;--color-fill-green-secondary:#030;--color-fill-orange-secondary:#472400;--color-fill-red-secondary:#300;--color-figure-blue:#09f;--color-figure-gray:#fff;--color-figure-gray-secondary:#ccc;--color-figure-gray-secondary-alt:#b0b0b0;--color-figure-gray-tertiary:#b0b0b0;--color-figure-green:#090;--color-figure-light-gray:#b0b0b0;--color-figure-orange:#f60;--color-figure-red:#f33;--color-tutorials-teal:#fff;--color-article-body-background:#111;--color-badge-default:var(--color-badge-dark-default);--color-button-background-active:#06f;--color-code-line-highlight:rgba(0,153,255,0.08);--color-dropdown-background:var(--color-dropdown-dark-background);--color-dropdown-border:var(--color-dropdown-dark-border);--color-dropdown-option-text:var(--color-dropdown-dark-option-text);--color-dropdown-text:var(--color-dropdown-dark-text);--color-nav-color:var(--color-nav-dark-color);--color-nav-current-link:var(--color-nav-dark-current-link);--color-nav-expanded:var(--color-nav-dark-expanded);--color-nav-hierarchy-collapse-background:var(--color-nav-dark-hierarchy-collapse-background);--color-nav-hierarchy-collapse-borders:var(--color-nav-dark-hierarchy-collapse-borders);--color-nav-hierarchy-item-borders:var(--color-nav-dark-hierarchy-item-borders);--color-nav-keyline:var(--color-nav-dark-keyline);--color-nav-link-color:var(--color-nav-dark-link-color);--color-nav-link-color-hover:var(--color-nav-dark-link-color-hover);--color-nav-outlines:var(--color-nav-dark-outlines);--color-nav-rule:var(--color-nav-dark-rule);--color-nav-solid-background:var(--color-nav-dark-solid-background);--color-nav-sticking-expanded-keyline:var(--color-nav-dark-sticking-expanded-keyline);--color-nav-stuck:var(--color-nav-dark-stuck);--color-nav-uiblur-expanded:var(--color-nav-dark-uiblur-expanded);--color-nav-uiblur-stuck:var(--color-nav-dark-uiblur-stuck);--color-runtime-preview-disabled-text:hsla(0,0%,80%,0.6);--color-syntax-attributes:#cc9768;--color-syntax-characters:#d9c97c;--color-syntax-comments:#7f8c98;--color-syntax-documentation-markup:#7f8c98;--color-syntax-documentation-markup-keywords:#a3b1bf;--color-syntax-keywords:#ff7ab2;--color-syntax-marks:#fff;--color-syntax-numbers:#d9c97c;--color-syntax-other-class-names:#dabaff;--color-syntax-other-constants:#a7ebdd;--color-syntax-other-declarations:#4eb0cc;--color-syntax-other-function-and-method-names:#b281eb;--color-syntax-other-instance-variables-and-globals:#b281eb;--color-syntax-other-preprocessor-macros:#ffa14f;--color-syntax-other-type-names:#dabaff;--color-syntax-param-internal-name:#bfbfbf;--color-syntax-plain-text:#fff;--color-syntax-preprocessor-statements:#ffa14f;--color-syntax-project-class-names:#acf2e4;--color-syntax-project-constants:#78c2b3;--color-syntax-project-function-and-method-names:#78c2b3;--color-syntax-project-instance-variables-and-globals:#78c2b3;--color-syntax-project-preprocessor-macros:#ffa14f;--color-syntax-project-type-names:#acf2e4;--color-syntax-strings:#ff8170;--color-syntax-type-declarations:#6bdfff;--color-syntax-urls:#69f;--color-tutorial-background:var(--color-fill-tertiary);--color-navigator-item-hover:rgba(0,102,255,0.5)}}#main{outline-style:none}:root{--app-height:100vh}[data-v-6f639c59] :focus:not(input):not(textarea):not(select){outline:none}.fromkeyboard[data-v-6f639c59] :focus:not(input):not(textarea):not(select){outline:4px solid var(--color-focus-color);outline-offset:1px}#app[data-v-6f639c59]{display:grid;grid-template-rows:auto 1fr auto;min-height:100%}#app[data-v-6f639c59]>*{min-width:0}#app.hascustomheader[data-v-6f639c59]{grid-template-rows:auto auto 1fr auto}.container[data-v-790053de]{margin-left:auto;margin-right:auto;width:980px;outline-style:none;margin-top:92px;margin-bottom:140px}@media only screen and (max-width:1250px){.container[data-v-790053de]{width:692px}}@media only screen and (max-width:735px){.container[data-v-790053de]{width:87.5%}}.error-content[data-v-790053de]{box-sizing:border-box;width:502px;margin-left:auto;margin-right:auto;margin-bottom:54px}@media only screen and (max-width:1250px){.error-content[data-v-790053de]{width:420px;margin-bottom:45px}}@media only screen and (max-width:735px){.error-content[data-v-790053de]{max-width:330px;width:auto;margin-bottom:35px}}.title[data-v-790053de]{text-align:center;font-size:2.82353rem;line-height:1.08333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:1250px){.title[data-v-790053de]{font-size:2.35294rem;line-height:1.1;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){.title[data-v-790053de]{font-size:1.88235rem;line-height:1.125;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/css/topic.ee15af52.css b/docs/docc/Reducer.doccarchive/css/topic.ee15af52.css
deleted file mode 100644
index 82d8849..0000000
--- a/docs/docc/Reducer.doccarchive/css/topic.ee15af52.css
+++ /dev/null
@@ -1,9 +0,0 @@
-/*!
- * This source file is part of the Swift.org open source project
- *
- * Copyright (c) 2021 Apple Inc. and the Swift project authors
- * Licensed under Apache License v2.0 with Runtime Library Exception
- *
- * See https://swift.org/LICENSE.txt for license information
- * See https://swift.org/CONTRIBUTORS.txt for Swift project authors
- */.nav-title-content[data-v-60ea3af8]{max-width:100%}.title[data-v-60ea3af8]{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;display:inline-block;vertical-align:top;max-width:296px}@media only screen and (max-width:1023px){.title[data-v-60ea3af8]{max-width:205px}}@media only screen and (max-width:767px){.title[data-v-60ea3af8]{flex-basis:fill;display:initial;vertical-align:initial;max-width:none}}.subhead[data-v-60ea3af8]{color:var(--color-nav-root-subhead)}.theme-dark .subhead[data-v-60ea3af8]{color:var(--color-nav-dark-root-subhead)}.mobile-dropdown[data-v-154acfbd]{box-sizing:border-box}.nav--in-breakpoint-range .mobile-dropdown[data-v-154acfbd]{padding-left:.23529rem;padding-right:.23529rem}.mobile-dropdown ul[data-v-154acfbd]{list-style:none}.mobile-dropdown .option[data-v-154acfbd]{cursor:pointer;font-size:.70588rem;padding:.5rem 0;display:block;text-decoration:none;color:inherit}.mobile-dropdown .option[data-v-154acfbd]:focus{outline-offset:0}.mobile-dropdown .option.depth1[data-v-154acfbd]{padding-left:.47059rem}.active[data-v-154acfbd],.tutorial.router-link-active[data-v-154acfbd]{font-weight:600}.active[data-v-154acfbd]:focus,.tutorial.router-link-active[data-v-154acfbd]:focus{outline:none}.chapter-list[data-v-154acfbd]:not(:first-child){margin-top:1rem}.chapter-name[data-v-154acfbd],.tutorial[data-v-154acfbd]{padding:.5rem 0;font-size:1rem;line-height:1.47059;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.section-list[data-v-154acfbd],.tutorial-list[data-v-154acfbd]{padding:0 .58824rem}.chapter-list:last-child .tutorial-list[data-v-154acfbd]:last-child{padding-bottom:10em}.chapter-list[data-v-154acfbd]{display:inline-block}.form-element[data-v-998803d8]{position:relative}.form-dropdown[data-v-998803d8]{font-size:1rem;line-height:1.23529;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;display:block;box-sizing:border-box;width:100%;height:3.3em;color:var(--color-dropdown-text);padding:1.11765rem 2.35294rem 0 .94118rem;text-align:left;border:1px solid var(--color-dropdown-border);border-radius:4px;background-clip:padding-box;margin-bottom:.82353rem;-webkit-appearance:none;-moz-appearance:none;appearance:none;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;min-height:32px}.form-dropdown[data-v-998803d8]:focus{box-shadow:0 0 0 4px var(--color-focus-color);outline:none;border-color:var(--color-focus-border-color)}.form-dropdown.no-eyebrow[data-v-998803d8]{padding-top:0}.form-dropdown[data-v-998803d8]:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--color-dropdown-text)}.form-dropdown[data-v-998803d8]::-ms-expand{opacity:0}.form-dropdown~.form-icon[data-v-998803d8]{position:absolute;display:block;pointer-events:none;fill:var(--color-figure-gray-tertiary);right:14px;width:13px;height:auto;top:50%;transform:translateY(-50%)}.is-open .form-dropdown~.form-icon[data-v-998803d8]{transform:translateY(-50%) scale(-1)}@media only screen and (max-width:735px){.form-dropdown~.form-icon[data-v-998803d8]{right:14px}}.form-dropdown~.form-label[data-v-998803d8]{font-size:.70588rem;line-height:1.75;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;position:absolute;top:.47059rem;left:17px;color:var(--color-figure-gray-secondary);pointer-events:none;padding:0;z-index:1}.form-dropdown[data-v-998803d8] option{color:var(--color-dropdown-text)}.form-dropdown-selectnone[data-v-998803d8]{color:transparent}.form-dropdown-selectnone~.form-label[data-v-998803d8]{font-size:1rem;line-height:1.23529;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;top:19px;left:17px;color:var(--color-figure-gray-tertiary)}.form-dropdown-selectnone[data-v-998803d8]:-moz-focusring{text-shadow:none}.form-dropdown-selectnone[data-v-998803d8]::-ms-value{display:none}.theme-dark .form-dropdown[data-v-998803d8]{color:var(--color-dropdown-dark-text);background-color:var(--color-dropdown-dark-background);border-color:var(--color-dropdown-dark-border)}.theme-dark .form-dropdown~.form-label[data-v-998803d8]{color:#ccc}.theme-dark .form-dropdown[data-v-998803d8]:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--color-dropdown-dark-text)}.theme-dark .form-dropdown.form-dropdown-selectnone[data-v-998803d8]{color:transparent}.theme-dark .form-dropdown.form-dropdown-selectnone[data-v-998803d8]:-moz-focusring{text-shadow:none}.theme-dark .form-dropdown-selectnone~.form-label[data-v-998803d8]{color:#b0b0b0}.dropdown-small[data-v-12dd746a]{height:30px;display:flex;align-items:center;position:relative;background:var(--color-fill)}.dropdown-small .form-dropdown-toggle[data-v-12dd746a]{line-height:1.5;font-size:12px;padding-top:0;padding-bottom:0;padding-left:20px;min-height:unset;height:30px;display:flex;align-items:center}.dropdown-small .form-dropdown-toggle[data-v-12dd746a]:focus{box-shadow:none;border-color:var(--color-dropdown-border)}.fromkeyboard .dropdown-small .form-dropdown-toggle[data-v-12dd746a]:focus{box-shadow:0 0 0 2px var(--color-focus-color);outline:none;border-color:var(--color-focus-border-color)}.form-dropdown-toggle[data-v-12dd746a]{margin:0}.is-open .form-dropdown-toggle[data-v-12dd746a]{border-radius:4px 4px 0 0;border-bottom:none;padding-bottom:1px}.fromkeyboard .is-open .form-dropdown-toggle[data-v-12dd746a]{box-shadow:1px -1px 0 1px var(--color-focus-color),-1px -1px 0 1px var(--color-focus-color);border-color:var(--color-focus-border-color)}.form-dropdown-title[data-v-12dd746a]{margin:0;padding:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.dropdown-custom[data-v-12dd746a]{border-radius:4px}.dropdown-custom.is-open[data-v-12dd746a]{border-radius:4px 4px 0 0}.dropdown-custom[data-v-12dd746a] .form-dropdown-content{background:var(--color-fill);position:absolute;right:0;left:0;top:100%;border-bottom-left-radius:4px;border-bottom-right-radius:4px;border:1px solid var(--color-dropdown-border);border-top:none;display:none;overflow-y:auto}.dropdown-custom[data-v-12dd746a] .form-dropdown-content.is-open{display:block}.fromkeyboard .dropdown-custom[data-v-12dd746a] .form-dropdown-content.is-open{box-shadow:1px 1px 0 1px var(--color-focus-color),-1px 1px 0 1px var(--color-focus-color);border-color:var(--color-focus-border-color);border-top-color:transparent}.nav .dropdown-custom[data-v-12dd746a] .form-dropdown-content{max-height:calc(100vh - 116px - 3.05882rem)}.nav--is-sticking.nav .dropdown-custom[data-v-12dd746a] .form-dropdown-content{max-height:calc(100vh - 3.05882rem - 72px)}.dropdown-custom[data-v-12dd746a] .options{list-style:none;margin:0;padding:0 0 20px}.dropdown-custom[data-v-12dd746a] .option{cursor:pointer;padding:5px 20px;font-size:12px;line-height:20px;outline:none}.dropdown-custom[data-v-12dd746a] .option:hover{background-color:var(--color-fill-tertiary)}.dropdown-custom[data-v-12dd746a] .option.option-active{font-weight:600}.fromkeyboard .dropdown-custom[data-v-12dd746a] .option:hover{background-color:transparent}.fromkeyboard .dropdown-custom[data-v-12dd746a] .option:focus{background-color:var(--color-fill-tertiary);outline:none}.tutorial-dropdown[data-v-4a151342]{grid-column:3}.section-tracker[data-v-4a151342]{font-size:.70588rem;line-height:1.33333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--color-figure-gray-secondary);margin-left:15px}.tutorial-dropdown[data-v-78dc103f]{grid-column:1/2}.tutorial-dropdown .options[data-v-78dc103f]{padding-top:1rem;padding-bottom:0}.tutorial-dropdown .option[data-v-78dc103f]{padding:5px 20px 5px 30px}.chapter-list[data-v-78dc103f]{padding-bottom:20px}.chapter-name[data-v-78dc103f]{margin:0 20px 5px 20px;line-height:normal;color:var(--color-figure-gray-secondary)}.chevron-icon[data-v-26e19f17]{padding:0;color:var(--color-nav-outlines);grid-column:2;height:20px;width:20px;margin:0 4px}@media only screen and (min-width:768px){.nav[data-v-26e19f17] .nav-content{display:grid;grid-template-columns:auto auto 3fr;align-items:center}.nav[data-v-26e19f17] .nav-menu{padding:0;grid-column:3/5}.nav[data-v-26e19f17] .nav-menu-item{margin:0}}.dropdown-container[data-v-26e19f17]{height:3.05882rem;display:grid;grid-template-columns:minmax(230px,285px) auto minmax(230px,1fr);align-items:center}@media only screen and (max-width:1023px){.dropdown-container[data-v-26e19f17]{grid-template-columns:minmax(173px,216px) auto minmax(173px,1fr)}}.separator[data-v-26e19f17]{height:20px;border-right:1px solid;border-color:var(--color-nav-outlines);margin:0 20px;grid-column:2}.mobile-dropdown-container[data-v-26e19f17],.nav--in-breakpoint-range.nav .dropdown-container[data-v-26e19f17],.nav--in-breakpoint-range.nav .separator[data-v-26e19f17]{display:none}.nav--in-breakpoint-range.nav .mobile-dropdown-container[data-v-26e19f17]{display:block}.nav--in-breakpoint-range.nav[data-v-26e19f17] .nav-title{grid-area:title}.nav--in-breakpoint-range.nav[data-v-26e19f17] .pre-title{display:none}.nav[data-v-26e19f17] .nav-title{grid-column:1;width:90%;padding-top:0}.primary-dropdown[data-v-26e19f17],.secondary-dropdown[data-v-26e19f17]{background:var(--color-tutorial-navbar-dropdown-background);border-color:var(--color-tutorial-navbar-dropdown-border)}.primary-dropdown[data-v-26e19f17] .form-dropdown,.primary-dropdown[data-v-26e19f17] .form-dropdown:focus,.secondary-dropdown[data-v-26e19f17] .form-dropdown,.secondary-dropdown[data-v-26e19f17] .form-dropdown:focus{border-color:var(--color-tutorial-navbar-dropdown-border)}.primary-dropdown[data-v-26e19f17] .options,.secondary-dropdown[data-v-26e19f17] .options{background:var(--color-tutorial-navbar-dropdown-background);border-color:var(--color-tutorial-navbar-dropdown-border)}.replay-button[data-v-59608016]{display:flex;align-items:center;justify-content:center;cursor:pointer;visibility:hidden;margin-top:.5rem;-webkit-tap-highlight-color:transparent}.replay-button.visible[data-v-59608016]{visibility:visible}.replay-button svg.replay-icon[data-v-59608016]{height:12px;width:12px;margin-left:.3em}[data-v-1b5cc854] img,[data-v-1b5cc854] video{display:block;margin-left:auto;margin-right:auto;-o-object-fit:contain;object-fit:contain;max-width:100%}[data-v-3cfe1c35] .code-listing+*,[data-v-3cfe1c35] aside+*,[data-v-3cfe1c35] h2+*,[data-v-3cfe1c35] h3+*,[data-v-3cfe1c35] ol+*,[data-v-3cfe1c35] p+*,[data-v-3cfe1c35] ul+*{margin-top:20px}[data-v-3cfe1c35] ol ol,[data-v-3cfe1c35] ol ul,[data-v-3cfe1c35] ul ol,[data-v-3cfe1c35] ul ul{margin-top:0}[data-v-3cfe1c35] h2{font-size:1.88235rem;line-height:1.25;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:1250px){[data-v-3cfe1c35] h2{font-size:1.64706rem;line-height:1.28571;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){[data-v-3cfe1c35] h2{font-size:1.41176rem;line-height:1.33333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}[data-v-3cfe1c35] h3{font-size:1.41176rem;line-height:1.16667;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:1250px){[data-v-3cfe1c35] h3{font-size:1.23529rem;line-height:1.19048;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}[data-v-3cfe1c35] .code-listing{background:var(--color-code-background);border-color:var(--colors-grid,var(--color-grid));border-style:solid;border-width:1px}[data-v-3cfe1c35] .code-listing pre{font-size:.70588rem;line-height:1.83333;font-weight:400;font-family:Menlo,monospace;padding:20px 0}.columns[data-v-30edf911]{display:grid;grid-template-rows:repeat(2,auto)}.columns.cols-2[data-v-30edf911]{gap:20px 8.33333%;grid-template-columns:repeat(2,1fr)}.columns.cols-3[data-v-30edf911]{gap:20px 4.16667%;grid-template-columns:repeat(3,1fr)}.asset[data-v-30edf911]{align-self:end;grid-row:1}.content[data-v-30edf911]{grid-row:2}@media only screen and (max-width:735px){.columns.cols-2[data-v-30edf911],.columns.cols-3[data-v-30edf911]{grid-template-columns:unset}.asset[data-v-30edf911],.content[data-v-30edf911]{grid-row:auto}}.content-and-media[data-v-3fa44f9e]{display:flex}.content-and-media.media-leading[data-v-3fa44f9e]{flex-direction:row-reverse}.content-and-media.media-trailing[data-v-3fa44f9e]{flex-direction:row}@media only screen and (min-width:736px){.content-and-media[data-v-3fa44f9e]{align-items:center;justify-content:center}}.content[data-v-3fa44f9e]{width:62.5%}.asset[data-v-3fa44f9e]{width:29.16667%}.media-leading .asset[data-v-3fa44f9e]{margin-right:8.33333%}.media-trailing .asset[data-v-3fa44f9e]{margin-left:8.33333%}@media only screen and (max-width:735px){.content-and-media.media-leading[data-v-3fa44f9e],.content-and-media.media-trailing[data-v-3fa44f9e]{flex-direction:column}.asset[data-v-3fa44f9e],.content[data-v-3fa44f9e]{width:100%}.media-leading .asset[data-v-3fa44f9e],.media-trailing .asset[data-v-3fa44f9e]{margin:20px 0 0 0}}.group[id][data-v-1f2be54b]{margin-top:20px;padding-top:20px}[data-v-1f2be54b] img,[data-v-1f2be54b] video{display:block;margin:0 auto;max-width:100%}.layout+[data-v-4d5a806e]{margin-top:40px}@media only screen and (max-width:735px){.layout[data-v-4d5a806e]:first-child>:not(.group[id]){margin-top:40px}}.body[data-v-6499e2f2]{background:var(--colors-text-background,var(--color-article-body-background));margin-left:auto;margin-right:auto;width:980px;border-radius:10px;transform:translateY(-120px)}@media only screen and (max-width:1250px){.body[data-v-6499e2f2]{width:692px}}@media only screen and (max-width:735px){.body[data-v-6499e2f2]{width:87.5%;border-radius:0;transform:none}}.body[data-v-6499e2f2]~*{margin-top:-40px}.body-content[data-v-6499e2f2]{padding:40px 8.33333% 80px 8.33333%}@media only screen and (max-width:735px){.body-content[data-v-6499e2f2]{padding:0 0 40px 0}}.call-to-action[data-v-2016b288]{padding:65px 0;background:var(--color-call-to-action-background)}.theme-dark .call-to-action[data-v-2016b288]{--color-call-to-action-background:#424242}.row[data-v-2016b288]{margin-left:auto;margin-right:auto;width:980px;display:flex;align-items:center}@media only screen and (max-width:1250px){.row[data-v-2016b288]{width:692px}}@media only screen and (max-width:735px){.row[data-v-2016b288]{width:87.5%}}[data-v-2016b288] img,[data-v-2016b288] video{max-height:560px}h2[data-v-2016b288]{font-size:1.88235rem;line-height:1.25;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:1250px){h2[data-v-2016b288]{font-size:1.64706rem;line-height:1.28571;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){h2[data-v-2016b288]{font-size:1.41176rem;line-height:1.33333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.label[data-v-2016b288]{display:block;font-size:1.23529rem;line-height:1.19048;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;margin-bottom:.4em;color:var(--color-eyebrow)}@media only screen and (max-width:735px){.label[data-v-2016b288]{font-size:1.11765rem;line-height:1.21053;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.content[data-v-2016b288]{margin-bottom:1.5rem}.right-column[data-v-2016b288]{margin-left:auto}@media only screen and (max-width:735px){.row[data-v-2016b288]{display:block}.col+.col[data-v-2016b288]{margin-top:40px}}@media only screen and (max-width:735px){.call-to-action[data-v-426a965c]{margin-top:0}}.headline[data-v-1898f592]{margin-bottom:.8em}.heading[data-v-1898f592]{font-size:2.82353rem;line-height:1.08333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--color-header-text)}@media only screen and (max-width:1250px){.heading[data-v-1898f592]{font-size:2.35294rem;line-height:1.1;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){.heading[data-v-1898f592]{font-size:1.88235rem;line-height:1.125;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.dark .heading[data-v-1898f592]{color:#fff}.eyebrow[data-v-1898f592]{font-size:1.41176rem;line-height:1.16667;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;display:block;margin-bottom:.4em;color:var(--color-eyebrow)}@media only screen and (max-width:1250px){.eyebrow[data-v-1898f592]{font-size:1.23529rem;line-height:1.19048;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.generic-modal[data-v-ea628b36]{position:fixed;top:0;left:0;right:0;bottom:0;margin:0;z-index:11000;display:flex;align-items:center;justify-content:center;flex-wrap:wrap;background:none;overflow:auto}.modal-fullscreen[data-v-ea628b36]{align-items:stretch}.modal-fullscreen .container[data-v-ea628b36]{margin:0;flex:1;width:100%;height:100%;padding-top:env(safe-area-inset-top);padding-right:env(safe-area-inset-right);padding-bottom:env(safe-area-inset-bottom);padding-left:env(safe-area-inset-left)}.modal-standard[data-v-ea628b36]{padding:20px}.modal-standard .container[data-v-ea628b36]{padding:60px;border-radius:4px}@media screen{[data-color-scheme=dark] .modal-standard .container[data-v-ea628b36]{background:#1d1d1f}}@media screen and (prefers-color-scheme:dark){[data-color-scheme=auto] .modal-standard .container[data-v-ea628b36]{background:#1d1d1f}}@media only screen and (max-width:735px){.modal-standard[data-v-ea628b36]{padding:0;align-items:stretch}.modal-standard .container[data-v-ea628b36]{margin:20px 0 0;padding:50px 30px;flex:1;width:100%;border-bottom-left-radius:0;border-bottom-right-radius:0}}.backdrop[data-v-ea628b36]{overflow:auto;background:rgba(0,0,0,.4);-webkit-overflow-scrolling:touch;width:100%;height:100%;position:fixed}.container[data-v-ea628b36]{margin-left:auto;margin-right:auto;width:980px;background:var(--colors-generic-modal-background,var(--color-generic-modal-background));z-index:1;position:relative;overflow:auto;max-width:100%}@media only screen and (max-width:1250px){.container[data-v-ea628b36]{width:692px}}@media only screen and (max-width:735px){.container[data-v-ea628b36]{width:87.5%}}.close[data-v-ea628b36]{position:absolute;z-index:9999;top:22px;left:22px;width:30px;height:30px;color:#666;cursor:pointer;background:none;border:0;display:flex;align-items:center}.close .close-icon[data-v-ea628b36]{fill:currentColor;width:100%;height:100%}.theme-dark .container[data-v-ea628b36]{background:#000}.theme-dark .container .close[data-v-ea628b36]{color:#b0b0b0}.theme-code .container[data-v-ea628b36]{background-color:var(--background,var(--color-code-background))}.metadata[data-v-2fa6f125]{display:flex}.item[data-v-2fa6f125]{font-size:.70588rem;line-height:1.33333;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;border-right:1px solid #fff;padding:0 27.5px}@media only screen and (max-width:735px){.item[data-v-2fa6f125]{font-size:.64706rem;line-height:1.63636;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;padding:0 8px}}.item[data-v-2fa6f125]:first-of-type{padding-left:0}.item[data-v-2fa6f125]:last-of-type{border:none}@media only screen and (max-width:735px){.item[data-v-2fa6f125]:last-of-type{padding-right:0}}.content[data-v-2fa6f125]{color:#fff}.icon[data-v-2fa6f125]{font-size:2.82353rem;line-height:1.08333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:1250px){.icon[data-v-2fa6f125]{font-size:2.35294rem;line-height:1.1;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){.icon[data-v-2fa6f125]{font-size:1.88235rem;line-height:1.125;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.small-icon[data-v-2fa6f125]{width:1em;height:1em;margin-left:.2rem}.small-icon.xcode-icon[data-v-2fa6f125]{width:.8em;height:.8em}.content-link[data-v-2fa6f125]{display:flex;align-items:center}a[data-v-2fa6f125]{color:var(--colors-link,var(--color-tutorials-overview-link))}.duration[data-v-2fa6f125]{display:flex;align-items:baseline;font-size:2.35294rem;line-height:1;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:1.8rem}@media only screen and (max-width:735px){.duration[data-v-2fa6f125]{font-size:1.64706rem;line-height:1;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:1.3rem}}.minutes[data-v-2fa6f125]{display:inline-block;font-size:1.64706rem;line-height:1;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:1.3rem}@media only screen and (max-width:735px){.minutes[data-v-2fa6f125]{font-size:1rem;line-height:1.23529;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:.8rem}}.item-large-icon[data-v-2fa6f125]{height:2.3rem;max-width:100%}@media only screen and (max-width:735px){.item-large-icon[data-v-2fa6f125]{height:1.5rem;max-width:100%}}.bottom[data-v-2fa6f125]{margin-top:13px}@media only screen and (max-width:735px){.bottom[data-v-2fa6f125]{margin-top:8px}}.hero[data-v-cb87b2d0]{color:var(--color-tutorial-hero-text);position:relative}.bg[data-v-cb87b2d0],.hero[data-v-cb87b2d0]{background-color:var(--color-tutorial-hero-background)}.bg[data-v-cb87b2d0]{background-position:top;background-repeat:no-repeat;background-size:cover;content:"";height:100%;left:0;opacity:.3;position:absolute;top:0;width:100%}.row[data-v-cb87b2d0]{margin-left:auto;margin-right:auto;width:980px;padding:80px 0}@media only screen and (max-width:1250px){.row[data-v-cb87b2d0]{width:692px}}@media only screen and (max-width:735px){.row[data-v-cb87b2d0]{width:87.5%}}.col[data-v-cb87b2d0]{z-index:1}[data-v-cb87b2d0] .eyebrow{font-size:1.41176rem;line-height:1.16667;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--color-hero-eyebrow)}@media only screen and (max-width:1250px){[data-v-cb87b2d0] .eyebrow{font-size:1.23529rem;line-height:1.19048;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.headline[data-v-cb87b2d0]{font-size:2.82353rem;line-height:1.08333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;margin-bottom:2rem}@media only screen and (max-width:1250px){.headline[data-v-cb87b2d0]{font-size:2.35294rem;line-height:1.1;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){.headline[data-v-cb87b2d0]{font-size:1.88235rem;line-height:1.125;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.intro[data-v-cb87b2d0]{font-size:1.23529rem;line-height:1.38095;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:735px){.intro[data-v-cb87b2d0]{font-size:1.11765rem;line-height:1.42105;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.content+p[data-v-cb87b2d0]{margin-top:.8em}@media only screen and (max-width:735px){.content+p[data-v-cb87b2d0]{margin-top:8px}}.call-to-action[data-v-cb87b2d0]{display:flex;align-items:center}.call-to-action .cta-icon[data-v-cb87b2d0]{margin-left:.4rem;width:1em;height:1em}.metadata[data-v-cb87b2d0]{margin-top:2rem}.video-asset[data-v-cb87b2d0]{display:grid;height:100vh;margin:0;place-items:center center}.video-asset[data-v-cb87b2d0] video{max-width:1280px;min-width:320px;width:100%}@media only screen and (max-width:735px){.headline[data-v-cb87b2d0]{margin-bottom:19px}}.tutorial-hero[data-v-35a9482f]{margin-bottom:80px}@media only screen and (max-width:735px){.tutorial-hero[data-v-35a9482f]{margin-bottom:0}}.title[data-v-8ec95972]{font-size:.70588rem;line-height:1.33333;color:var(--colors-secondary-label,var(--color-secondary-label))}.title[data-v-8ec95972],.title[data-v-455ff2a6]{font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.title[data-v-455ff2a6]{font-size:1.11765rem;line-height:1.21053;color:var(--colors-header-text,var(--color-header-text));margin:25px 0}.question-content[data-v-455ff2a6] code{font-size:.76471rem;line-height:1.84615;font-weight:400;font-family:Menlo,monospace}.choices[data-v-455ff2a6]{display:flex;flex-direction:column;padding:0;list-style:none;margin:25px 0}.choice[data-v-455ff2a6]{font-size:.82353rem;line-height:1.42857;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;flex:1;border-radius:4px;margin:8px 0;padding:1.5rem 40px;cursor:pointer;background:var(--colors-text-background,var(--color-text-background));display:flex;flex-direction:column;justify-content:center;border-width:1px;border-style:solid;border-color:var(--colors-grid,var(--color-grid));position:relative}.choice[data-v-455ff2a6] img{max-height:23.52941rem}.choice[data-v-455ff2a6]:first-of-type{margin-top:0}.choice[data-v-455ff2a6] code{font-size:.76471rem;line-height:1.84615;font-weight:400;font-family:Menlo,monospace}.controls[data-v-455ff2a6]{text-align:center;margin-bottom:40px}.controls .button-cta[data-v-455ff2a6]{margin:.5rem;margin-top:0;padding:.3rem 3rem;min-width:8rem}input[type=radio][data-v-455ff2a6]{position:absolute;width:100%;left:0;height:100%;opacity:0;z-index:-1}.active[data-v-455ff2a6]{border-color:var(--color-tutorial-quiz-border-active);box-shadow:0 0 0 4px var(--color-focus-color);outline:none}.active [data-v-455ff2a6]{color:var(--colors-text,var(--color-text))}.correct[data-v-455ff2a6]{background:var(--color-form-valid-background);border-color:var(--color-form-valid)}.correct .choice-icon[data-v-455ff2a6]{fill:var(--color-form-valid)}.incorrect[data-v-455ff2a6]{background:var(--color-form-error-background);border-color:var(--color-form-error)}.incorrect .choice-icon[data-v-455ff2a6]{fill:var(--color-form-error)}.correct[data-v-455ff2a6],.incorrect[data-v-455ff2a6]{position:relative}.correct .choice-icon[data-v-455ff2a6],.incorrect .choice-icon[data-v-455ff2a6]{position:absolute;top:11px;left:10px;font-size:20px;width:1.05em}.disabled[data-v-455ff2a6]{pointer-events:none}.answer[data-v-455ff2a6]{margin:.5rem 1.5rem .5rem 0;font-size:.70588rem;line-height:1.33333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.answer[data-v-455ff2a6]:last-of-type{margin-bottom:0}[data-v-455ff2a6] .question>.code-listing{padding:unset;border-radius:0}[data-v-455ff2a6] pre{padding:0}[data-v-455ff2a6] img{display:block;margin-left:auto;margin-right:auto;max-width:100%}.title[data-v-c1de71de]{font-size:1.88235rem;line-height:1.25;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--colors-header-text,var(--color-header-text))}@media only screen and (max-width:1250px){.title[data-v-c1de71de]{font-size:1.64706rem;line-height:1.28571;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){.title[data-v-c1de71de]{font-size:1.41176rem;line-height:1.33333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.title p[data-v-c1de71de]{color:var(--colors-text,var(--color-text))}.assessments[data-v-c1de71de]{box-sizing:content-box;padding:0 1rem;background:var(--color-tutorial-assessments-background);margin-left:auto;margin-right:auto;width:980px;margin-bottom:80px}@media only screen and (max-width:1250px){.assessments[data-v-c1de71de]{width:692px}}@media only screen and (max-width:735px){.assessments[data-v-c1de71de]{width:87.5%}}.banner[data-v-c1de71de]{padding:40px 0;border-bottom:1px solid;margin-bottom:40px;border-color:var(--colors-grid,var(--color-grid));text-align:center}.success[data-v-c1de71de]{text-align:center;padding-bottom:40px;font-size:1.88235rem;line-height:1.25;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--colors-text,var(--color-text))}@media only screen and (max-width:1250px){.success[data-v-c1de71de]{font-size:1.64706rem;line-height:1.28571;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){.success[data-v-c1de71de]{font-size:1.41176rem;line-height:1.33333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.assessments-wrapper[data-v-c1de71de]{padding-top:80px}.assessments-wrapper[data-v-3c94366b]{padding-bottom:40px;padding-top:0}@media only screen and (max-width:735px){.assessments-wrapper[data-v-3c94366b]{padding-top:80px}}.article[data-v-d9f204d0]{background:var(--colors-article-background,var(--color-article-background))}@media only screen and (max-width:735px){.article[data-v-d9f204d0]{background:var(--colors-text-background,var(--color-article-body-background))}}.intro-container[data-v-54daa228]{margin-bottom:80px}.intro[data-v-54daa228]{display:flex;align-items:center}@media only screen and (max-width:735px){.intro[data-v-54daa228]{padding-bottom:0;flex-direction:column}}.intro.ide .media[data-v-54daa228] img{background-color:var(--colors-text-background,var(--color-text-background))}.col.left[data-v-54daa228]{padding-right:40px}@media only screen and (max-width:1250px){.col.left[data-v-54daa228]{padding-right:28px}}@media only screen and (max-width:735px){.col.left[data-v-54daa228]{margin-left:auto;margin-right:auto;width:980px;padding-right:0}}@media only screen and (max-width:735px) and (max-width:1250px){.col.left[data-v-54daa228]{width:692px}}@media only screen and (max-width:735px) and (max-width:735px){.col.left[data-v-54daa228]{width:87.5%}}.col.right[data-v-54daa228]{padding-left:40px}@media only screen and (max-width:1250px){.col.right[data-v-54daa228]{padding-left:28px}}@media only screen and (max-width:735px){.col.right[data-v-54daa228]{padding-left:0}}.content[data-v-54daa228]{font-size:1rem;line-height:1.47059;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.media[data-v-54daa228] img{width:auto;max-height:560px;min-height:18.82353rem;-o-object-fit:scale-down;object-fit:scale-down}@media only screen and (max-width:735px){.media[data-v-54daa228]{margin:0;margin-top:40px}.media[data-v-54daa228] img,.media[data-v-54daa228] video{max-height:80vh}}.media[data-v-54daa228] .asset{padding:0 20px}.headline[data-v-54daa228]{color:var(--colors-header-text,var(--color-header-text))}[data-v-54daa228] .eyebrow{font-size:1.23529rem;line-height:1.19048;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:735px){[data-v-54daa228] .eyebrow{font-size:1.11765rem;line-height:1.21053;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}[data-v-54daa228] .eyebrow a{color:inherit}[data-v-54daa228] .heading{font-size:1.88235rem;line-height:1.25;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:1250px){[data-v-54daa228] .heading{font-size:1.64706rem;line-height:1.28571;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){[data-v-54daa228] .heading{font-size:1.41176rem;line-height:1.33333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.expanded-intro[data-v-54daa228]{margin-left:auto;margin-right:auto;width:980px;margin-top:40px}@media only screen and (max-width:1250px){.expanded-intro[data-v-54daa228]{width:692px}}@media only screen and (max-width:735px){.expanded-intro[data-v-54daa228]{width:87.5%}}[data-v-54daa228] .cols-2{gap:20px 16.66667%}[data-v-54daa228] .cols-3 .column{gap:20px 12.5%}.code-preview[data-v-9acc0234]{position:sticky;overflow-y:auto;-webkit-overflow-scrolling:touch;background-color:var(--background,var(--color-step-background));height:calc(100vh - 3.05882rem)}.code-preview.ide[data-v-9acc0234]{height:100vh}.code-preview[data-v-9acc0234] .code-listing{color:var(--text,var(--color-code-plain))}.code-preview[data-v-9acc0234] pre{font-size:.70588rem;line-height:1.83333;font-weight:400;font-family:Menlo,monospace}.header[data-v-9acc0234]{font-size:.70588rem;line-height:1.33333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;position:relative;display:flex;justify-content:space-between;align-items:center;width:-webkit-fill-available;width:-moz-available;width:stretch;cursor:pointer;font-weight:600;padding:8px 12px;border-radius:4px 4px 0 0;z-index:1;background:var(--color-runtime-preview-background);color:var(--colors-runtime-preview-text,var(--color-runtime-preview-text))}.header[data-v-9acc0234]:focus{outline-style:none}#app.fromkeyboard .header[data-v-9acc0234]:focus{box-shadow:0 0 0 4px var(--color-focus-color);outline:none;border-color:var(--color-focus-border-color)}.runtime-preview[data-v-9acc0234]{--color-runtime-preview-shadow:rgba(0,0,0,0.4);position:absolute;top:0;right:0;background:var(--color-runtime-preview-background);border-radius:4px;margin:1rem;margin-left:0;transition:width .2s ease-in;box-shadow:0 0 3px 0 var(--color-runtime-preview-shadow)}@media screen{[data-color-scheme=dark] .runtime-preview[data-v-9acc0234]{--color-runtime-preview-shadow:hsla(0,0%,100%,0.4)}}@media screen and (prefers-color-scheme:dark){[data-color-scheme=auto] .runtime-preview[data-v-9acc0234]{--color-runtime-preview-shadow:hsla(0,0%,100%,0.4)}}@supports not ((width:-webkit-fill-available) or (width:-moz-available) or (width:stretch)){.runtime-preview[data-v-9acc0234]{display:flex;flex-direction:column}}.runtime-preview .runtimve-preview__container[data-v-9acc0234]{border-radius:4px;overflow:hidden}.runtime-preview-ide[data-v-9acc0234]{top:0}.runtime-preview-ide .runtime-preview-asset[data-v-9acc0234] img{background-color:var(--color-runtime-preview-background)}.runtime-preview.collapsed[data-v-9acc0234]{box-shadow:0 0 3px 0 var(--color-runtime-preview-shadow);width:102px}.runtime-preview.collapsed .header[data-v-9acc0234]{border-radius:4px}.runtime-preview.disabled[data-v-9acc0234]{box-shadow:0 0 3px 0 transparent}.runtime-preview.disabled .header[data-v-9acc0234]{color:var(--color-runtime-preview-disabled-text);cursor:auto}.runtime-preview-asset[data-v-9acc0234]{border-radius:0 0 4px 4px}.runtime-preview-asset[data-v-9acc0234] img{border-bottom-left-radius:4px;border-bottom-right-radius:4px}.preview-icon[data-v-9acc0234]{height:.8em;width:.8em;-webkit-user-select:none;-moz-user-select:none;user-select:none}.preview-show[data-v-9acc0234]{transform:scale(-1)}[data-v-5ad4e037] pre{padding:10px 0}.toggle-preview[data-v-d0709828]{color:var(--color-runtime-preview-disabled-text);display:flex;align-items:center}a[data-v-d0709828]{color:var(--url,var(--color-link))}.toggle-text[data-v-d0709828]{display:flex;align-items:center}svg.toggle-icon[data-v-d0709828]{width:1em;height:1em;margin-left:.5em}.mobile-code-preview[data-v-3bee1128]{background-color:var(--background,var(--color-step-background));padding:14px 0}@media only screen and (max-width:735px){.mobile-code-preview[data-v-3bee1128]{display:flex;flex-direction:column}}.runtime-preview-modal-content[data-v-3bee1128]{padding:45px 60px 0 60px;min-width:200px}.runtime-preview-modal-content[data-v-3bee1128] img:not(.file-icon){border-radius:4px;box-shadow:0 0 3px rgba(0,0,0,.4);max-height:80vh;width:auto;display:block;margin-bottom:1rem}.runtime-preview-modal-content .runtime-preview-label[data-v-3bee1128]{font-size:.70588rem;line-height:1.33333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--color-runtime-preview-text);display:block;text-align:center;padding:.5em}[data-v-3bee1128] .code-listing{color:var(--text,var(--color-code-plain))}[data-v-3bee1128] .full-code-listing{padding-top:60px;min-height:calc(100vh - 60px)}[data-v-3bee1128] pre{font-size:.70588rem;line-height:1.83333;font-weight:400;font-family:Menlo,monospace}.preview-toggle-container[data-v-3bee1128]{align-self:flex-end;margin-right:20px}.step-container[data-v-4abdd121]{margin:0}.step-container[data-v-4abdd121]:not(:last-child){margin-bottom:100px}@media only screen and (max-width:735px){.step-container[data-v-4abdd121]:not(:last-child){margin-bottom:80px}}.step[data-v-4abdd121]{position:relative;border-radius:4px;padding:1rem 2rem;background-color:var(--color-step-background);overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(#fff,#000)}.step[data-v-4abdd121]:before{content:"";position:absolute;top:0;left:0;border:1px solid var(--color-step-focused);background-color:var(--color-step-focused);height:calc(100% - 2px);width:4px;opacity:0;transition:opacity .15s ease-in}.step.focused[data-v-4abdd121],.step[data-v-4abdd121]:focus{outline:none}.step.focused[data-v-4abdd121]:before,.step[data-v-4abdd121]:focus:before{opacity:1}@media only screen and (max-width:735px){.step[data-v-4abdd121]{padding-left:2rem}.step[data-v-4abdd121]:before{opacity:1}}.step-label[data-v-4abdd121]{font-size:.70588rem;line-height:1.33333;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--colors-text,var(--color-step-text));margin-bottom:.4em}.caption[data-v-4abdd121]{border-top:1px solid;border-color:var(--color-step-caption);padding:1rem 0 0 0;margin-top:1rem}.media-container[data-v-4abdd121]{display:none}@media only screen and (max-width:735px){.step[data-v-4abdd121]{margin:0 .58824rem 1.17647rem .58824rem}.step.focused[data-v-4abdd121],.step[data-v-4abdd121]:focus{outline:none}.media-container[data-v-4abdd121]{display:block;position:relative}.media-container[data-v-4abdd121] img,.media-container[data-v-4abdd121] video{max-height:80vh}[data-v-4abdd121] .asset{padding:0 20px}}.steps[data-v-25d30c2c]{position:relative;font-size:.82353rem;line-height:1.42857;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;display:flex;color:var(--colors-text,var(--color-text))}@media only screen and (max-width:735px){.steps[data-v-25d30c2c]{padding-top:80px}.steps[data-v-25d30c2c]:before{position:absolute;top:0;border-top:1px solid var(--color-fill-gray-tertiary);content:"";width:calc(100% - 2.35294rem);margin:0 1.17647rem}}.content-container[data-v-25d30c2c]{flex:none;margin-right:4.16667%;width:37.5%;margin-top:140px;margin-bottom:94vh}@media only screen and (max-width:735px){.content-container[data-v-25d30c2c]{margin-top:0;margin-bottom:0;height:100%;margin-left:0;margin-right:0;position:relative;width:100%}}.asset-container[data-v-25d30c2c]{flex:none;height:calc(100vh - 3.05882rem);background-color:var(--background,var(--color-step-background));max-width:921px;width:calc(50vw + 8.33333%);position:sticky;top:3.05882rem;transition:margin .1s ease-in-out}@media only screen and (max-width:767px){.asset-container[data-v-25d30c2c]{top:2.82353rem;height:calc(100vh - 2.82353rem)}}.asset-container[data-v-25d30c2c]:not(.for-step-code){overflow-y:auto;-webkit-overflow-scrolling:touch}.asset-container.ide[data-v-25d30c2c]{height:100vh;top:0}@media only screen and (min-width:736px){.asset-container[data-v-25d30c2c]{display:grid}.asset-container>[data-v-25d30c2c]{grid-row:1;grid-column:1;height:calc(100vh - 3.05882rem)}.asset-container.ide>[data-v-25d30c2c]{height:100vh}}.asset-container .step-asset[data-v-25d30c2c]{box-sizing:border-box;padding:0;padding-left:40px;min-height:320px;height:100%}.asset-container .step-asset[data-v-25d30c2c],.asset-container .step-asset[data-v-25d30c2c] picture{height:100%;display:flex;align-items:center}.asset-container .step-asset[data-v-25d30c2c] .video-replay-container{height:100%;display:flex;flex-direction:column;justify-content:center}.asset-container .step-asset[data-v-25d30c2c] img,.asset-container .step-asset[data-v-25d30c2c] video{width:auto;max-height:calc(100vh - 3.05882rem - 80px);max-width:531.6634px;margin:0}@media only screen and (max-width:1250px){.asset-container .step-asset[data-v-25d30c2c] img,.asset-container .step-asset[data-v-25d30c2c] video{max-width:363.66436px}}.asset-container .step-asset[data-v-25d30c2c] .video-replay-container,.asset-container .step-asset[data-v-25d30c2c] img{min-height:320px}.asset-container .step-asset[data-v-25d30c2c] .video-replay-container video{min-height:280px}@media only screen and (max-width:735px){.asset-container[data-v-25d30c2c]{display:none}}.asset-wrapper[data-v-25d30c2c]{width:63.2%;align-self:center;transition:transform .25s ease-out;will-change:transform}.asset-wrapper.ide .step-asset[data-v-25d30c2c] img{background-color:var(--background,var(--color-step-background))}[data-v-25d30c2c] .runtime-preview-asset{display:grid}[data-v-25d30c2c] .runtime-preview-asset>*{grid-row:1;grid-column:1}.interstitial[data-v-25d30c2c]{padding:0 2rem}.interstitial[data-v-25d30c2c]:not(:first-child){margin-top:5.88235rem}.interstitial[data-v-25d30c2c]:not(:last-child){margin-bottom:30px}@media only screen and (max-width:735px){.interstitial[data-v-25d30c2c]{margin-left:auto;margin-right:auto;width:980px;padding:0}}@media only screen and (max-width:735px) and (max-width:1250px){.interstitial[data-v-25d30c2c]{width:692px}}@media only screen and (max-width:735px) and (max-width:735px){.interstitial[data-v-25d30c2c]{width:87.5%}}@media only screen and (max-width:735px){.interstitial[data-v-25d30c2c]:not(:first-child){margin-top:0}}.fade-enter-active[data-v-25d30c2c],.fade-leave-active[data-v-25d30c2c]{transition:opacity .3s ease-in-out}.fade-enter[data-v-25d30c2c],.fade-leave-to[data-v-25d30c2c]{opacity:0}.section[data-v-6b3a0b3a]{padding-top:80px}.sections[data-v-79a75e9e]{margin-left:auto;margin-right:auto;width:980px}@media only screen and (max-width:1250px){.sections[data-v-79a75e9e]{width:692px}}@media only screen and (max-width:735px){.sections[data-v-79a75e9e]{width:87.5%;margin:0;width:100%}}.tutorial[data-v-0f871b08]{background-color:var(--colors-text-background,var(--color-tutorial-background))}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/css/tutorials-overview.06e8bcf7.css b/docs/docc/Reducer.doccarchive/css/tutorials-overview.06e8bcf7.css
deleted file mode 100644
index 9f65a57..0000000
--- a/docs/docc/Reducer.doccarchive/css/tutorials-overview.06e8bcf7.css
+++ /dev/null
@@ -1,9 +0,0 @@
-/*!
- * This source file is part of the Swift.org open source project
- *
- * Copyright (c) 2021 Apple Inc. and the Swift project authors
- * Licensed under Apache License v2.0 with Runtime Library Exception
- *
- * See https://swift.org/LICENSE.txt for license information
- * See https://swift.org/CONTRIBUTORS.txt for Swift project authors
- */.tutorials-navigation-link[data-v-6bb99205]{color:var(--color-tutorials-overview-navigation-link);transition:color .3s linear}.tutorials-navigation-link[data-v-6bb99205]:hover{text-decoration:none;transition:none;color:var(--color-tutorials-overview-navigation-link-hover)}.tutorials-navigation-link.active[data-v-6bb99205]{color:var(--color-tutorials-overview-navigation-link-active)}.tutorials-navigation-list[data-v-6f2800d1]{list-style-type:none;margin:0}.tutorials-navigation-list li+li[data-v-6f2800d1]:not(.volume--named){margin-top:24px}.tutorials-navigation-list .volume--named+.volume--named[data-v-6f2800d1]{margin-top:12px}.expand-enter-active,.expand-leave-active{transition:height .3s ease-in-out;overflow:hidden}.expand-enter,.expand-leave-to{height:0}.toggle[data-v-6513d652]{color:#f0f0f0;line-height:21px;display:flex;align-items:center;width:100%;font-weight:600;padding:6px 6px 6px 0;border-bottom:1px solid #2a2a2a;text-decoration:none;box-sizing:border-box}@media only screen and (max-width:767px){.toggle[data-v-6513d652]{padding-right:6px;border-bottom-color:hsla(0,0%,100%,.1)}}.toggle .text[data-v-6513d652]{word-break:break-word}.toggle[data-v-6513d652]:hover{text-decoration:none}.toggle .toggle-icon[data-v-6513d652]{display:inline-block;transition:transform .2s ease-in;height:.4em;width:.4em;margin-left:auto;margin-right:.2em}.collapsed .toggle .toggle-icon[data-v-6513d652]{transform:rotate(45deg)}.collapsed .toggle[data-v-6513d652],.collapsed .toggle[data-v-6513d652]:hover{color:#b0b0b0}.tutorials-navigation-menu-content[data-v-6513d652]{opacity:1;transition:height .2s ease-in,opacity .2s ease-in}.collapsed .tutorials-navigation-menu-content[data-v-6513d652]{height:0;opacity:0}.tutorials-navigation-menu-content .tutorials-navigation-list[data-v-6513d652]{padding:24px 0 12px 0}.tutorials-navigation[data-v-0cbd8adb]{font-size:1rem;line-height:1.23529;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.nav-title-content[data-v-60ea3af8]{max-width:100%}.title[data-v-60ea3af8]{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;display:inline-block;vertical-align:top;max-width:296px}@media only screen and (max-width:1023px){.title[data-v-60ea3af8]{max-width:205px}}@media only screen and (max-width:767px){.title[data-v-60ea3af8]{flex-basis:fill;display:initial;vertical-align:initial;max-width:none}}.subhead[data-v-60ea3af8]{color:var(--color-nav-root-subhead)}.theme-dark .subhead[data-v-60ea3af8]{color:var(--color-nav-dark-root-subhead)}.nav[data-v-1001350c] .nav-menu{padding-top:0}.nav[data-v-1001350c] .nav-menu .nav-menu-items{margin-left:auto}@media only screen and (min-width:768px){.nav[data-v-1001350c] .nav-menu .nav-menu-items .in-page-navigation{display:none}}@media only screen and (min-width:320px) and (max-width:735px){.nav[data-v-1001350c] .nav-menu .nav-menu-items{padding:18px 0 40px}}.replay-button[data-v-59608016]{display:flex;align-items:center;justify-content:center;cursor:pointer;visibility:hidden;margin-top:.5rem;-webkit-tap-highlight-color:transparent}.replay-button.visible[data-v-59608016]{visibility:visible}.replay-button svg.replay-icon[data-v-59608016]{height:12px;width:12px;margin-left:.3em}[data-v-1b5cc854] img,[data-v-1b5cc854] video{display:block;margin-left:auto;margin-right:auto;-o-object-fit:contain;object-fit:contain;max-width:100%}.hero[data-v-fc7f508c]{margin-left:auto;margin-right:auto;width:980px;padding-bottom:4.70588rem;padding-top:4.70588rem}@media only screen and (max-width:1250px){.hero[data-v-fc7f508c]{width:692px}}@media only screen and (max-width:735px){.hero[data-v-fc7f508c]{width:87.5%}}.copy-container[data-v-fc7f508c]{margin:0 auto;text-align:center;width:720px}.title[data-v-fc7f508c]{font-size:2.82353rem;line-height:1.08333;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--color-tutorials-overview-content)}@media only screen and (max-width:1250px){.title[data-v-fc7f508c]{font-size:2.35294rem;line-height:1.1;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){.title[data-v-fc7f508c]{font-size:1.88235rem;line-height:1.125;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.content[data-v-fc7f508c]{font-size:1.23529rem;line-height:1.38095;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--color-tutorials-overview-content)}@media only screen and (max-width:735px){.content[data-v-fc7f508c]{font-size:1.11765rem;line-height:1.42105;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.meta[data-v-fc7f508c]{color:var(--color-tutorials-overview-content-alt);align-items:center;display:flex;justify-content:center}.meta-content[data-v-fc7f508c]{font-size:.82353rem;line-height:1.42857;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.meta .timer-icon[data-v-fc7f508c]{margin-right:.35294rem;height:.94118rem;width:.94118rem;fill:var(--color-tutorials-overview-icon)}@media only screen and (max-width:735px){.meta .timer-icon[data-v-fc7f508c]{margin-right:.29412rem;height:.82353rem;width:.82353rem}}.meta .time[data-v-fc7f508c]{font-size:1.11765rem;line-height:1.21053;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}@media only screen and (max-width:735px){.meta .time[data-v-fc7f508c]{font-size:1rem;line-height:1.11765;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.title+.content[data-v-fc7f508c]{margin-top:1.47059rem}.content+.meta[data-v-fc7f508c]{margin-top:1.17647rem}.button-cta[data-v-fc7f508c]{margin-top:1.76471rem}*+.asset[data-v-fc7f508c]{margin-top:4.11765rem}@media only screen and (max-width:1250px){.copy-container[data-v-fc7f508c]{width:636px}}@media only screen and (max-width:735px){.hero[data-v-fc7f508c]{padding-bottom:1.76471rem;padding-top:2.35294rem}.copy-container[data-v-fc7f508c]{width:100%}.title+.content[data-v-fc7f508c]{margin-top:.88235rem}.button-cta[data-v-fc7f508c]{margin-top:1.41176rem}*+.asset[data-v-fc7f508c]{margin-top:2.23529rem}}.image[data-v-14577284]{margin-bottom:10px}.name[data-v-14577284]{font-size:1.88235rem;line-height:1.125;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:#f0f0f0;word-break:break-word}@media only screen and (max-width:1250px){.name[data-v-14577284]{font-size:1.64706rem;line-height:1.14286;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){.name[data-v-14577284]{font-size:1.41176rem;line-height:1.16667;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.content[data-v-14577284]{font-size:1rem;line-height:1.23529;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--color-tutorials-overview-content-alt);margin-top:10px}.volume-name[data-v-14577284]{padding:50px 60px;text-align:center;background:#161616;margin:2px 0}@media only screen and (max-width:735px){.volume-name[data-v-14577284]{padding:40px 20px}}.document-icon[data-v-56114692]{margin-left:-3px}.tile[data-v-86db603a]{background:#161616;padding:40px 30px;color:var(--color-tutorials-overview-content-alt)}.content[data-v-86db603a] a,a[data-v-86db603a]{color:var(--colors-link,var(--color-tutorials-overview-link))}.icon[data-v-86db603a]{display:block;height:1.47059rem;line-height:1.47059rem;margin-bottom:.58824rem;width:1.47059rem}.icon[data-v-86db603a] svg.svg-icon{width:100%;max-height:100%;fill:var(--color-tutorials-overview-icon)}.icon[data-v-86db603a] svg.svg-icon .svg-icon-stroke{stroke:var(--color-tutorials-overview-content-alt)}.title[data-v-86db603a]{font-size:1.23529rem;line-height:1.19048;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;margin-bottom:.8em}.content[data-v-86db603a],.link[data-v-86db603a]{font-size:.82353rem;line-height:1.42857;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.content[data-v-86db603a]{color:var(--color-tutorials-overview-content-alt)}.link[data-v-86db603a]{display:block;margin-top:1.17647rem}.link .link-icon[data-v-86db603a]{margin-left:.2em;width:.6em;height:.6em}[data-v-86db603a] .content ul{list-style-type:none;margin-left:0;font-size:.82353rem;line-height:1.28571;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}[data-v-86db603a] .content ul li:before{content:"\200B";position:absolute}[data-v-86db603a] .content li+li{margin-top:8px}@media only screen and (max-width:735px){.tile[data-v-86db603a]{padding:1.76471rem 1.17647rem}}.tile-group[data-v-015f9f13]{display:grid;grid-column-gap:2px;grid-row-gap:2px}.tile-group.count-1[data-v-015f9f13]{grid-template-columns:1fr;text-align:center}.tile-group.count-1[data-v-015f9f13] .icon{margin-left:auto;margin-right:auto}.tile-group.count-2[data-v-015f9f13]{grid-template-columns:repeat(2,1fr)}.tile-group.count-3[data-v-015f9f13]{grid-template-columns:repeat(3,1fr)}.tile-group.count-4[data-v-015f9f13]{grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(2,auto)}.tile-group.count-5[data-v-015f9f13]{grid-template-columns:repeat(6,1fr);grid-template-rows:repeat(2,auto)}.tile-group.count-5 .tile[data-v-015f9f13]{grid-column-end:span 2}.tile-group.count-5 .tile[data-v-015f9f13]:nth-of-type(-n+2){grid-column-end:span 3}.tile-group.count-6[data-v-015f9f13]{grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(3,auto)}@media only screen and (min-width:768px) and (max-width:1250px){.tile-group.tile-group[data-v-015f9f13]{grid-template-columns:1fr;grid-template-rows:auto}}@media only screen and (max-width:735px){.tile-group.count-1[data-v-015f9f13],.tile-group.count-2[data-v-015f9f13],.tile-group.count-3[data-v-015f9f13],.tile-group.count-4[data-v-015f9f13],.tile-group.count-5[data-v-015f9f13],.tile-group.count-6[data-v-015f9f13]{grid-template-columns:1fr;grid-template-rows:auto}}.title[data-v-49ba6f62]{font-size:1.88235rem;line-height:1.125;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:#f0f0f0}@media only screen and (max-width:1250px){.title[data-v-49ba6f62]{font-size:1.64706rem;line-height:1.14286;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}@media only screen and (max-width:735px){.title[data-v-49ba6f62]{font-size:1.41176rem;line-height:1.16667;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.content[data-v-49ba6f62]{font-size:1rem;line-height:1.23529;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:#b0b0b0;margin-top:10px}.topic-list[data-v-da979188]{list-style-type:none;margin:50px 0 0 0;position:relative}.topic-list li[data-v-da979188]:before{content:"\200B";position:absolute}.topic-list[data-v-da979188]:before{content:"";border-left:1px solid var(--color-fill-quaternary);display:block;height:calc(100% - .88235rem);left:.88235rem;position:absolute;top:50%;transform:translateY(-50%);width:0}.topic[data-v-da979188]{font-size:1rem;line-height:1.47059;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;display:flex;align-items:flex-start}@media only screen and (max-width:735px){.topic[data-v-da979188]{font-size:.82353rem;line-height:1.28571;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}}.topic+.topic[data-v-da979188]{margin-top:.58824rem}.topic .topic-icon[data-v-da979188]{background-color:var(--color-fill-quaternary);border-radius:50%;flex-shrink:0;height:1.76471rem;width:1.76471rem;margin-right:1.17647rem;position:relative;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:.47059rem;box-sizing:border-box;display:flex;justify-content:center;align-items:center}.topic .topic-icon svg[data-v-da979188]{fill:var(--color-tutorials-overview-icon);max-width:100%;max-height:100%;width:100%}.container[data-v-da979188]{align-items:baseline;display:flex;justify-content:space-between;width:100%;padding-top:.11765rem}.container[data-v-da979188]:hover{text-decoration:none}.container:hover .link[data-v-da979188]{text-decoration:underline}.timer-icon[data-v-da979188]{margin-right:.29412rem;height:.70588rem;width:.70588rem;fill:var(--color-tutorials-overview-icon)}.time[data-v-da979188]{font-size:.82353rem;line-height:1.28571;font-weight:400;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:var(--color-tutorials-overview-content-alt);align-items:center;display:inline-flex}.link[data-v-da979188]{padding-right:.58824rem;color:var(--colors-link,var(--color-tutorials-overview-link))}@media only screen and (min-width:768px) and (max-width:1250px){.topic-list[data-v-da979188]{margin-top:2.35294rem}}@media only screen and (max-width:735px){.topic-list[data-v-da979188]{margin-top:1.76471rem}.topic[data-v-da979188]{height:auto;align-items:flex-start}.topic.no-time-estimate[data-v-da979188]{align-items:center}.topic.no-time-estimate .topic-icon[data-v-da979188]{align-self:flex-start;top:0}.topic+.topic[data-v-da979188]{margin-top:1.17647rem}.topic .topic-icon[data-v-da979188]{top:.29412rem;margin-right:.76471rem}.container[data-v-da979188]{flex-wrap:wrap;padding-top:0}.link[data-v-da979188],.time[data-v-da979188]{flex-basis:100%}.time[data-v-da979188]{margin-top:.29412rem}}.chapter[data-v-1d13969f]:focus{outline:none!important}.info[data-v-1d13969f]{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.name[data-v-1d13969f]{font-size:1.23529rem;line-height:1.19048;font-weight:600;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:#f0f0f0}.name-text[data-v-1d13969f]{word-break:break-word}.eyebrow[data-v-1d13969f]{font-size:1rem;line-height:1.23529;font-weight:400;color:var(--color-tutorials-overview-eyebrow);display:block;font-weight:600;margin-bottom:5px}.content[data-v-1d13969f],.eyebrow[data-v-1d13969f]{font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.content[data-v-1d13969f]{font-size:.82353rem;line-height:1.42857;font-weight:400;color:var(--color-tutorials-overview-content-alt)}.asset[data-v-1d13969f]{flex:0 0 190px}.intro[data-v-1d13969f]{flex:0 1 360px}@media only screen and (min-width:768px) and (max-width:1250px){.asset[data-v-1d13969f]{flex:0 0 130px}.intro[data-v-1d13969f]{flex:0 1 260px}}@media only screen and (max-width:767px){.intro[data-v-1d13969f]{flex:0 1 340px}}@media only screen and (max-width:735px){.info[data-v-1d13969f]{display:block;text-align:center}.asset[data-v-1d13969f]{margin:0 45px}.eyebrow[data-v-1d13969f]{margin-bottom:7px}.intro[data-v-1d13969f]{margin-top:40px}}.tile[data-v-2129f58c]{background:#161616;margin:2px 0;padding:50px 60px}.asset[data-v-2129f58c]{margin-bottom:10px}@media only screen and (min-width:768px) and (max-width:1250px){.tile[data-v-2129f58c]{padding:40px 30px}}@media only screen and (max-width:735px){.volume[data-v-2129f58c]{border-radius:0}.tile[data-v-2129f58c]{padding:40px 20px}}.learning-path[data-v-48bfa85c]{background:#000;padding:4.70588rem 0}.main-container[data-v-48bfa85c]{margin-left:auto;margin-right:auto;width:980px;align-items:stretch;display:flex;justify-content:space-between}@media only screen and (max-width:1250px){.main-container[data-v-48bfa85c]{width:692px}}@media only screen and (max-width:735px){.main-container[data-v-48bfa85c]{width:87.5%}}.ide .main-container[data-v-48bfa85c]{justify-content:center}.secondary-content-container[data-v-48bfa85c]{flex:0 0 200px;width:200px}.tutorials-navigation[data-v-48bfa85c]{position:sticky;top:7.76471rem}.primary-content-container[data-v-48bfa85c]{flex:0 1 720px;max-width:100%}.content-sections-container .content-section[data-v-48bfa85c]{border-radius:12px;overflow:hidden}.content-sections-container .content-section+.content-section[data-v-48bfa85c]{margin-top:1.17647rem}@media only screen and (min-width:768px) and (max-width:1250px){.learning-path[data-v-48bfa85c]{padding:2.35294rem 0}.primary-content-container[data-v-48bfa85c]{flex-basis:auto;margin-left:1.29412rem}.secondary-content-container[data-v-48bfa85c]{flex:0 0 180px;width:180px}}@media only screen and (max-width:767px){.secondary-content-container[data-v-48bfa85c]{display:none}}@media only screen and (max-width:735px){.content-sections-container .content-section[data-v-48bfa85c]{border-radius:0}.content-sections-container .content-section.volume[data-v-48bfa85c]{margin-top:1.17647rem}.learning-path[data-v-48bfa85c]{padding:0}.main-container[data-v-48bfa85c]{width:100%}}.tutorials-overview[data-v-53888684]{height:100%}.tutorials-overview .radial-gradient[data-v-53888684]{margin-top:-3.05882rem;padding-top:3.05882rem;background:var(--color-tutorials-overview-background)}@media only screen and (max-width:735px){.tutorials-overview .radial-gradient[data-v-53888684]{margin-top:-2.82353rem;padding-top:2.82353rem}}@-moz-document url-prefix(){.tutorials-overview .radial-gradient{background:#111!important}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer.json b/docs/docc/Reducer.doccarchive/data/documentation/reducer.json
deleted file mode 100644
index c407b78..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer.json
+++ /dev/null
@@ -1 +0,0 @@
-{"variants":[{"paths":["\/documentation\/reducer"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer","interfaceLanguage":"swift"},"topicSections":[{"title":"Structures","identifiers":["doc:\/\/Reducer\/documentation\/Reducer\/Reducer"]},{"title":"Enumerations","identifiers":["doc:\/\/Reducer\/documentation\/Reducer\/ReducerBuilder"]}],"kind":"symbol","metadata":{"roleHeading":"Framework","externalID":"Reducer","title":"Reducer","symbolKind":"module","role":"collection","modules":[{"name":"Reducer"}]},"hierarchy":{"paths":[[]]},"references":{"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"},"doc://Reducer/documentation/Reducer/ReducerBuilder":{"role":"symbol","title":"ReducerBuilder","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"ReducerBuilder"}],"abstract":[{"type":"text","text":"DSL Builder for Reducer compose"}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/ReducerBuilder","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ReducerBuilder"}],"url":"\/documentation\/reducer\/reducerbuilder"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer.json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer.json
deleted file mode 100644
index 618227e..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer.json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"ActionType"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"StateType"},{"kind":"text","text":">"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"content","content":[{"anchor":"overview","level":2,"type":"heading","text":"Overview"},{"type":"paragraph","inlineContent":[{"type":"text","text":"An app triggers several actions over time, either coming from user input (button tap, scroll, pinch gesture), from sensors (CoreLocation, NFC,"},{"type":"text","text":" "},{"type":"text","text":"HealthKit), communication protocols (CoreBluetooth, networking, WebSocket), databases (CoreData, Realm), timers and many more."},{"type":"text","text":" "},{"type":"text","text":"An app also starts with an initial state, right after its cold launch."},{"type":"text","text":" "},{"type":"text","text":"For each action that arrives, the state can be modified, and this is exactly what a "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" does: folds all actions that arrived since the app"},{"type":"text","text":" "},{"type":"text","text":"launch, plus the initial state, into the current state. One at the time."},{"type":"text","text":" "},{"type":"text","text":"The shape of a "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" could be represented as "},{"type":"codeVoice","code":"(Action, State) -> State"},{"type":"text","text":", or given the incoming action and the latest known state, calculate the"},{"type":"text","text":" "},{"type":"text","text":"new state."},{"type":"text","text":" "},{"type":"text","text":"For the sake of performance, and keeping the same semantics, the SwiftRex "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" is represented as "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":", avoiding"},{"type":"text","text":" "},{"type":"text","text":"unnecessary copies and allowing performance tuning for arrays or other big collections."},{"type":"text","text":" "},{"type":"text","text":"A "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" can focus in a small part, and be composed with other reducers. The order of this composition matters, because the state will be modified"},{"type":"text","text":" "},{"type":"text","text":"in the order as the reducers were composed, but you should avoid two reducers changing the same domain. If you can’t avoid, mind the order."},{"type":"text","text":" "},{"type":"text","text":"A "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" can also focus in a subset of your full AppAction and AppState, and be “lifted” from the subset to the whole, for example it’s focused on"},{"type":"text","text":" "},{"type":"text","text":"LoginAction and LoginState, then lifted to the whole AppAction and AppState by providing the KeyPath where the subset LoginAction is in the"},{"type":"text","text":" "},{"type":"text","text":"AppAction, and where the subset LoginState is in the AppState."}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducer"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"title":"Reducer","roleHeading":"Structure","role":"symbol","symbolKind":"struct","externalID":"s:7ReducerAAV","modules":[{"name":"Reducer"}],"navigatorTitle":[{"kind":"identifier","text":"Reducer"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer"]]},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/reduce"]},{"title":"Instance Methods","identifiers":["doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(action:)","doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(action:state:)","doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(actionGetter:stateGetter:stateSetter:)","doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(state:)","doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/liftToCollection(action:stateCollection:)-4gphe","doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/liftToCollection(action:stateCollection:)-5a160","doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/liftToCollection(action:stateCollection:identifier:)"]},{"title":"Type Properties","identifiers":["doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/identity"]},{"title":"Type Methods","identifiers":["doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/compose(_:_:)","doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/compose(content:)","doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/reduce(_:)"]}],"references":{"doc://Reducer/documentation/Reducer/Reducer/reduce(_:)":{"role":"symbol","title":"reduce(_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"reduce"},{"kind":"text","text":"(("},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"}],"abstract":[{"type":"text","text":"Reducer initialiser takes only the underlying function "},{"type":"codeVoice","code":"(ActionType, inout StateType) -> Void"},{"type":"text","text":" that is the reducer"},{"type":"text","text":" "},{"type":"text","text":"function itself."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/reduce(_:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/reduce(_:)"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"},"doc://Reducer/documentation/Reducer/Reducer/compose(_:_:)":{"role":"symbol","title":"compose(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"compose"},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"...) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"}],"abstract":[{"type":"text","text":"Composes two or more reducers in series, to be evaluated from the left to the right for each incoming action."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/compose(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/compose(_:_:)"},"doc://Reducer/documentation/Reducer/Reducer/reduce":{"role":"symbol","title":"reduce","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"reduce"},{"kind":"text","text":": ("},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"}],"abstract":[{"type":"text","text":"Execute the wrapped reduce function. You must provide the parameters "},{"type":"codeVoice","code":"action: ActionType"},{"type":"text","text":" (the action to be"},{"type":"text","text":" "},{"type":"text","text":"evaluated during the reducing process) and an "},{"type":"codeVoice","code":"inout"},{"type":"text","text":" version of the latest "},{"type":"codeVoice","code":"state: StateType"},{"type":"text","text":", (the current"},{"type":"text","text":" "},{"type":"text","text":"state in your single source-of-truth)."},{"type":"text","text":" "},{"type":"text","text":"State will be mutated in place ("},{"type":"codeVoice","code":"inout"},{"type":"text","text":") and finish with the calculated new state."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/reduce","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/reduce"},"doc://Reducer/documentation/Reducer/Reducer/lift(actionGetter:stateGetter:stateSetter:)":{"role":"symbol","title":"lift(actionGetter:stateGetter:stateSetter:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalActionType"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalStateType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"actionGetter"},{"kind":"text","text":": ("},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":"?, "},{"kind":"externalParam","text":"stateGetter"},{"kind":"text","text":": ("},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":", "},{"kind":"externalParam","text":"stateSetter"},{"kind":"text","text":": ("},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":", that is a"},{"type":"text","text":" "},{"type":"text","text":"sub-state."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(actionGetter:stateGetter:stateSetter:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lift(actiongetter:stategetter:statesetter:)"},"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"},"doc://Reducer/documentation/Reducer/Reducer/liftToCollection(action:stateCollection:)-5a160":{"conformance":{"constraints":[{"type":"codeVoice","code":"StateType"},{"type":"text","text":" conforms to "},{"type":"codeVoice","code":"Identifiable"},{"type":"text","text":"."}],"availabilityPrefix":[{"type":"text","text":"Available when"}],"conformancePrefix":[{"type":"text","text":"Conforms when"}]},"role":"symbol","title":"liftToCollection(action:stateCollection:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"liftToCollection"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalAction"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"CollectionState"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", (id"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE9StateTypeq_mfp"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"ID","preciseIdentifier":"s:s12IdentifiableP2IDQa"},{"kind":"text","text":", action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE10ActionTypexmfp"},{"kind":"text","text":")?>, "},{"kind":"externalParam","text":"stateCollection"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF0E5StateL_qd_1_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method for collections. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles an element"},{"type":"text","text":" "},{"type":"text","text":"that is inside of a collection, which itself is sub-state of the global. Let’s call this single element "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/liftToCollection(action:stateCollection:)-5a160","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lifttocollection(action:statecollection:)-5a160"},"doc://Reducer/documentation/Reducer/Reducer/lift(action:)":{"role":"symbol","title":"lift(action:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalActionType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6actionAByqd__q_Gs7KeyPathCyqd__xSgG_tlF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":"?>) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6actionAByqd__q_Gs7KeyPathCyqd__xSgG_tlF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":", that is a"},{"type":"text","text":" "},{"type":"text","text":"sub-state."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(action:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lift(action:)"},"doc://Reducer/documentation/Reducer/Reducer/identity":{"role":"symbol","title":"identity","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"identity"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"No-op reducer. Composing it with any other reducer will not change anything from the other reducer behaviour, regardless if the identity reducer"},{"type":"text","text":" "},{"type":"text","text":"is on the left-hand side or the right-hand side or this composition. This is the neutral element in a monoidal composition."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/identity","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/identity"},"doc://Reducer/documentation/Reducer/Reducer/lift(action:state:)":{"role":"symbol","title":"lift(action:state:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalActionType"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalStateType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":"?>, "},{"kind":"externalParam","text":"state"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":", that is a"},{"type":"text","text":" "},{"type":"text","text":"sub-state."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(action:state:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lift(action:state:)"},"doc://Reducer/documentation/Reducer/Reducer/lift(state:)":{"role":"symbol","title":"lift(state:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalStateType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"state"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift5stateAByxqd__Gs15WritableKeyPathCyqd__q_G_tlF15GlobalStateTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift5stateAByxqd__Gs15WritableKeyPathCyqd__q_G_tlF15GlobalStateTypeL_qd__mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":", that is a"},{"type":"text","text":" "},{"type":"text","text":"sub-state."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(state:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lift(state:)"},"doc://Reducer/documentation/Reducer/Reducer/liftToCollection(action:stateCollection:)-4gphe":{"role":"symbol","title":"liftToCollection(action:stateCollection:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"liftToCollection"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalAction"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"CollectionState"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", (index"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF0D5StateL_qd_1_mfp"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Index","preciseIdentifier":"s:Sl5IndexQa"},{"kind":"text","text":", action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":")?>, "},{"kind":"externalParam","text":"stateCollection"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF0D5StateL_qd_1_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method for collections. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles an element"},{"type":"text","text":" "},{"type":"text","text":"that is inside of a collection, which itself is sub-state of the global. Let’s call this single element "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/liftToCollection(action:stateCollection:)-4gphe","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lifttocollection(action:statecollection:)-4gphe"},"doc://Reducer/documentation/Reducer/Reducer/liftToCollection(action:stateCollection:identifier:)":{"role":"symbol","title":"liftToCollection(action:stateCollection:identifier:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"liftToCollection"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalAction"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"CollectionState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"ID"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", (id"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ID","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF2IDL_qd_2_mfp"},{"kind":"text","text":", action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":")?>, "},{"kind":"externalParam","text":"stateCollection"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF0D5StateL_qd_1_mfp"},{"kind":"text","text":">, "},{"kind":"externalParam","text":"identifier"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"ID","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF2IDL_qd_2_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method for collections. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles an element"},{"type":"text","text":" "},{"type":"text","text":"that is inside of a collection, which itself is sub-state of the global. Let’s call this single element "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/liftToCollection(action:stateCollection:identifier:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lifttocollection(action:statecollection:identifier:)"},"doc://Reducer/documentation/Reducer/Reducer/compose(content:)":{"role":"symbol","title":"compose(content:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"compose"},{"kind":"text","text":"("},{"kind":"externalParam","text":"content"},{"kind":"text","text":": () -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"}],"abstract":[{"type":"text","text":"Composes two or more reducers in series, to be evaluated from the top to the bottom for each incoming action."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/compose(content:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/compose(content:)"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/compose(_:_:).json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/compose(_:_:).json
deleted file mode 100644
index 0aec46c..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/compose(_:_:).json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"compose"},{"kind":"text","text":"("},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"first"},{"kind":"text","text":": "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"},{"kind":"text","text":", "},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"others"},{"kind":"text","text":": "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"},{"kind":"text","text":"...) -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"content","content":[{"anchor":"return-value","level":2,"type":"heading","text":"Return Value"},{"type":"paragraph","inlineContent":[{"type":"text","text":"a composed reducer "},{"type":"codeVoice","code":"(ActionType, inout StateType) -> Void"},{"type":"text","text":" equivalent to "},{"type":"codeVoice","code":"g(f(x))"}]}]},{"kind":"parameters","parameters":[{"name":"first","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"First reducer "},{"type":"codeVoice","code":"(ActionType, inout StateType) -> Void"},{"type":"text","text":", let’s call it "},{"type":"codeVoice","code":"f(x)"}]}]},{"name":"others","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"Second, Third, nth reducers "},{"type":"codeVoice","code":"(ActionType, inout StateType) -> Void"},{"type":"text","text":", let’s call it "},{"type":"codeVoice","code":"g(x)"}]}]}]},{"kind":"content","content":[{"anchor":"discussion","level":2,"type":"heading","text":"Discussion"},{"type":"paragraph","inlineContent":[{"type":"text","text":"When composing reducer A with reducer B, when an action X arrives, first it will be forwarded to"},{"type":"text","text":" "},{"type":"text","text":"reducer A together with the initial state. This reducer may return a slightly (or completely) changed state from"},{"type":"text","text":" "},{"type":"text","text":"that operation, and this state will then be forwarded to reducer B together with the same action X. If you change"},{"type":"text","text":" "},{"type":"text","text":"the order, results may vary as you can imagine. Monoids don’t necessarily hold the commutative axiom, although"},{"type":"text","text":" "},{"type":"text","text":"sometimes they do. What they necessarily hold is the associativity axiom, which means that if you compose A and B,"},{"type":"text","text":" "},{"type":"text","text":"and later C, it’s exactly the same as if you compose A to a previously composed B and C:"},{"type":"text","text":" "},{"type":"codeVoice","code":".compose(.compose(A, B), C) == .compose(A, .compose(B, C))"},{"type":"text","text":". So please don’t worry about surrounding your reducers with parenthesis:"}]},{"type":"codeListing","syntax":null,"code":["let globalReducer = .compose(firstReducer, secondReducer, thirdReducer, andSoOn)"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducer\/compose(_:_:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/compose(_:_:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Composes two or more reducers in series, to be evaluated from the left to the right for each incoming action."}],"kind":"symbol","metadata":{"role":"symbol","title":"compose(_:_:)","roleHeading":"Type Method","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"compose"},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"...) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"}],"symbolKind":"method","externalID":"s:7ReducerAAV7composeyAByxq_GAD_ADdtFZ","extendedModule":"Reducer","modules":[{"name":"Reducer"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer","doc:\/\/Reducer\/documentation\/Reducer\/Reducer"]]},"references":{"doc://Reducer/documentation/Reducer/Reducer/compose(_:_:)":{"role":"symbol","title":"compose(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"compose"},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"...) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"}],"abstract":[{"type":"text","text":"Composes two or more reducers in series, to be evaluated from the left to the right for each incoming action."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/compose(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/compose(_:_:)"},"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/compose(content:).json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/compose(content:).json
deleted file mode 100644
index 785b480..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/compose(content:).json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"compose"},{"kind":"text","text":"("},{"kind":"externalParam","text":"content"},{"kind":"text","text":": () -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"content","content":[{"anchor":"return-value","level":2,"type":"heading","text":"Return Value"},{"type":"paragraph","inlineContent":[{"type":"text","text":"a composed reducer "},{"type":"codeVoice","code":"(ActionType, inout StateType) -> Void"},{"type":"text","text":" equivalent to running all the internal"},{"type":"text","text":" "},{"type":"text","text":"reducers in series"}]}]},{"kind":"parameters","parameters":[{"name":"content","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a result builder (DSL) having zero or more reducers to be composed sequentially"}]}]}]},{"kind":"content","content":[{"anchor":"discussion","level":2,"type":"heading","text":"Discussion"},{"type":"paragraph","inlineContent":[{"type":"text","text":"When composing reducer A with reducer B, when an action X arrives, first it will be forwarded to"},{"type":"text","text":" "},{"type":"text","text":"reducer A together with the initial state. This reducer may return a slightly (or completely) changed state from"},{"type":"text","text":" "},{"type":"text","text":"that operation, and this state will then be forwarded to reducer B together with the same action X. If you change"},{"type":"text","text":" "},{"type":"text","text":"the order, results may vary as you can imagine. Monoids don’t necessarily hold the commutative axiom, although"},{"type":"text","text":" "},{"type":"text","text":"sometimes they do."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"For example you can compose reducers like this:"}]},{"type":"codeListing","syntax":null,"code":["Reducer.compose {"," Reducer"," .login"," .lift(action: \\.loginAction, state: \\.loginState)",""," Reducer"," .lifecycle"," .lift(action: \\.lifecycleAction, state: \\.lifecycleState)",""," Reducer.app",""," Reducer.reduce { action, state in"," \/\/ some inline reducer"," }","}"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducer\/compose(content:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/compose(content:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Composes two or more reducers in series, to be evaluated from the top to the bottom for each incoming action."}],"kind":"symbol","metadata":{"role":"symbol","title":"compose(content:)","roleHeading":"Type Method","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"compose"},{"kind":"text","text":"("},{"kind":"externalParam","text":"content"},{"kind":"text","text":": () -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"}],"symbolKind":"method","externalID":"s:7ReducerAAV7compose7contentAByxq_GAEyXE_tFZ","extendedModule":"Reducer","modules":[{"name":"Reducer"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer","doc:\/\/Reducer\/documentation\/Reducer\/Reducer"]]},"references":{"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"},"doc://Reducer/documentation/Reducer/Reducer/compose(content:)":{"role":"symbol","title":"compose(content:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"compose"},{"kind":"text","text":"("},{"kind":"externalParam","text":"content"},{"kind":"text","text":": () -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"}],"abstract":[{"type":"text","text":"Composes two or more reducers in series, to be evaluated from the top to the bottom for each incoming action."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/compose(content:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/compose(content:)"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/identity.json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/identity.json
deleted file mode 100644
index 80b15a8..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/identity.json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"identity"},{"kind":"text","text":": "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":"> { "},{"kind":"keyword","text":"get"},{"kind":"text","text":" }"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"content","content":[{"anchor":"discussion","level":2,"type":"heading","text":"Discussion"},{"type":"paragraph","inlineContent":[{"type":"text","text":"Therefore:"}]},{"type":"codeListing","syntax":null,"code":[" .compose( Reducer, .identity )","== .compose( .identity, Reducer )","== Reducer"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"This is useful for composition purposes, for example when you call a function "},{"type":"codeVoice","code":"Array.reduce"},{"type":"text","text":" in an array of Reducers and you need a no-op start:"}]},{"type":"codeListing","syntax":null,"code":["[reducer1, reducer2].reduce(.identity) { accumulator, nextReducer in"," Reducer.compose(accumulator, nextReducer)","}","\/\/ .identity won't have any behaviour and the final composition \".identity >>> reducer1, reducer2\" will be as if .identity wasn't there."]},{"type":"paragraph","inlineContent":[{"type":"text","text":"The implementation of this reducer, as one should expect, simply ignores the action and returns the state unchanged"}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducer\/identity"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/identity","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No-op reducer. Composing it with any other reducer will not change anything from the other reducer behaviour, regardless if the identity reducer"},{"type":"text","text":" "},{"type":"text","text":"is on the left-hand side or the right-hand side or this composition. This is the neutral element in a monoidal composition."}],"kind":"symbol","metadata":{"role":"symbol","title":"identity","roleHeading":"Type Property","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"identity"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">"}],"symbolKind":"property","externalID":"s:7ReducerAAV8identityAByxq_GvpZ","extendedModule":"Reducer","modules":[{"name":"Reducer"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer","doc:\/\/Reducer\/documentation\/Reducer\/Reducer"]]},"references":{"doc://Reducer/documentation/Reducer/Reducer/identity":{"role":"symbol","title":"identity","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"identity"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"No-op reducer. Composing it with any other reducer will not change anything from the other reducer behaviour, regardless if the identity reducer"},{"type":"text","text":" "},{"type":"text","text":"is on the left-hand side or the right-hand side or this composition. This is the neutral element in a monoidal composition."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/identity","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/identity"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"},"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lift(action:).json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lift(action:).json
deleted file mode 100644
index e805a8e..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lift(action:).json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalActionType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6actionAByqd__q_Gs7KeyPathCyqd__xSgG_tlF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":"?>) -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6actionAByqd__q_Gs7KeyPathCyqd__xSgG_tlF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"content","content":[{"anchor":"return-value","level":2,"type":"heading","text":"Return Value"},{"type":"paragraph","inlineContent":[{"type":"text","text":"a "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" that maps actions and states from the original specialized"},{"type":"text","text":" "},{"type":"text","text":"reducer into a more generic and global reducer, to be used in a larger context."}]}]},{"kind":"parameters","parameters":[{"name":"action","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a read-only key-path from global action into a local action, but it’s optional because maybe this"},{"type":"text","text":" "},{"type":"text","text":"reducer shouldn’t care about certain actions. Because actions are usually enums, you can switch over"},{"type":"text","text":" "},{"type":"text","text":"the enum and in case it’s nothing you care about, you simply return nil in the closure. If you don’t"},{"type":"text","text":" "},{"type":"text","text":"want to lift this reducer in terms of "},{"type":"codeVoice","code":"action"},{"type":"text","text":", just remove this parameter from the call."}]}]}]},{"kind":"content","content":[{"anchor":"discussion","level":2,"type":"heading","text":"Discussion"},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s suppose you may want to have a "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" that knows about the following "},{"type":"codeVoice","code":"struct"},{"type":"text","text":":"}]},{"type":"codeListing","syntax":null,"code":["struct Location {"," let latitude: Double"," let longitude: Double","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s call it "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":". Both, this state and its reducer will be part of an external framework, used by dozens of"},{"type":"text","text":" "},{"type":"text","text":"apps. Internally probably the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" will receive some known "},{"type":"codeVoice","code":"ActionType"},{"type":"text","text":" and calculate a new location. On the"},{"type":"text","text":" "},{"type":"text","text":"main app we have a global state, that we now call "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]},{"type":"codeListing","syntax":null,"code":["struct MyGlobalState {"," let title: String?"," let listOfItems: [Item]"," let currentLocation: Location","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"As expected, "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":") is a property of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":"). This relationship could be less"},{"type":"text","text":" "},{"type":"text","text":"direct, for example there could be several levels of properties until you find the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" in the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", like"},{"type":"text","text":" "},{"type":"codeVoice","code":"global.firstLevel.secondLevel.currentLocation"},{"type":"text","text":", but let’s keep it a single-level for this example."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Because our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":") and our "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":"), we"},{"type":"text","text":" "},{"type":"text","text":"must "},{"type":"codeVoice","code":"lift"},{"type":"text","text":" the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" to the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" level, by using:"}]},{"type":"codeListing","syntax":null,"code":["let globalStateReducer = gpsReducer.lift("," action: \\.self,"," state: \\.currentLocation",")","\/\/ where:","\/\/ globalStateReducer: Reducer","\/\/ ↑ lift","\/\/ gpsReducer: Reducer"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Now this reducer can be used within our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" or even composed with others. It also can be used in other apps as"},{"type":"text","text":" "},{"type":"text","text":"long as we have a way to lift it to the world of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Same strategy works for the "},{"type":"codeVoice","code":"action"},{"type":"text","text":", as you can guess by the "},{"type":"codeVoice","code":"action"},{"type":"text","text":" KeyPath parameter. You can provide a KeyPath"},{"type":"text","text":" "},{"type":"text","text":"that takes a global action ("},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":") and returns an optional local action ("},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":"). It’s optional because perhaps"},{"type":"text","text":" "},{"type":"text","text":"you want to ignore actions that are not relevant for this reducer."}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducer\/lift(action:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(action:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"A type-lifting method. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":", that is a"},{"type":"text","text":" "},{"type":"text","text":"sub-state."}],"kind":"symbol","metadata":{"role":"symbol","title":"lift(action:)","roleHeading":"Instance Method","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalActionType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6actionAByqd__q_Gs7KeyPathCyqd__xSgG_tlF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":"?>) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6actionAByqd__q_Gs7KeyPathCyqd__xSgG_tlF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">"}],"symbolKind":"method","externalID":"s:7ReducerAAV4lift6actionAByqd__q_Gs7KeyPathCyqd__xSgG_tlF","extendedModule":"Reducer","modules":[{"name":"Reducer"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer","doc:\/\/Reducer\/documentation\/Reducer\/Reducer"]]},"references":{"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"},"doc://Reducer/documentation/Reducer/Reducer/lift(action:)":{"role":"symbol","title":"lift(action:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalActionType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6actionAByqd__q_Gs7KeyPathCyqd__xSgG_tlF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":"?>) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6actionAByqd__q_Gs7KeyPathCyqd__xSgG_tlF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":", that is a"},{"type":"text","text":" "},{"type":"text","text":"sub-state."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(action:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lift(action:)"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lift(action:state:).json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lift(action:state:).json
deleted file mode 100644
index 5d8bd1e..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lift(action:state:).json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalActionType"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalStateType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":"?>, "},{"kind":"externalParam","text":"state"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":">"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"content","content":[{"anchor":"return-value","level":2,"type":"heading","text":"Return Value"},{"type":"paragraph","inlineContent":[{"type":"text","text":"a "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" that maps actions and states from the original specialised"},{"type":"text","text":" "},{"type":"text","text":"reducer into a more generic and global reducer, to be used in a larger context."}]}]},{"kind":"parameters","parameters":[{"name":"action","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a read-only key-path from global action into a local action, but it’s optional because maybe this"},{"type":"text","text":" "},{"type":"text","text":"reducer shouldn’t care about certain actions. Because actions are usually enums, you can switch over"},{"type":"text","text":" "},{"type":"text","text":"the enum and in case it’s nothing you care about, you simply return nil in the closure. If you don’t"},{"type":"text","text":" "},{"type":"text","text":"want to lift this reducer in terms of "},{"type":"codeVoice","code":"action"},{"type":"text","text":", just remove this parameter from the call."}]}]},{"name":"state","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a writable key-path from global state that traverses into a local state, by extracting only the part"},{"type":"text","text":" "},{"type":"text","text":"that it’s relevant for this reducer. This will also be used to set the new local state into the global"},{"type":"text","text":" "},{"type":"text","text":"state once the reducer finishes it’s operation. For example: "},{"type":"codeVoice","code":"\\.currentGame.scoreBoard"},{"type":"text","text":"."}]}]}]},{"kind":"content","content":[{"anchor":"discussion","level":2,"type":"heading","text":"Discussion"},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s suppose you may want to have a "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" that knows about the following "},{"type":"codeVoice","code":"struct"},{"type":"text","text":":"}]},{"type":"codeListing","syntax":null,"code":["struct Location {"," let latitude: Double"," let longitude: Double","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s call it "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":". Both, this state and its reducer will be part of an external framework, used by dozens of"},{"type":"text","text":" "},{"type":"text","text":"apps. Internally probably the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" will receive some known "},{"type":"codeVoice","code":"ActionType"},{"type":"text","text":" and calculate a new location. On the"},{"type":"text","text":" "},{"type":"text","text":"main app we have a global state, that we now call "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]},{"type":"codeListing","syntax":null,"code":["struct MyGlobalState {"," let title: String?"," let listOfItems: [Item]"," let currentLocation: Location","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"As expected, "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":") is a property of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":"). This relationship could be less"},{"type":"text","text":" "},{"type":"text","text":"direct, for example there could be several levels of properties until you find the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" in the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", like"},{"type":"text","text":" "},{"type":"codeVoice","code":"global.firstLevel.secondLevel.currentLocation"},{"type":"text","text":", but let’s keep it a single-level for this example."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Because our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":") and our "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":"), we"},{"type":"text","text":" "},{"type":"text","text":"must "},{"type":"codeVoice","code":"lift"},{"type":"text","text":" the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" to the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" level, by using:"}]},{"type":"codeListing","syntax":null,"code":["let globalStateReducer = gpsReducer.lift("," action: \\.self,"," state: \\.currentLocation",")","\/\/ where:","\/\/ globalStateReducer: Reducer","\/\/ ↑ lift","\/\/ gpsReducer: Reducer"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Now this reducer can be used within our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" or even composed with others. It also can be used in other apps as"},{"type":"text","text":" "},{"type":"text","text":"long as we have a way to lift it to the world of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Same strategy works for the "},{"type":"codeVoice","code":"action"},{"type":"text","text":", as you can guess by the "},{"type":"codeVoice","code":"action"},{"type":"text","text":" KeyPath parameter. You can provide a KeyPath"},{"type":"text","text":" "},{"type":"text","text":"that takes a global action ("},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":") and returns an optional local action ("},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":"). It’s optional because perhaps"},{"type":"text","text":" "},{"type":"text","text":"you want to ignore actions that are not relevant for this reducer."}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducer\/lift(action:state:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(action:state:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"A type-lifting method. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":", that is a"},{"type":"text","text":" "},{"type":"text","text":"sub-state."}],"kind":"symbol","metadata":{"role":"symbol","title":"lift(action:state:)","roleHeading":"Instance Method","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalActionType"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalStateType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":"?>, "},{"kind":"externalParam","text":"state"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":">"}],"symbolKind":"method","externalID":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF","extendedModule":"Reducer","modules":[{"name":"Reducer"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer","doc:\/\/Reducer\/documentation\/Reducer\/Reducer"]]},"references":{"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"},"doc://Reducer/documentation/Reducer/Reducer/lift(action:state:)":{"role":"symbol","title":"lift(action:state:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalActionType"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalStateType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":"?>, "},{"kind":"externalParam","text":"state"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift6action5stateAByqd__qd_0_Gs7KeyPathCyqd__xSgG_s08WritableeF0Cyqd_0_q_Gtr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":", that is a"},{"type":"text","text":" "},{"type":"text","text":"sub-state."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(action:state:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lift(action:state:)"},"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lift(actiongetter:stategetter:statesetter:).json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lift(actiongetter:stategetter:statesetter:).json
deleted file mode 100644
index aff1115..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lift(actiongetter:stategetter:statesetter:).json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalActionType"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalStateType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"actionGetter"},{"kind":"text","text":": "},{"kind":"attribute","text":"@escaping"},{"kind":"text","text":" ("},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":"?, "},{"kind":"externalParam","text":"stateGetter"},{"kind":"text","text":": "},{"kind":"attribute","text":"@escaping"},{"kind":"text","text":" ("},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":", "},{"kind":"externalParam","text":"stateSetter"},{"kind":"text","text":": "},{"kind":"attribute","text":"@escaping"},{"kind":"text","text":" ("},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":">"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"content","content":[{"anchor":"return-value","level":2,"type":"heading","text":"Return Value"},{"type":"paragraph","inlineContent":[{"type":"text","text":"a "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" that maps actions and states from the original specialised"},{"type":"text","text":" "},{"type":"text","text":"reducer into a more generic and global reducer, to be used in a larger context."}]}]},{"kind":"parameters","parameters":[{"name":"actionGetter","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a way to convert a global action into a local action, but it’s optional because maybe this"},{"type":"text","text":" "},{"type":"text","text":"reducer shouldn’t care about certain actions. Because actions are usually enums, you can switch"},{"type":"text","text":" "},{"type":"text","text":"over the enum and in case it’s nothing you care about, you simply return nil in the closure. If"},{"type":"text","text":" "},{"type":"text","text":"you don’t want to lift this reducer in terms of "},{"type":"codeVoice","code":"action"},{"type":"text","text":", just provide the identity function"},{"type":"text","text":" "},{"type":"codeVoice","code":"{ $0 }"},{"type":"text","text":" as input."}]}]},{"name":"stateGetter","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a way to read from a global state and extract only the part that it’s relevant for this reducer,"},{"type":"text","text":" "},{"type":"text","text":"by traversing the tree of the global state until you find the property you want, for example:"},{"type":"text","text":" "},{"type":"codeVoice","code":"{ $0.currentGame.scoreBoard }"}]}]},{"name":"stateSetter","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a way to write back into the global state once you finished reducing the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":", so now you have"},{"type":"text","text":" "},{"type":"text","text":"a new part that was calculated by this reducer and you want to set it into the global state, also"},{"type":"text","text":" "},{"type":"text","text":"provided as the first parameter as an "},{"type":"codeVoice","code":"inout"},{"type":"text","text":" property:"},{"type":"text","text":" "},{"type":"codeVoice","code":"{ globalState, newScoreBoard in globalState.currentGame.scoreBoard = newScoreBoard }"}]}]}]},{"kind":"content","content":[{"anchor":"discussion","level":2,"type":"heading","text":"Discussion"},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s suppose you may want to have a "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" that knows about the following "},{"type":"codeVoice","code":"struct"},{"type":"text","text":":"}]},{"type":"codeListing","syntax":null,"code":["struct Location {"," let latitude: Double"," let longitude: Double","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s call it "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":". Both, this state and its reducer will be part of an external framework, used by dozens of"},{"type":"text","text":" "},{"type":"text","text":"apps. Internally probably the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" will receive some known "},{"type":"codeVoice","code":"ActionType"},{"type":"text","text":" and calculate a new location. On the"},{"type":"text","text":" "},{"type":"text","text":"main app we have a global state, that we now call "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]},{"type":"codeListing","syntax":null,"code":["struct MyGlobalState {"," let title: String?"," let listOfItems: [Item]"," let currentLocation: Location","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"As expected, "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":") is a property of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":"). This relationship could be less"},{"type":"text","text":" "},{"type":"text","text":"direct, for example there could be several levels of properties until you find the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" in the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", like"},{"type":"text","text":" "},{"type":"codeVoice","code":"global.firstLevel.secondLevel.currentLocation"},{"type":"text","text":", but let’s keep it a single-level for this example."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Because our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":") and our "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":"), we"},{"type":"text","text":" "},{"type":"text","text":"must "},{"type":"codeVoice","code":"lift"},{"type":"text","text":" the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" to the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" level, by using:"}]},{"type":"codeListing","syntax":null,"code":["let globalStateReducer = gpsReducer.lift("," actionGetter: { $0 },"," stateGetter: { global in global.currentLocation },"," stateSetter: { global, part in global.currentLocation = path }",")","\/\/ where:","\/\/ globalStateReducer: Reducer","\/\/ ↑ lift","\/\/ gpsReducer: Reducer"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Now this reducer can be used within our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" or even composed with others. It also can be used in other apps as"},{"type":"text","text":" "},{"type":"text","text":"long as we have a way to lift it to the world of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Same strategy works for the "},{"type":"codeVoice","code":"action"},{"type":"text","text":", as you can guess by the "},{"type":"codeVoice","code":"actionGetter"},{"type":"text","text":" parameter. You can provide a function"},{"type":"text","text":" "},{"type":"text","text":"that takes a global action ("},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":") and returns an optional local action ("},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":"). It’s optional because perhaps"},{"type":"text","text":" "},{"type":"text","text":"you want to ignore actions that are not relevant for this reducer."}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducer\/lift(actiongetter:stategetter:statesetter:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(actionGetter:stateGetter:stateSetter:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"A type-lifting method. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":", that is a"},{"type":"text","text":" "},{"type":"text","text":"sub-state."}],"kind":"symbol","metadata":{"role":"symbol","title":"lift(actionGetter:stateGetter:stateSetter:)","roleHeading":"Instance Method","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalActionType"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalStateType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"actionGetter"},{"kind":"text","text":": ("},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":"?, "},{"kind":"externalParam","text":"stateGetter"},{"kind":"text","text":": ("},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":", "},{"kind":"externalParam","text":"stateSetter"},{"kind":"text","text":": ("},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":">"}],"symbolKind":"method","externalID":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF","extendedModule":"Reducer","modules":[{"name":"Reducer"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer","doc:\/\/Reducer\/documentation\/Reducer\/Reducer"]]},"references":{"doc://Reducer/documentation/Reducer/Reducer/lift(actionGetter:stateGetter:stateSetter:)":{"role":"symbol","title":"lift(actionGetter:stateGetter:stateSetter:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalActionType"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalStateType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"actionGetter"},{"kind":"text","text":": ("},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":"?, "},{"kind":"externalParam","text":"stateGetter"},{"kind":"text","text":": ("},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":", "},{"kind":"externalParam","text":"stateSetter"},{"kind":"text","text":": ("},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalActionType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF16GlobalActionTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift12actionGetter05stateD00E6SetterAByqd__qd_0_GxSgqd__c_q_qd_0_cyqd_0_z_q_tctr0_lF15GlobalStateTypeL_qd_0_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":", that is a"},{"type":"text","text":" "},{"type":"text","text":"sub-state."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(actionGetter:stateGetter:stateSetter:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lift(actiongetter:stategetter:statesetter:)"},"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lift(state:).json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lift(state:).json
deleted file mode 100644
index 4b8644a..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lift(state:).json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalStateType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"state"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift5stateAByxqd__Gs15WritableKeyPathCyqd__q_G_tlF15GlobalStateTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift5stateAByxqd__Gs15WritableKeyPathCyqd__q_G_tlF15GlobalStateTypeL_qd__mfp"},{"kind":"text","text":">"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"content","content":[{"anchor":"return-value","level":2,"type":"heading","text":"Return Value"},{"type":"paragraph","inlineContent":[{"type":"text","text":"a "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" that maps actions and states from the original specialized"},{"type":"text","text":" "},{"type":"text","text":"reducer into a more generic and global reducer, to be used in a larger context."}]}]},{"kind":"parameters","parameters":[{"name":"state","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a writable key-path from global state that traverses into a local state, by extracting only the part"},{"type":"text","text":" "},{"type":"text","text":"that it’s relevant for this reducer. This will also be used to set the new local state into the global"},{"type":"text","text":" "},{"type":"text","text":"state once the reducer finishes it’s operation. For example: "},{"type":"codeVoice","code":"\\.currentGame.scoreBoard"},{"type":"text","text":"."}]}]}]},{"kind":"content","content":[{"anchor":"discussion","level":2,"type":"heading","text":"Discussion"},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s suppose you may want to have a "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" that knows about the following "},{"type":"codeVoice","code":"struct"},{"type":"text","text":":"}]},{"type":"codeListing","syntax":null,"code":["struct Location {"," let latitude: Double"," let longitude: Double","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s call it "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":". Both, this state and its reducer will be part of an external framework, used by dozens of"},{"type":"text","text":" "},{"type":"text","text":"apps. Internally probably the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" will receive some known "},{"type":"codeVoice","code":"ActionType"},{"type":"text","text":" and calculate a new location. On the"},{"type":"text","text":" "},{"type":"text","text":"main app we have a global state, that we now call "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]},{"type":"codeListing","syntax":null,"code":["struct MyGlobalState {"," let title: String?"," let listOfItems: [Item]"," let currentLocation: Location","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"As expected, "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":") is a property of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":"). This relationship could be less"},{"type":"text","text":" "},{"type":"text","text":"direct, for example there could be several levels of properties until you find the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" in the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", like"},{"type":"text","text":" "},{"type":"codeVoice","code":"global.firstLevel.secondLevel.currentLocation"},{"type":"text","text":", but let’s keep it a single-level for this example."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Because our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":") and our "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":"), we"},{"type":"text","text":" "},{"type":"text","text":"must "},{"type":"codeVoice","code":"lift"},{"type":"text","text":" the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" to the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" level, by using:"}]},{"type":"codeListing","syntax":null,"code":["let globalStateReducer = gpsReducer.lift("," action: \\.self,"," state: \\.currentLocation",")","\/\/ where:","\/\/ globalStateReducer: Reducer","\/\/ ↑ lift","\/\/ gpsReducer: Reducer"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Now this reducer can be used within our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" or even composed with others. It also can be used in other apps as"},{"type":"text","text":" "},{"type":"text","text":"long as we have a way to lift it to the world of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Same strategy works for the "},{"type":"codeVoice","code":"action"},{"type":"text","text":", as you can guess by the "},{"type":"codeVoice","code":"action"},{"type":"text","text":" KeyPath parameter. You can provide a KeyPath"},{"type":"text","text":" "},{"type":"text","text":"that takes a global action ("},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":") and returns an optional local action ("},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":"). It’s optional because perhaps"},{"type":"text","text":" "},{"type":"text","text":"you want to ignore actions that are not relevant for this reducer."}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducer\/lift(state:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(state:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"A type-lifting method. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":", that is a"},{"type":"text","text":" "},{"type":"text","text":"sub-state."}],"kind":"symbol","metadata":{"role":"symbol","title":"lift(state:)","roleHeading":"Instance Method","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalStateType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"state"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift5stateAByxqd__Gs15WritableKeyPathCyqd__q_G_tlF15GlobalStateTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift5stateAByxqd__Gs15WritableKeyPathCyqd__q_G_tlF15GlobalStateTypeL_qd__mfp"},{"kind":"text","text":">"}],"symbolKind":"method","externalID":"s:7ReducerAAV4lift5stateAByxqd__Gs15WritableKeyPathCyqd__q_G_tlF","extendedModule":"Reducer","modules":[{"name":"Reducer"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer","doc:\/\/Reducer\/documentation\/Reducer\/Reducer"]]},"references":{"doc://Reducer/documentation/Reducer/Reducer/lift(state:)":{"role":"symbol","title":"lift(state:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"lift"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalStateType"},{"kind":"text","text":">("},{"kind":"externalParam","text":"state"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift5stateAByxqd__Gs15WritableKeyPathCyqd__q_G_tlF15GlobalStateTypeL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalStateType","preciseIdentifier":"s:7ReducerAAV4lift5stateAByxqd__Gs15WritableKeyPathCyqd__q_G_tlF15GlobalStateTypeL_qd__mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":", that is a"},{"type":"text","text":" "},{"type":"text","text":"sub-state."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/lift(state:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lift(state:)"},"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lifttocollection(action:statecollection:)-4gphe.json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lifttocollection(action:statecollection:)-4gphe.json
deleted file mode 100644
index 5877243..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lifttocollection(action:statecollection:)-4gphe.json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"liftToCollection"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalAction"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"CollectionState"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":" "},{"kind":"internalParam","text":"actionMap"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", (index"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF0D5StateL_qd_1_mfp"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Index","preciseIdentifier":"s:Sl5IndexQa"},{"kind":"text","text":", action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":")?>, "},{"kind":"externalParam","text":"stateCollection"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF0D5StateL_qd_1_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":"> "},{"kind":"keyword","text":"where"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"StateType"},{"kind":"text","text":" == "},{"kind":"typeIdentifier","text":"CollectionState"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Element"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"MutableCollection","preciseIdentifier":"s:SM"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"content","content":[{"anchor":"return-value","level":2,"type":"heading","text":"Return Value"},{"type":"paragraph","inlineContent":[{"type":"text","text":"a "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" that maps actions and states from the original local reducer, which"},{"type":"text","text":" "},{"type":"text","text":"is specialised in a single Element, into a more generic and global reducer, to be used in a larger context."}]}]},{"kind":"parameters","parameters":[{"name":"actionMap","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a read-only key-path from global action into a tuple: (index, local action), but it’s optional because"},{"type":"text","text":" "},{"type":"text","text":"maybe this reducer shouldn’t care about certain actions."}]}]},{"name":"stateCollection","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a writable key-path from global state that traverses into a local state, by extracting only"},{"type":"text","text":" "},{"type":"text","text":"the part that it’s relevant for this reducer. This part needs to be a "},{"type":"codeVoice","code":"MutableCollection"},{"type":"text","text":"."}]}]}]},{"kind":"content","content":[{"anchor":"discussion","level":2,"type":"heading","text":"Discussion"},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s suppose you may want to have a "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" that knows about the following "},{"type":"codeVoice","code":"struct"},{"type":"text","text":":"}]},{"type":"codeListing","syntax":null,"code":["struct Location {"," let latitude: Double"," let longitude: Double","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s call it "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":". Both, this state and its reducer will be part of an external framework, used by dozens of"},{"type":"text","text":" "},{"type":"text","text":"apps. Internally probably the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" will receive some known "},{"type":"codeVoice","code":"ActionType"},{"type":"text","text":" and calculate a new location. On the"},{"type":"text","text":" "},{"type":"text","text":"main app we have a global state, that we now call "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]},{"type":"codeListing","syntax":null,"code":["struct MyGlobalState {"," let title: String?"," let knownLocations: [Location]","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"As expected, "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":") is an element of the array "},{"type":"codeVoice","code":"knownLocations"},{"type":"text","text":", which is property of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" "},{"type":"text","text":"("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":"). This relationship could be less direct, for example there could be several levels of properties"},{"type":"text","text":" "},{"type":"text","text":"until you find the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" in the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", like "},{"type":"codeVoice","code":"global.firstLevel.secondLevel.knownLocations"},{"type":"text","text":", but let’s keep it a"},{"type":"text","text":" "},{"type":"text","text":"single-level for this example."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"To resolve this single element, we not only have to find the path to the array, but we have to find the element"},{"type":"text","text":" "},{"type":"text","text":"inside of the array. There are three methods for doing so:"}]},{"type":"orderedList","items":[{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"the element is "},{"type":"codeVoice","code":"Identifiable"},{"type":"text","text":" (iOS 13 or later)"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"the element has a "},{"type":"codeVoice","code":"Hashable"},{"type":"text","text":" property that makes it unique, so we can find it in the array using this identifier"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"using the index of the element in the array"}]}]}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Because our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":") and our "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":"), we"},{"type":"text","text":" "},{"type":"text","text":"must "},{"type":"codeVoice","code":"liftToCollection"},{"type":"text","text":" the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" to the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" level, by using:"}]},{"type":"codeListing","syntax":null,"code":["let globalStateReducer = gpsReducer.liftToCollection("," actionMap: \\.actionKeyPathToATuple,"," state: \\.knownLocations",")","\/\/ where:","\/\/ globalStateReducer: Reducer","\/\/ ↑ lift","\/\/ gpsReducer: Reducer"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Different from simple "},{"type":"codeVoice","code":"lift"},{"type":"text","text":" to scalar, this one requires necessarily that you lift the action together with the state."},{"type":"text","text":" "},{"type":"text","text":"That’s because your action has to contain the ID or Index of the element we will modify. The "},{"type":"codeVoice","code":"actionMap"},{"type":"text","text":" KeyPath has to"},{"type":"text","text":" "},{"type":"text","text":"give us a tuple of either:"}]},{"type":"unorderedList","items":[{"content":[{"type":"paragraph","inlineContent":[{"type":"codeVoice","code":"(id, actionToSingleElement)"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"codeVoice","code":"(index, actionToSingleElement)"}]}]}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"The id or index is gonna be how we will search the array for the desired element, and only if we find it, we will run"},{"type":"text","text":" "},{"type":"text","text":"the "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" for that specific element, using the action that has to do with single elements only."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"As "},{"type":"codeVoice","code":"Location"},{"type":"text","text":" doesn’t have an "},{"type":"codeVoice","code":"id"},{"type":"text","text":" property we will have to either use index, implement "},{"type":"codeVoice","code":"Identifiable"},{"type":"text","text":" protocol or"},{"type":"text","text":" "},{"type":"text","text":"give another unique and "},{"type":"codeVoice","code":"Hashable"},{"type":"text","text":" property."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Now this reducer can be used within our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" or even composed with others. It also can be used in other apps as"},{"type":"text","text":" "},{"type":"text","text":"long as we have a way to lift it to the world of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducer\/lifttocollection(action:statecollection:)-4gphe"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/liftToCollection(action:stateCollection:)-4gphe","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"A type-lifting method for collections. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles an element"},{"type":"text","text":" "},{"type":"text","text":"that is inside of a collection, which itself is sub-state of the global. Let’s call this single element "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":"."}],"kind":"symbol","metadata":{"role":"symbol","title":"liftToCollection(action:stateCollection:)","roleHeading":"Instance Method","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"liftToCollection"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalAction"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"CollectionState"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", (index"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF0D5StateL_qd_1_mfp"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Index","preciseIdentifier":"s:Sl5IndexQa"},{"kind":"text","text":", action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":")?>, "},{"kind":"externalParam","text":"stateCollection"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF0D5StateL_qd_1_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":">"}],"symbolKind":"method","externalID":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF","extendedModule":"Reducer","modules":[{"name":"Reducer"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer","doc:\/\/Reducer\/documentation\/Reducer\/Reducer"]]},"references":{"doc://Reducer/documentation/Reducer/Reducer/liftToCollection(action:stateCollection:)-4gphe":{"role":"symbol","title":"liftToCollection(action:stateCollection:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"liftToCollection"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalAction"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"CollectionState"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", (index"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF0D5StateL_qd_1_mfp"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Index","preciseIdentifier":"s:Sl5IndexQa"},{"kind":"text","text":", action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":")?>, "},{"kind":"externalParam","text":"stateCollection"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF0D5StateL_qd_1_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD0AByqd__qd_0_Gs7KeyPathCyqd__5IndexQyd_1_5index_xADtSgG_s08WritablegH0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method for collections. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles an element"},{"type":"text","text":" "},{"type":"text","text":"that is inside of a collection, which itself is sub-state of the global. Let’s call this single element "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/liftToCollection(action:stateCollection:)-4gphe","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lifttocollection(action:statecollection:)-4gphe"},"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lifttocollection(action:statecollection:)-5a160.json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lifttocollection(action:statecollection:)-5a160.json
deleted file mode 100644
index d7d9cc5..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lifttocollection(action:statecollection:)-5a160.json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"liftToCollection"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalAction"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"CollectionState"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":" "},{"kind":"internalParam","text":"actionMap"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", (id"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE9StateTypeq_mfp"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"ID","preciseIdentifier":"s:s12IdentifiableP2IDQa"},{"kind":"text","text":", action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE10ActionTypexmfp"},{"kind":"text","text":")?>, "},{"kind":"externalParam","text":"stateCollection"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF0E5StateL_qd_1_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":"> "},{"kind":"keyword","text":"where"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"StateType"},{"kind":"text","text":" == "},{"kind":"typeIdentifier","text":"CollectionState"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Element"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"MutableCollection","preciseIdentifier":"s:SM"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"content","content":[{"anchor":"return-value","level":2,"type":"heading","text":"Return Value"},{"type":"paragraph","inlineContent":[{"type":"text","text":"a "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" that maps actions and states from the original local reducer, which"},{"type":"text","text":" "},{"type":"text","text":"is specialised in a single Element, into a more generic and global reducer, to be used in a larger context."}]}]},{"kind":"parameters","parameters":[{"name":"actionMap","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a read-only key-path from global action into a tuple: (id, local action), but it’s optional because"},{"type":"text","text":" "},{"type":"text","text":"maybe this reducer shouldn’t care about certain actions."}]}]},{"name":"stateCollection","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a writable key-path from global state that traverses into a local state, by extracting only"},{"type":"text","text":" "},{"type":"text","text":"the part that it’s relevant for this reducer. This part needs to be a "},{"type":"codeVoice","code":"MutableCollection"},{"type":"text","text":"."}]}]}]},{"kind":"content","content":[{"anchor":"discussion","level":2,"type":"heading","text":"Discussion"},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s suppose you may want to have a "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" that knows about the following "},{"type":"codeVoice","code":"struct"},{"type":"text","text":":"}]},{"type":"codeListing","syntax":null,"code":["struct Location {"," let latitude: Double"," let longitude: Double","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s call it "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":". Both, this state and its reducer will be part of an external framework, used by dozens of"},{"type":"text","text":" "},{"type":"text","text":"apps. Internally probably the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" will receive some known "},{"type":"codeVoice","code":"ActionType"},{"type":"text","text":" and calculate a new location. On the"},{"type":"text","text":" "},{"type":"text","text":"main app we have a global state, that we now call "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]},{"type":"codeListing","syntax":null,"code":["struct MyGlobalState {"," let title: String?"," let knownLocations: [Location]","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"As expected, "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":") is an element of the array "},{"type":"codeVoice","code":"knownLocations"},{"type":"text","text":", which is property of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" "},{"type":"text","text":"("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":"). This relationship could be less direct, for example there could be several levels of properties"},{"type":"text","text":" "},{"type":"text","text":"until you find the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" in the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", like "},{"type":"codeVoice","code":"global.firstLevel.secondLevel.knownLocations"},{"type":"text","text":", but let’s keep it a"},{"type":"text","text":" "},{"type":"text","text":"single-level for this example."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"To resolve this single element, we not only have to find the path to the array, but we have to find the element"},{"type":"text","text":" "},{"type":"text","text":"inside of the array. There are three methods for doing so:"}]},{"type":"orderedList","items":[{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"the element is "},{"type":"codeVoice","code":"Identifiable"},{"type":"text","text":" (iOS 13 or later)"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"the element has a "},{"type":"codeVoice","code":"Hashable"},{"type":"text","text":" property that makes it unique, so we can find it in the array using this identifier"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"using the index of the element in the array"}]}]}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Because our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":") and our "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":"), we"},{"type":"text","text":" "},{"type":"text","text":"must "},{"type":"codeVoice","code":"liftToCollection"},{"type":"text","text":" the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" to the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" level, by using:"}]},{"type":"codeListing","syntax":null,"code":["let globalStateReducer = gpsReducer.liftToCollection("," actionMap: \\.actionKeyPathToATuple,"," state: \\.knownLocations",")","\/\/ where:","\/\/ globalStateReducer: Reducer","\/\/ ↑ lift","\/\/ gpsReducer: Reducer"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Different from simple "},{"type":"codeVoice","code":"lift"},{"type":"text","text":" to scalar, this one requires necessarily that you lift the action together with the state."},{"type":"text","text":" "},{"type":"text","text":"That’s because your action has to contain the ID or Index of the element we will modify. The "},{"type":"codeVoice","code":"actionMap"},{"type":"text","text":" KeyPath has to"},{"type":"text","text":" "},{"type":"text","text":"give us a tuple of either:"}]},{"type":"unorderedList","items":[{"content":[{"type":"paragraph","inlineContent":[{"type":"codeVoice","code":"(id, actionToSingleElement)"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"codeVoice","code":"(index, actionToSingleElement)"}]}]}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"The id or index is gonna be how we will search the array for the desired element, and only if we find it, we will run"},{"type":"text","text":" "},{"type":"text","text":"the "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" for that specific element, using the action that has to do with single elements only."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"As "},{"type":"codeVoice","code":"Location"},{"type":"text","text":" doesn’t have an "},{"type":"codeVoice","code":"id"},{"type":"text","text":" property we will have to either use index, implement "},{"type":"codeVoice","code":"Identifiable"},{"type":"text","text":" protocol or"},{"type":"text","text":" "},{"type":"text","text":"give another unique and "},{"type":"codeVoice","code":"Hashable"},{"type":"text","text":" property."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Now this reducer can be used within our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" or even composed with others. It also can be used in other apps as"},{"type":"text","text":" "},{"type":"text","text":"long as we have a way to lift it to the world of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducer\/lifttocollection(action:statecollection:)-5a160"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/liftToCollection(action:stateCollection:)-5a160","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"A type-lifting method for collections. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles an element"},{"type":"text","text":" "},{"type":"text","text":"that is inside of a collection, which itself is sub-state of the global. Let’s call this single element "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":"."}],"kind":"symbol","metadata":{"modules":[{"name":"Reducer"}],"conformance":{"constraints":[{"type":"codeVoice","code":"StateType"},{"type":"text","text":" conforms to "},{"type":"codeVoice","code":"Identifiable"},{"type":"text","text":"."}],"availabilityPrefix":[{"type":"text","text":"Available when"}],"conformancePrefix":[{"type":"text","text":"Conforms when"}]},"role":"symbol","title":"liftToCollection(action:stateCollection:)","roleHeading":"Instance Method","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"liftToCollection"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalAction"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"CollectionState"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", (id"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE9StateTypeq_mfp"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"ID","preciseIdentifier":"s:s12IdentifiableP2IDQa"},{"kind":"text","text":", action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE10ActionTypexmfp"},{"kind":"text","text":")?>, "},{"kind":"externalParam","text":"stateCollection"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF0E5StateL_qd_1_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":">"}],"symbolKind":"method","externalID":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF","extendedModule":"Reducer","platforms":[{"beta":false,"unavailable":false,"name":"iOS","introducedAt":"13.0","deprecated":false},{"beta":false,"unavailable":false,"name":"macOS","introducedAt":"10.15","deprecated":false},{"beta":false,"unavailable":false,"name":"tvOS","introducedAt":"13.0","deprecated":false},{"beta":false,"unavailable":false,"name":"watchOS","introducedAt":"6.0","deprecated":false}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer","doc:\/\/Reducer\/documentation\/Reducer\/Reducer"]]},"references":{"doc://Reducer/documentation/Reducer/Reducer/liftToCollection(action:stateCollection:)-5a160":{"conformance":{"constraints":[{"type":"codeVoice","code":"StateType"},{"type":"text","text":" conforms to "},{"type":"codeVoice","code":"Identifiable"},{"type":"text","text":"."}],"availabilityPrefix":[{"type":"text","text":"Available when"}],"conformancePrefix":[{"type":"text","text":"Conforms when"}]},"role":"symbol","title":"liftToCollection(action:stateCollection:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"liftToCollection"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalAction"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"CollectionState"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", (id"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE9StateTypeq_mfp"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"ID","preciseIdentifier":"s:s12IdentifiableP2IDQa"},{"kind":"text","text":", action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE10ActionTypexmfp"},{"kind":"text","text":")?>, "},{"kind":"externalParam","text":"stateCollection"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF0E5StateL_qd_1_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAVAAs12IdentifiableR_rlE16liftToCollection6action05stateE0AByqd__qd_0_Gs7KeyPathCyqd__2IDQy_2id_xAEtSgG_s08WritablehI0Cyqd_0_qd_1_Gt7ElementQyd_1_Rs_SMRd_1_r1_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method for collections. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles an element"},{"type":"text","text":" "},{"type":"text","text":"that is inside of a collection, which itself is sub-state of the global. Let’s call this single element "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/liftToCollection(action:stateCollection:)-5a160","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lifttocollection(action:statecollection:)-5a160"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"},"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lifttocollection(action:statecollection:identifier:).json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lifttocollection(action:statecollection:identifier:).json
deleted file mode 100644
index ecb391e..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/lifttocollection(action:statecollection:identifier:).json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"liftToCollection"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalAction"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"CollectionState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"ID"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":" "},{"kind":"internalParam","text":"actionMap"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", (id"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ID","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF2IDL_qd_2_mfp"},{"kind":"text","text":", action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":")?>, "},{"kind":"externalParam","text":"stateCollection"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF0D5StateL_qd_1_mfp"},{"kind":"text","text":">, "},{"kind":"externalParam","text":"identifier"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"ID","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF2IDL_qd_2_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":"> "},{"kind":"keyword","text":"where"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"StateType"},{"kind":"text","text":" == "},{"kind":"typeIdentifier","text":"CollectionState"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Element"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"MutableCollection","preciseIdentifier":"s:SM"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"ID"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"Hashable","preciseIdentifier":"s:SH"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"content","content":[{"anchor":"return-value","level":2,"type":"heading","text":"Return Value"},{"type":"paragraph","inlineContent":[{"type":"text","text":"a "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" that maps actions and states from the original local reducer, which"},{"type":"text","text":" "},{"type":"text","text":"is specialised in a single Element, into a more generic and global reducer, to be used in a larger context."}]}]},{"kind":"parameters","parameters":[{"name":"actionMap","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a read-only key-path from global action into a tuple: (id, local action), but it’s optional because"},{"type":"text","text":" "},{"type":"text","text":"maybe this reducer shouldn’t care about certain actions."}]}]},{"name":"stateCollection","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a writable key-path from global state that traverses into a local state, by extracting only"},{"type":"text","text":" "},{"type":"text","text":"the part that it’s relevant for this reducer. This part needs to be a "},{"type":"codeVoice","code":"MutableCollection"},{"type":"text","text":"."}]}]},{"name":"identifier","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a key-path to define who is the unique-identifier of the Element (it has to be "},{"type":"codeVoice","code":"Hashable"},{"type":"text","text":")"}]}]}]},{"kind":"content","content":[{"anchor":"discussion","level":2,"type":"heading","text":"Discussion"},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s suppose you may want to have a "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" that knows about the following "},{"type":"codeVoice","code":"struct"},{"type":"text","text":":"}]},{"type":"codeListing","syntax":null,"code":["struct Location {"," let latitude: Double"," let longitude: Double","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Let’s call it "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":". Both, this state and its reducer will be part of an external framework, used by dozens of"},{"type":"text","text":" "},{"type":"text","text":"apps. Internally probably the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" will receive some known "},{"type":"codeVoice","code":"ActionType"},{"type":"text","text":" and calculate a new location. On the"},{"type":"text","text":" "},{"type":"text","text":"main app we have a global state, that we now call "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]},{"type":"codeListing","syntax":null,"code":["struct MyGlobalState {"," let title: String?"," let knownLocations: [Location]","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"As expected, "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":") is an element of the array "},{"type":"codeVoice","code":"knownLocations"},{"type":"text","text":", which is property of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" "},{"type":"text","text":"("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":"). This relationship could be less direct, for example there could be several levels of properties"},{"type":"text","text":" "},{"type":"text","text":"until you find the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" in the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", like "},{"type":"codeVoice","code":"global.firstLevel.secondLevel.knownLocations"},{"type":"text","text":", but let’s keep it a"},{"type":"text","text":" "},{"type":"text","text":"single-level for this example."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"To resolve this single element, we not only have to find the path to the array, but we have to find the element"},{"type":"text","text":" "},{"type":"text","text":"inside of the array. There are three methods for doing so:"}]},{"type":"orderedList","items":[{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"the element is "},{"type":"codeVoice","code":"Identifiable"},{"type":"text","text":" (iOS 13 or later)"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"the element has a "},{"type":"codeVoice","code":"Hashable"},{"type":"text","text":" property that makes it unique, so we can find it in the array using this identifier"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"using the index of the element in the array"}]}]}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Because our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"MyGlobalState"},{"type":"text","text":") and our "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" understands "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":" ("},{"type":"codeVoice","code":"Location"},{"type":"text","text":"), we"},{"type":"text","text":" "},{"type":"text","text":"must "},{"type":"codeVoice","code":"liftToCollection"},{"type":"text","text":" the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" to the "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":" level, by using:"}]},{"type":"codeListing","syntax":null,"code":["let globalStateReducer = gpsReducer.liftToCollection("," actionMap: \\.actionKeyPathToATuple,"," state: \\.knownLocations",")","\/\/ where:","\/\/ globalStateReducer: Reducer","\/\/ ↑ lift","\/\/ gpsReducer: Reducer"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Different from simple "},{"type":"codeVoice","code":"lift"},{"type":"text","text":" to scalar, this one requires necessarily that you lift the action together with the state."},{"type":"text","text":" "},{"type":"text","text":"That’s because your action has to contain the ID or Index of the element we will modify. The "},{"type":"codeVoice","code":"actionMap"},{"type":"text","text":" KeyPath has to"},{"type":"text","text":" "},{"type":"text","text":"give us a tuple of either:"}]},{"type":"unorderedList","items":[{"content":[{"type":"paragraph","inlineContent":[{"type":"codeVoice","code":"(id, actionToSingleElement)"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"codeVoice","code":"(index, actionToSingleElement)"}]}]}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"The id or index is gonna be how we will search the array for the desired element, and only if we find it, we will run"},{"type":"text","text":" "},{"type":"text","text":"the "},{"type":"codeVoice","code":"gpsReducer"},{"type":"text","text":" for that specific element, using the action that has to do with single elements only."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"As "},{"type":"codeVoice","code":"Location"},{"type":"text","text":" doesn’t have an "},{"type":"codeVoice","code":"id"},{"type":"text","text":" property we will have to either use index, implement "},{"type":"codeVoice","code":"Identifiable"},{"type":"text","text":" protocol or"},{"type":"text","text":" "},{"type":"text","text":"give another unique and "},{"type":"codeVoice","code":"Hashable"},{"type":"text","text":" property."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"Now this reducer can be used within our "},{"type":"codeVoice","code":"Store"},{"type":"text","text":" or even composed with others. It also can be used in other apps as"},{"type":"text","text":" "},{"type":"text","text":"long as we have a way to lift it to the world of "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":"."}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducer\/lifttocollection(action:statecollection:identifier:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/liftToCollection(action:stateCollection:identifier:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"A type-lifting method for collections. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles an element"},{"type":"text","text":" "},{"type":"text","text":"that is inside of a collection, which itself is sub-state of the global. Let’s call this single element "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":"."}],"kind":"symbol","metadata":{"role":"symbol","title":"liftToCollection(action:stateCollection:identifier:)","roleHeading":"Instance Method","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"liftToCollection"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalAction"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"CollectionState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"ID"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", (id"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ID","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF2IDL_qd_2_mfp"},{"kind":"text","text":", action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":")?>, "},{"kind":"externalParam","text":"stateCollection"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF0D5StateL_qd_1_mfp"},{"kind":"text","text":">, "},{"kind":"externalParam","text":"identifier"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"ID","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF2IDL_qd_2_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":">"}],"symbolKind":"method","externalID":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF","extendedModule":"Reducer","modules":[{"name":"Reducer"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer","doc:\/\/Reducer\/documentation\/Reducer\/Reducer"]]},"references":{"doc://Reducer/documentation/Reducer/Reducer/liftToCollection(action:stateCollection:identifier:)":{"role":"symbol","title":"liftToCollection(action:stateCollection:identifier:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"liftToCollection"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"GlobalAction"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"GlobalState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"CollectionState"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"ID"},{"kind":"text","text":">("},{"kind":"externalParam","text":"action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", (id"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ID","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF2IDL_qd_2_mfp"},{"kind":"text","text":", action"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":")?>, "},{"kind":"externalParam","text":"stateCollection"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"WritableKeyPath","preciseIdentifier":"s:s15WritableKeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"CollectionState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF0D5StateL_qd_1_mfp"},{"kind":"text","text":">, "},{"kind":"externalParam","text":"identifier"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"ID","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF2IDL_qd_2_mfp"},{"kind":"text","text":">) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"GlobalAction","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF12GlobalActionL_qd__mfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"GlobalState","preciseIdentifier":"s:7ReducerAAV16liftToCollection6action05stateD010identifierAByqd__qd_0_Gs7KeyPathCyqd__qd_2_2id_xADtSgG_s08WritablehI0Cyqd_0_qd_1_GAIyq_qd_2_Gt7ElementQyd_1_Rs_SMRd_1_SHRd_2_r2_lF11GlobalStateL_qd_0_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"A type-lifting method for collections. The global state of your app is "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Whole"}]},{"type":"text","text":", and the "},{"type":"codeVoice","code":"Reducer"},{"type":"text","text":" handles an element"},{"type":"text","text":" "},{"type":"text","text":"that is inside of a collection, which itself is sub-state of the global. Let’s call this single element "},{"type":"emphasis","inlineContent":[{"type":"text","text":"Part"}]},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/liftToCollection(action:stateCollection:identifier:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/lifttocollection(action:statecollection:identifier:)"},"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/reduce(_:).json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/reduce(_:).json
deleted file mode 100644
index dc758fb..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/reduce(_:).json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"reduce"},{"kind":"text","text":"("},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"reduce"},{"kind":"text","text":": "},{"kind":"attribute","text":"@escaping"},{"kind":"text","text":" ("},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"parameters","parameters":[{"name":"reduce","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"a pure function that calculates the new state from an action and the current state."}]}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducer\/reduce(_:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/reduce(_:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Reducer initialiser takes only the underlying function "},{"type":"codeVoice","code":"(ActionType, inout StateType) -> Void"},{"type":"text","text":" that is the reducer"},{"type":"text","text":" "},{"type":"text","text":"function itself."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"reduce"},{"kind":"text","text":"(("},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"}],"title":"reduce(_:)","roleHeading":"Type Method","role":"symbol","symbolKind":"method","externalID":"s:7ReducerAAV6reduceyAByxq_Gyx_q_ztcFZ","modules":[{"name":"Reducer"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer","doc:\/\/Reducer\/documentation\/Reducer\/Reducer"]]},"references":{"doc://Reducer/documentation/Reducer/Reducer/reduce(_:)":{"role":"symbol","title":"reduce(_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"reduce"},{"kind":"text","text":"(("},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"}],"abstract":[{"type":"text","text":"Reducer initialiser takes only the underlying function "},{"type":"codeVoice","code":"(ActionType, inout StateType) -> Void"},{"type":"text","text":" that is the reducer"},{"type":"text","text":" "},{"type":"text","text":"function itself."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/reduce(_:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/reduce(_:)"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"},"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/reduce.json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/reduce.json
deleted file mode 100644
index c3009f3..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducer/reduce.json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"reduce"},{"kind":"text","text":": ("},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducer\/reduce"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/reduce","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Execute the wrapped reduce function. You must provide the parameters "},{"type":"codeVoice","code":"action: ActionType"},{"type":"text","text":" (the action to be"},{"type":"text","text":" "},{"type":"text","text":"evaluated during the reducing process) and an "},{"type":"codeVoice","code":"inout"},{"type":"text","text":" version of the latest "},{"type":"codeVoice","code":"state: StateType"},{"type":"text","text":", (the current"},{"type":"text","text":" "},{"type":"text","text":"state in your single source-of-truth)."},{"type":"text","text":" "},{"type":"text","text":"State will be mutated in place ("},{"type":"codeVoice","code":"inout"},{"type":"text","text":") and finish with the calculated new state."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"reduce"},{"kind":"text","text":": ("},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"}],"title":"reduce","roleHeading":"Instance Property","role":"symbol","symbolKind":"property","externalID":"s:7ReducerAAV6reduceyyx_q_ztcvp","modules":[{"name":"Reducer"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer","doc:\/\/Reducer\/documentation\/Reducer\/Reducer"]]},"references":{"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"},"doc://Reducer/documentation/Reducer/Reducer/reduce":{"role":"symbol","title":"reduce","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"reduce"},{"kind":"text","text":": ("},{"kind":"typeIdentifier","text":"ActionType","preciseIdentifier":"s:7ReducerAAV10ActionTypexmfp"},{"kind":"text","text":", "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"StateType","preciseIdentifier":"s:7ReducerAAV9StateTypeq_mfp"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"}],"abstract":[{"type":"text","text":"Execute the wrapped reduce function. You must provide the parameters "},{"type":"codeVoice","code":"action: ActionType"},{"type":"text","text":" (the action to be"},{"type":"text","text":" "},{"type":"text","text":"evaluated during the reducing process) and an "},{"type":"codeVoice","code":"inout"},{"type":"text","text":" version of the latest "},{"type":"codeVoice","code":"state: StateType"},{"type":"text","text":", (the current"},{"type":"text","text":" "},{"type":"text","text":"state in your single source-of-truth)."},{"type":"text","text":" "},{"type":"text","text":"State will be mutated in place ("},{"type":"codeVoice","code":"inout"},{"type":"text","text":") and finish with the calculated new state."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer\/reduce","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducer\/reduce"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducerbuilder.json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducerbuilder.json
deleted file mode 100644
index 43cda68..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducerbuilder.json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"attribute","text":"@resultBuilder"},{"kind":"text","text":" "},{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"ReducerBuilder"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducerbuilder"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/ReducerBuilder","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"DSL Builder for Reducer compose"}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"ReducerBuilder"}],"title":"ReducerBuilder","roleHeading":"Enumeration","role":"symbol","symbolKind":"enum","externalID":"s:7Reducer0A7BuilderO","modules":[{"name":"Reducer"}],"navigatorTitle":[{"kind":"identifier","text":"ReducerBuilder"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer"]]},"topicSections":[{"title":"Type Methods","identifiers":["doc:\/\/Reducer\/documentation\/Reducer\/ReducerBuilder\/buildBlock(_:)"]}],"references":{"doc://Reducer/documentation/Reducer/ReducerBuilder/buildBlock(_:)":{"role":"symbol","title":"buildBlock(_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"buildBlock"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"Action"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"State"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"Action","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ6ActionL_xmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"State","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ5StateL_q_mfp"},{"kind":"text","text":">...) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"Action","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ6ActionL_xmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"State","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ5StateL_q_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"DSL Builder for Reducer compose"}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/ReducerBuilder\/buildBlock(_:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducerbuilder\/buildblock(_:)"},"doc://Reducer/documentation/Reducer/ReducerBuilder":{"role":"symbol","title":"ReducerBuilder","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"ReducerBuilder"}],"abstract":[{"type":"text","text":"DSL Builder for Reducer compose"}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/ReducerBuilder","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ReducerBuilder"}],"url":"\/documentation\/reducer\/reducerbuilder"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducerbuilder/buildblock(_:).json b/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducerbuilder/buildblock(_:).json
deleted file mode 100644
index 3ef35b6..0000000
--- a/docs/docc/Reducer.doccarchive/data/documentation/reducer/reducerbuilder/buildblock(_:).json
+++ /dev/null
@@ -1 +0,0 @@
-{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"buildBlock"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"Action"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"State"},{"kind":"text","text":">("},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"reducers"},{"kind":"text","text":": "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"Action","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ6ActionL_xmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"State","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ5StateL_q_mfp"},{"kind":"text","text":">...) -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","preciseIdentifier":"s:7ReducerAAV","text":"Reducer"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"Action","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ6ActionL_xmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"State","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ5StateL_q_mfp"},{"kind":"text","text":">"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"content","content":[{"anchor":"return-value","level":2,"type":"heading","text":"Return Value"},{"type":"paragraph","inlineContent":[{"type":"text","text":"the composed reducer that will run all the inner reducers sequentially\/"}]}]},{"kind":"parameters","parameters":[{"name":"reducers","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"the reducers to be combined\/"}]}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/reducer\/reducerbuilder\/buildblock(_:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Reducer\/documentation\/Reducer\/ReducerBuilder\/buildBlock(_:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"DSL Builder for Reducer compose"}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"buildBlock"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"Action"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"State"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"Action","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ6ActionL_xmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"State","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ5StateL_q_mfp"},{"kind":"text","text":">...) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"Action","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ6ActionL_xmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"State","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ5StateL_q_mfp"},{"kind":"text","text":">"}],"title":"buildBlock(_:)","roleHeading":"Type Method","role":"symbol","symbolKind":"method","externalID":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ","modules":[{"name":"Reducer"}]},"hierarchy":{"paths":[["doc:\/\/Reducer\/documentation\/Reducer","doc:\/\/Reducer\/documentation\/Reducer\/ReducerBuilder"]]},"references":{"doc://Reducer/documentation/Reducer/ReducerBuilder":{"role":"symbol","title":"ReducerBuilder","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"ReducerBuilder"}],"abstract":[{"type":"text","text":"DSL Builder for Reducer compose"}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/ReducerBuilder","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ReducerBuilder"}],"url":"\/documentation\/reducer\/reducerbuilder"},"doc://Reducer/documentation/Reducer/Reducer":{"role":"symbol","title":"Reducer","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Reducer"}],"abstract":[{"type":"text","text":"An entity that calculates the new state when given current state and an incoming action "},{"type":"codeVoice","code":"(Action, inout State) -> Void"},{"type":"text","text":"."}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/Reducer","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Reducer"}],"url":"\/documentation\/reducer\/reducer"},"doc://Reducer/documentation/Reducer":{"role":"collection","title":"Reducer","abstract":[],"identifier":"doc:\/\/Reducer\/documentation\/Reducer","kind":"symbol","type":"topic","url":"\/documentation\/reducer"},"doc://Reducer/documentation/Reducer/ReducerBuilder/buildBlock(_:)":{"role":"symbol","title":"buildBlock(_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"buildBlock"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"Action"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"State"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"Action","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ6ActionL_xmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"State","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ5StateL_q_mfp"},{"kind":"text","text":">...) -> "},{"kind":"typeIdentifier","text":"Reducer","preciseIdentifier":"s:7ReducerAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"Action","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ6ActionL_xmfp"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"State","preciseIdentifier":"s:7Reducer0A7BuilderO10buildBlockyA2AVyxq_GAFd_tr0_lFZ5StateL_q_mfp"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"DSL Builder for Reducer compose"}],"identifier":"doc:\/\/Reducer\/documentation\/Reducer\/ReducerBuilder\/buildBlock(_:)","kind":"symbol","type":"topic","url":"\/documentation\/reducer\/reducerbuilder\/buildblock(_:)"}}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/developer-og-twitter.jpg b/docs/docc/Reducer.doccarchive/developer-og-twitter.jpg
deleted file mode 100644
index 63c4835..0000000
Binary files a/docs/docc/Reducer.doccarchive/developer-og-twitter.jpg and /dev/null differ
diff --git a/docs/docc/Reducer.doccarchive/developer-og.jpg b/docs/docc/Reducer.doccarchive/developer-og.jpg
deleted file mode 100644
index 4db8408..0000000
Binary files a/docs/docc/Reducer.doccarchive/developer-og.jpg and /dev/null differ
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/compose(_:_:)/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/compose(_:_:)/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/compose(_:_:)/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/compose(content:)/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/compose(content:)/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/compose(content:)/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/identity/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/identity/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/identity/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lift(action:)/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lift(action:)/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lift(action:)/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lift(action:state:)/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lift(action:state:)/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lift(action:state:)/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lift(actiongetter:stategetter:statesetter:)/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lift(actiongetter:stategetter:statesetter:)/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lift(actiongetter:stategetter:statesetter:)/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lift(state:)/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lift(state:)/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lift(state:)/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lifttocollection(action:statecollection:)-4gphe/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lifttocollection(action:statecollection:)-4gphe/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lifttocollection(action:statecollection:)-4gphe/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lifttocollection(action:statecollection:)-5a160/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lifttocollection(action:statecollection:)-5a160/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lifttocollection(action:statecollection:)-5a160/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lifttocollection(action:statecollection:identifier:)/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lifttocollection(action:statecollection:identifier:)/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/lifttocollection(action:statecollection:identifier:)/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/reduce(_:)/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/reduce(_:)/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/reduce(_:)/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/reduce/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/reduce/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducer/reduce/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducerbuilder/buildblock(_:)/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducerbuilder/buildblock(_:)/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducerbuilder/buildblock(_:)/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/documentation/reducer/reducerbuilder/index.html b/docs/docc/Reducer.doccarchive/documentation/reducer/reducerbuilder/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/documentation/reducer/reducerbuilder/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/favicon.ico b/docs/docc/Reducer.doccarchive/favicon.ico
deleted file mode 100644
index 5231da6..0000000
Binary files a/docs/docc/Reducer.doccarchive/favicon.ico and /dev/null differ
diff --git a/docs/docc/Reducer.doccarchive/favicon.svg b/docs/docc/Reducer.doccarchive/favicon.svg
deleted file mode 100644
index c54c53f..0000000
--- a/docs/docc/Reducer.doccarchive/favicon.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/img/added-icon.d6f7e47d.svg b/docs/docc/Reducer.doccarchive/img/added-icon.d6f7e47d.svg
deleted file mode 100644
index 6bb6d89..0000000
--- a/docs/docc/Reducer.doccarchive/img/added-icon.d6f7e47d.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/img/deprecated-icon.015b4f17.svg b/docs/docc/Reducer.doccarchive/img/deprecated-icon.015b4f17.svg
deleted file mode 100644
index a0f8008..0000000
--- a/docs/docc/Reducer.doccarchive/img/deprecated-icon.015b4f17.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/img/modified-icon.f496e73d.svg b/docs/docc/Reducer.doccarchive/img/modified-icon.f496e73d.svg
deleted file mode 100644
index 3e0bd6f..0000000
--- a/docs/docc/Reducer.doccarchive/img/modified-icon.f496e73d.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/img/no-image@2x.df2a0a50.png b/docs/docc/Reducer.doccarchive/img/no-image@2x.df2a0a50.png
deleted file mode 100644
index 041394e..0000000
Binary files a/docs/docc/Reducer.doccarchive/img/no-image@2x.df2a0a50.png and /dev/null differ
diff --git a/docs/docc/Reducer.doccarchive/index.html b/docs/docc/Reducer.doccarchive/index.html
deleted file mode 100644
index a58bd88..0000000
--- a/docs/docc/Reducer.doccarchive/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Documentation
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/index/availability.index b/docs/docc/Reducer.doccarchive/index/availability.index
deleted file mode 100644
index f44216f..0000000
Binary files a/docs/docc/Reducer.doccarchive/index/availability.index and /dev/null differ
diff --git a/docs/docc/Reducer.doccarchive/index/data.mdb b/docs/docc/Reducer.doccarchive/index/data.mdb
deleted file mode 100755
index 4fdf084..0000000
Binary files a/docs/docc/Reducer.doccarchive/index/data.mdb and /dev/null differ
diff --git a/docs/docc/Reducer.doccarchive/index/index.json b/docs/docc/Reducer.doccarchive/index/index.json
deleted file mode 100644
index 3d12d8f..0000000
--- a/docs/docc/Reducer.doccarchive/index/index.json
+++ /dev/null
@@ -1 +0,0 @@
-{"interfaceLanguages":{"swift":[{"children":[{"title":"Structures","type":"groupMarker"},{"children":[{"title":"Instance Properties","type":"groupMarker"},{"path":"\/documentation\/reducer\/reducer\/reduce","title":"let reduce: (ActionType, inout StateType) -> Void","type":"property"},{"title":"Instance Methods","type":"groupMarker"},{"path":"\/documentation\/reducer\/reducer\/lift(action:)","title":"func lift(action: KeyPath) -> Reducer","type":"method"},{"path":"\/documentation\/reducer\/reducer\/lift(action:state:)","title":"func lift(action: KeyPath, state: WritableKeyPath) -> Reducer","type":"method"},{"path":"\/documentation\/reducer\/reducer\/lift(actiongetter:stategetter:statesetter:)","title":"func lift(actionGetter: (GlobalActionType) -> ActionType?, stateGetter: (GlobalStateType) -> StateType, stateSetter: (inout GlobalStateType, StateType) -> Void) -> Reducer","type":"method"},{"path":"\/documentation\/reducer\/reducer\/lift(state:)","title":"func lift(state: WritableKeyPath) -> Reducer","type":"method"},{"path":"\/documentation\/reducer\/reducer\/lifttocollection(action:statecollection:)-4gphe","title":"func liftToCollection(action: KeyPath, stateCollection: WritableKeyPath) -> Reducer","type":"method"},{"path":"\/documentation\/reducer\/reducer\/lifttocollection(action:statecollection:)-5a160","title":"func liftToCollection(action: KeyPath, stateCollection: WritableKeyPath) -> Reducer","type":"method"},{"path":"\/documentation\/reducer\/reducer\/lifttocollection(action:statecollection:identifier:)","title":"func liftToCollection(action: KeyPath, stateCollection: WritableKeyPath, identifier: KeyPath) -> Reducer","type":"method"},{"title":"Type Properties","type":"groupMarker"},{"path":"\/documentation\/reducer\/reducer\/identity","title":"static var identity: Reducer","type":"property"},{"title":"Type Methods","type":"groupMarker"},{"path":"\/documentation\/reducer\/reducer\/compose(_:_:)","title":"static func compose(Reducer, Reducer...) -> Reducer","type":"method"},{"path":"\/documentation\/reducer\/reducer\/compose(content:)","title":"static func compose(content: () -> Reducer) -> Reducer","type":"method"},{"path":"\/documentation\/reducer\/reducer\/reduce(_:)","title":"static func reduce((ActionType, inout StateType) -> Void) -> Reducer","type":"method"}],"path":"\/documentation\/reducer\/reducer","title":"Reducer","type":"struct"},{"title":"Enumerations","type":"groupMarker"},{"children":[{"title":"Type Methods","type":"groupMarker"},{"path":"\/documentation\/reducer\/reducerbuilder\/buildblock(_:)","title":"static func buildBlock(Reducer...) -> Reducer","type":"method"}],"path":"\/documentation\/reducer\/reducerbuilder","title":"ReducerBuilder","type":"enum"}],"path":"\/documentation\/reducer","title":"Reducer","type":"module"}]},"schemaVersion":{"major":0,"minor":1,"patch":0}}
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/index/navigator.index b/docs/docc/Reducer.doccarchive/index/navigator.index
deleted file mode 100644
index 4af6715..0000000
Binary files a/docs/docc/Reducer.doccarchive/index/navigator.index and /dev/null differ
diff --git a/docs/docc/Reducer.doccarchive/js/chunk-2d0d3105.cd72cc8e.js b/docs/docc/Reducer.doccarchive/js/chunk-2d0d3105.cd72cc8e.js
deleted file mode 100644
index 74345f0..0000000
--- a/docs/docc/Reducer.doccarchive/js/chunk-2d0d3105.cd72cc8e.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/*!
- * This source file is part of the Swift.org open source project
- *
- * Copyright (c) 2021 Apple Inc. and the Swift project authors
- * Licensed under Apache License v2.0 with Runtime Library Exception
- *
- * See https://swift.org/LICENSE.txt for license information
- * See https://swift.org/CONTRIBUTORS.txt for Swift project authors
- */
-(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0d3105"],{"5abe":function(t,e){(function(){"use strict";if("object"===typeof window)if("IntersectionObserver"in window&&"IntersectionObserverEntry"in window&&"intersectionRatio"in window.IntersectionObserverEntry.prototype)"isIntersecting"in window.IntersectionObserverEntry.prototype||Object.defineProperty(window.IntersectionObserverEntry.prototype,"isIntersecting",{get:function(){return this.intersectionRatio>0}});else{var t=function(t){var e=t,n=i(e);while(n)e=n.ownerDocument,n=i(e);return e}(window.document),e=[],n=null,o=null;s.prototype.THROTTLE_TIMEOUT=100,s.prototype.POLL_INTERVAL=null,s.prototype.USE_MUTATION_OBSERVER=!0,s._setupCrossOriginUpdater=function(){return n||(n=function(t,n){o=t&&n?g(t,n):p(),e.forEach((function(t){t._checkForIntersections()}))}),n},s._resetCrossOriginUpdater=function(){n=null,o=null},s.prototype.observe=function(t){var e=this._observationTargets.some((function(e){return e.element==t}));if(!e){if(!t||1!=t.nodeType)throw new Error("target must be an Element");this._registerInstance(),this._observationTargets.push({element:t,entry:null}),this._monitorIntersections(t.ownerDocument),this._checkForIntersections()}},s.prototype.unobserve=function(t){this._observationTargets=this._observationTargets.filter((function(e){return e.element!=t})),this._unmonitorIntersections(t.ownerDocument),0==this._observationTargets.length&&this._unregisterInstance()},s.prototype.disconnect=function(){this._observationTargets=[],this._unmonitorAllIntersections(),this._unregisterInstance()},s.prototype.takeRecords=function(){var t=this._queuedEntries.slice();return this._queuedEntries=[],t},s.prototype._initThresholds=function(t){var e=t||[0];return Array.isArray(e)||(e=[e]),e.sort().filter((function(t,e,n){if("number"!=typeof t||isNaN(t)||t<0||t>1)throw new Error("threshold must be a number between 0 and 1 inclusively");return t!==n[e-1]}))},s.prototype._parseRootMargin=function(t){var e=t||"0px",n=e.split(/\s+/).map((function(t){var e=/^(-?\d*\.?\d+)(px|%)$/.exec(t);if(!e)throw new Error("rootMargin must be specified in pixels or percent");return{value:parseFloat(e[1]),unit:e[2]}}));return n[1]=n[1]||n[0],n[2]=n[2]||n[0],n[3]=n[3]||n[1],n},s.prototype._monitorIntersections=function(e){var n=e.defaultView;if(n&&-1==this._monitoringDocuments.indexOf(e)){var o=this._checkForIntersections,r=null,s=null;this.POLL_INTERVAL?r=n.setInterval(o,this.POLL_INTERVAL):(c(n,"resize",o,!0),c(e,"scroll",o,!0),this.USE_MUTATION_OBSERVER&&"MutationObserver"in n&&(s=new n.MutationObserver(o),s.observe(e,{attributes:!0,childList:!0,characterData:!0,subtree:!0}))),this._monitoringDocuments.push(e),this._monitoringUnsubscribes.push((function(){var t=e.defaultView;t&&(r&&t.clearInterval(r),a(t,"resize",o,!0)),a(e,"scroll",o,!0),s&&s.disconnect()}));var h=this.root&&(this.root.ownerDocument||this.root)||t;if(e!=h){var u=i(e);u&&this._monitorIntersections(u.ownerDocument)}}},s.prototype._unmonitorIntersections=function(e){var n=this._monitoringDocuments.indexOf(e);if(-1!=n){var o=this.root&&(this.root.ownerDocument||this.root)||t,r=this._observationTargets.some((function(t){var n=t.element.ownerDocument;if(n==e)return!0;while(n&&n!=o){var r=i(n);if(n=r&&r.ownerDocument,n==e)return!0}return!1}));if(!r){var s=this._monitoringUnsubscribes[n];if(this._monitoringDocuments.splice(n,1),this._monitoringUnsubscribes.splice(n,1),s(),e!=o){var h=i(e);h&&this._unmonitorIntersections(h.ownerDocument)}}}},s.prototype._unmonitorAllIntersections=function(){var t=this._monitoringUnsubscribes.slice(0);this._monitoringDocuments.length=0,this._monitoringUnsubscribes.length=0;for(var e=0;e=0&&h>=0&&{top:n,bottom:o,left:i,right:r,width:s,height:h}||null}function f(t){var e;try{e=t.getBoundingClientRect()}catch(n){}return e?(e.width&&e.height||(e={top:e.top,right:e.right,bottom:e.bottom,left:e.left,width:e.right-e.left,height:e.bottom-e.top}),e):p()}function p(){return{top:0,bottom:0,left:0,right:0,width:0,height:0}}function d(t){return!t||"x"in t?t:{top:t.top,y:t.top,bottom:t.bottom,left:t.left,x:t.left,right:t.right,width:t.width,height:t.height}}function g(t,e){var n=e.top-t.top,o=e.left-t.left;return{top:n,left:o,height:e.height,width:e.width,bottom:n+e.height,right:o+e.width}}function m(t,e){var n=e;while(n){if(n==t)return!0;n=v(n)}return!1}function v(e){var n=e.parentNode;return 9==e.nodeType&&e!=t?i(e):(n&&n.assignedSlot&&(n=n.assignedSlot.parentNode),n&&11==n.nodeType&&n.host?n.host:n)}function w(t){return t&&9===t.nodeType}})()}}]);
\ No newline at end of file
diff --git a/docs/docc/Reducer.doccarchive/js/chunk-vendors.b24b7aaa.js b/docs/docc/Reducer.doccarchive/js/chunk-vendors.b24b7aaa.js
deleted file mode 100644
index 5a98336..0000000
--- a/docs/docc/Reducer.doccarchive/js/chunk-vendors.b24b7aaa.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*!
- * This source file is part of the Swift.org open source project
- *
- * Copyright (c) 2021 Apple Inc. and the Swift project authors
- * Licensed under Apache License v2.0 with Runtime Library Exception
- *
- * See https://swift.org/LICENSE.txt for license information
- * See https://swift.org/CONTRIBUTORS.txt for Swift project authors
- */
-(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-vendors"],{2877:function(t,e,n){"use strict";function r(t,e,n,r,o,i,a,s){var c,u="function"===typeof t?t.options:t;if(e&&(u.render=e,u.staticRenderFns=n,u._compiled=!0),r&&(u.functional=!0),i&&(u._scopeId="data-v-"+i),a?(c=function(t){t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,t||"undefined"===typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),o&&o.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(a)},u._ssrRegister=c):o&&(c=s?function(){o.call(this,(u.functional?this.parent:this).$root.$options.shadowRoot)}:o),c)if(u.functional){u._injectStyles=c;var f=u.render;u.render=function(t,e){return c.call(e),f(t,e)}}else{var l=u.beforeCreate;u.beforeCreate=l?[].concat(l,c):[c]}return{exports:t,options:u}}n.d(e,"a",(function(){return r}))},"2b0e":function(t,e,n){"use strict";n.r(e),function(t){
-/*!
- * Vue.js v2.6.14
- * (c) 2014-2021 Evan You
- * Released under the MIT License.
- */
-var n=Object.freeze({});function r(t){return void 0===t||null===t}function o(t){return void 0!==t&&null!==t}function i(t){return!0===t}function a(t){return!1===t}function s(t){return"string"===typeof t||"number"===typeof t||"symbol"===typeof t||"boolean"===typeof t}function c(t){return null!==t&&"object"===typeof t}var u=Object.prototype.toString;function f(t){return"[object Object]"===u.call(t)}function l(t){return"[object RegExp]"===u.call(t)}function p(t){var e=parseFloat(String(t));return e>=0&&Math.floor(e)===e&&isFinite(t)}function d(t){return o(t)&&"function"===typeof t.then&&"function"===typeof t.catch}function h(t){return null==t?"":Array.isArray(t)||f(t)&&t.toString===u?JSON.stringify(t,null,2):String(t)}function v(t){var e=parseFloat(t);return isNaN(e)?t:e}function y(t,e){for(var n=Object.create(null),r=t.split(","),o=0;o-1)return t.splice(n,1)}}var _=Object.prototype.hasOwnProperty;function b(t,e){return _.call(t,e)}function w(t){var e=Object.create(null);return function(n){var r=e[n];return r||(e[n]=t(n))}}var C=/-(\w)/g,x=w((function(t){return t.replace(C,(function(t,e){return e?e.toUpperCase():""}))})),A=w((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),$=/\B([A-Z])/g,k=w((function(t){return t.replace($,"-$1").toLowerCase()}));function O(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n}function S(t,e){return t.bind(e)}var E=Function.prototype.bind?S:O;function T(t,e){e=e||0;var n=t.length-e,r=new Array(n);while(n--)r[n]=t[n+e];return r}function j(t,e){for(var n in e)t[n]=e[n];return t}function R(t){for(var e={},n=0;n0,nt=Z&&Z.indexOf("edge/")>0,rt=(Z&&Z.indexOf("android"),Z&&/iphone|ipad|ipod|ios/.test(Z)||"ios"===Y),ot=(Z&&/chrome\/\d+/.test(Z),Z&&/phantomjs/.test(Z),Z&&Z.match(/firefox\/(\d+)/)),it={}.watch,at=!1;if(G)try{var st={};Object.defineProperty(st,"passive",{get:function(){at=!0}}),window.addEventListener("test-passive",null,st)}catch(Aa){}var ct=function(){return void 0===X&&(X=!G&&!Q&&"undefined"!==typeof t&&(t["process"]&&"server"===t["process"].env.VUE_ENV)),X},ut=G&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function ft(t){return"function"===typeof t&&/native code/.test(t.toString())}var lt,pt="undefined"!==typeof Symbol&&ft(Symbol)&&"undefined"!==typeof Reflect&&ft(Reflect.ownKeys);lt="undefined"!==typeof Set&&ft(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var dt=P,ht=0,vt=function(){this.id=ht++,this.subs=[]};vt.prototype.addSub=function(t){this.subs.push(t)},vt.prototype.removeSub=function(t){g(this.subs,t)},vt.prototype.depend=function(){vt.target&&vt.target.addDep(this)},vt.prototype.notify=function(){var t=this.subs.slice();for(var e=0,n=t.length;e-1)if(i&&!b(o,"default"))a=!1;else if(""===a||a===k(t)){var c=ee(String,o.type);(c<0||s0&&(a=Se(a,(e||"")+"_"+n),Oe(a[0])&&Oe(u)&&(f[c]=Ct(u.text+a[0].text),a.shift()),f.push.apply(f,a)):s(a)?Oe(u)?f[c]=Ct(u.text+a):""!==a&&f.push(Ct(a)):Oe(a)&&Oe(u)?f[c]=Ct(u.text+a.text):(i(t._isVList)&&o(a.tag)&&r(a.key)&&o(e)&&(a.key="__vlist"+e+"_"+n+"__"),f.push(a)));return f}function Ee(t){var e=t.$options.provide;e&&(t._provided="function"===typeof e?e.call(t):e)}function Te(t){var e=je(t.$options.inject,t);e&&(Et(!1),Object.keys(e).forEach((function(n){It(t,n,e[n])})),Et(!0))}function je(t,e){if(t){for(var n=Object.create(null),r=pt?Reflect.ownKeys(t):Object.keys(t),o=0;o0,a=t?!!t.$stable:!i,s=t&&t.$key;if(t){if(t._normalized)return t._normalized;if(a&&r&&r!==n&&s===r.$key&&!i&&!r.$hasNormal)return r;for(var c in o={},t)t[c]&&"$"!==c[0]&&(o[c]=Ne(e,c,t[c]))}else o={};for(var u in e)u in o||(o[u]=De(e,u));return t&&Object.isExtensible(t)&&(t._normalized=o),z(o,"$stable",a),z(o,"$key",s),z(o,"$hasNormal",i),o}function Ne(t,e,n){var r=function(){var t=arguments.length?n.apply(null,arguments):n({});t=t&&"object"===typeof t&&!Array.isArray(t)?[t]:ke(t);var e=t&&t[0];return t&&(!e||1===t.length&&e.isComment&&!Ie(e))?void 0:t};return n.proxy&&Object.defineProperty(t,e,{get:r,enumerable:!0,configurable:!0}),r}function De(t,e){return function(){return t[e]}}function Me(t,e){var n,r,i,a,s;if(Array.isArray(t)||"string"===typeof t)for(n=new Array(t.length),r=0,i=t.length;r1?T(n):n;for(var r=T(arguments,1),o='event handler for "'+t+'"',i=0,a=n.length;idocument.createEvent("Event").timeStamp&&(Jn=function(){return Gn.now()})}function Qn(){var t,e;for(Xn=Jn(),zn=!0,Vn.sort((function(t,e){return t.id-e.id})),Wn=0;WnWn&&Vn[n].id>t.id)n--;Vn.splice(n+1,0,t)}else Vn.push(t);qn||(qn=!0,ve(Qn))}}var nr=0,rr=function(t,e,n,r,o){this.vm=t,o&&(t._watcher=this),t._watchers.push(this),r?(this.deep=!!r.deep,this.user=!!r.user,this.lazy=!!r.lazy,this.sync=!!r.sync,this.before=r.before):this.deep=this.user=this.lazy=this.sync=!1,this.cb=n,this.id=++nr,this.active=!0,this.dirty=this.lazy,this.deps=[],this.newDeps=[],this.depIds=new lt,this.newDepIds=new lt,this.expression="","function"===typeof e?this.getter=e:(this.getter=K(e),this.getter||(this.getter=P)),this.value=this.lazy?void 0:this.get()};rr.prototype.get=function(){var t;mt(this);var e=this.vm;try{t=this.getter.call(e,e)}catch(Aa){if(!this.user)throw Aa;ne(Aa,e,'getter for watcher "'+this.expression+'"')}finally{this.deep&&me(t),gt(),this.cleanupDeps()}return t},rr.prototype.addDep=function(t){var e=t.id;this.newDepIds.has(e)||(this.newDepIds.add(e),this.newDeps.push(t),this.depIds.has(e)||t.addSub(this))},rr.prototype.cleanupDeps=function(){var t=this.deps.length;while(t--){var e=this.deps[t];this.newDepIds.has(e.id)||e.removeSub(this)}var n=this.depIds;this.depIds=this.newDepIds,this.newDepIds=n,this.newDepIds.clear(),n=this.deps,this.deps=this.newDeps,this.newDeps=n,this.newDeps.length=0},rr.prototype.update=function(){this.lazy?this.dirty=!0:this.sync?this.run():er(this)},rr.prototype.run=function(){if(this.active){var t=this.get();if(t!==this.value||c(t)||this.deep){var e=this.value;if(this.value=t,this.user){var n='callback for watcher "'+this.expression+'"';re(this.cb,this.vm,[t,e],this.vm,n)}else this.cb.call(this.vm,t,e)}}},rr.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},rr.prototype.depend=function(){var t=this.deps.length;while(t--)this.deps[t].depend()},rr.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||g(this.vm._watchers,this);var t=this.deps.length;while(t--)this.deps[t].removeSub(this);this.active=!1}};var or={enumerable:!0,configurable:!0,get:P,set:P};function ir(t,e,n){or.get=function(){return this[e][n]},or.set=function(t){this[e][n]=t},Object.defineProperty(t,n,or)}function ar(t){t._watchers=[];var e=t.$options;e.props&&sr(t,e.props),e.methods&&vr(t,e.methods),e.data?cr(t):Pt(t._data={},!0),e.computed&&lr(t,e.computed),e.watch&&e.watch!==it&&yr(t,e.watch)}function sr(t,e){var n=t.$options.propsData||{},r=t._props={},o=t.$options._propKeys=[],i=!t.$parent;i||Et(!1);var a=function(i){o.push(i);var a=Gt(i,e,n,t);It(r,i,a),i in t||ir(t,"_props",i)};for(var s in e)a(s);Et(!0)}function cr(t){var e=t.$options.data;e=t._data="function"===typeof e?ur(e,t):e||{},f(e)||(e={});var n=Object.keys(e),r=t.$options.props,o=(t.$options.methods,n.length);while(o--){var i=n[o];0,r&&b(r,i)||q(i)||ir(t,"_data",i)}Pt(e,!0)}function ur(t,e){mt();try{return t.call(e,e)}catch(Aa){return ne(Aa,e,"data()"),{}}finally{gt()}}var fr={lazy:!0};function lr(t,e){var n=t._computedWatchers=Object.create(null),r=ct();for(var o in e){var i=e[o],a="function"===typeof i?i:i.get;0,r||(n[o]=new rr(t,a||P,P,fr)),o in t||pr(t,o,i)}}function pr(t,e,n){var r=!ct();"function"===typeof n?(or.get=r?dr(e):hr(n),or.set=P):(or.get=n.get?r&&!1!==n.cache?dr(e):hr(n.get):P,or.set=n.set||P),Object.defineProperty(t,e,or)}function dr(t){return function(){var e=this._computedWatchers&&this._computedWatchers[t];if(e)return e.dirty&&e.evaluate(),vt.target&&e.depend(),e.value}}function hr(t){return function(){return t.call(this,this)}}function vr(t,e){t.$options.props;for(var n in e)t[n]="function"!==typeof e[n]?P:E(e[n],t)}function yr(t,e){for(var n in e){var r=e[n];if(Array.isArray(r))for(var o=0;o-1)return this;var n=T(arguments,1);return n.unshift(this),"function"===typeof t.install?t.install.apply(t,n):"function"===typeof t&&t.apply(null,n),e.push(t),this}}function kr(t){t.mixin=function(t){return this.options=Xt(this.options,t),this}}function Or(t){t.cid=0;var e=1;t.extend=function(t){t=t||{};var n=this,r=n.cid,o=t._Ctor||(t._Ctor={});if(o[r])return o[r];var i=t.name||n.options.name;var a=function(t){this._init(t)};return a.prototype=Object.create(n.prototype),a.prototype.constructor=a,a.cid=e++,a.options=Xt(n.options,t),a["super"]=n,a.options.props&&Sr(a),a.options.computed&&Er(a),a.extend=n.extend,a.mixin=n.mixin,a.use=n.use,U.forEach((function(t){a[t]=n[t]})),i&&(a.options.components[i]=a),a.superOptions=n.options,a.extendOptions=t,a.sealedOptions=j({},a.options),o[r]=a,a}}function Sr(t){var e=t.options.props;for(var n in e)ir(t.prototype,"_props",n)}function Er(t){var e=t.options.computed;for(var n in e)pr(t.prototype,n,e[n])}function Tr(t){U.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&f(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&"function"===typeof n&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}function jr(t){return t&&(t.Ctor.options.name||t.tag)}function Rr(t,e){return Array.isArray(t)?t.indexOf(e)>-1:"string"===typeof t?t.split(",").indexOf(e)>-1:!!l(t)&&t.test(e)}function Pr(t,e){var n=t.cache,r=t.keys,o=t._vnode;for(var i in n){var a=n[i];if(a){var s=a.name;s&&!e(s)&&Ir(n,i,r,o)}}}function Ir(t,e,n,r){var o=t[e];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),t[e]=null,g(n,e)}br(Ar),gr(Ar),Tn(Ar),In(Ar),bn(Ar);var Lr=[String,RegExp,Array],Nr={name:"keep-alive",abstract:!0,props:{include:Lr,exclude:Lr,max:[String,Number]},methods:{cacheVNode:function(){var t=this,e=t.cache,n=t.keys,r=t.vnodeToCache,o=t.keyToCache;if(r){var i=r.tag,a=r.componentInstance,s=r.componentOptions;e[o]={name:jr(s),tag:i,componentInstance:a},n.push(o),this.max&&n.length>parseInt(this.max)&&Ir(e,n[0],n,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var t in this.cache)Ir(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Pr(t,(function(t){return Rr(e,t)}))})),this.$watch("exclude",(function(e){Pr(t,(function(t){return!Rr(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=An(t),n=e&&e.componentOptions;if(n){var r=jr(n),o=this,i=o.include,a=o.exclude;if(i&&(!r||!Rr(i,r))||a&&r&&Rr(a,r))return e;var s=this,c=s.cache,u=s.keys,f=null==e.key?n.Ctor.cid+(n.tag?"::"+n.tag:""):e.key;c[f]?(e.componentInstance=c[f].componentInstance,g(u,f),u.push(f)):(this.vnodeToCache=e,this.keyToCache=f),e.data.keepAlive=!0}return e||t&&t[0]}},Dr={KeepAlive:Nr};function Mr(t){var e={get:function(){return B}};Object.defineProperty(t,"config",e),t.util={warn:dt,extend:j,mergeOptions:Xt,defineReactive:It},t.set=Lt,t.delete=Nt,t.nextTick=ve,t.observable=function(t){return Pt(t),t},t.options=Object.create(null),U.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,j(t.options.components,Dr),$r(t),kr(t),Or(t),Tr(t)}Mr(Ar),Object.defineProperty(Ar.prototype,"$isServer",{get:ct}),Object.defineProperty(Ar.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Ar,"FunctionalRenderContext",{value:Ze}),Ar.version="2.6.14";var Fr=y("style,class"),Ur=y("input,textarea,option,select,progress"),Vr=function(t,e,n){return"value"===n&&Ur(t)&&"button"!==e||"selected"===n&&"option"===t||"checked"===n&&"input"===t||"muted"===n&&"video"===t},Br=y("contenteditable,draggable,spellcheck"),Hr=y("events,caret,typing,plaintext-only"),qr=function(t,e){return Jr(e)||"false"===e?"false":"contenteditable"===t&&Hr(e)?e:"true"},zr=y("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),Wr="http://www.w3.org/1999/xlink",Kr=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},Xr=function(t){return Kr(t)?t.slice(6,t.length):""},Jr=function(t){return null==t||!1===t};function Gr(t){var e=t.data,n=t,r=t;while(o(r.componentInstance))r=r.componentInstance._vnode,r&&r.data&&(e=Qr(r.data,e));while(o(n=n.parent))n&&n.data&&(e=Qr(e,n.data));return Yr(e.staticClass,e.class)}function Qr(t,e){return{staticClass:Zr(t.staticClass,e.staticClass),class:o(t.class)?[t.class,e.class]:e.class}}function Yr(t,e){return o(t)||o(e)?Zr(t,to(e)):""}function Zr(t,e){return t?e?t+" "+e:t:e||""}function to(t){return Array.isArray(t)?eo(t):c(t)?no(t):"string"===typeof t?t:""}function eo(t){for(var e,n="",r=0,i=t.length;r-1?co[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:co[t]=/HTMLUnknownElement/.test(e.toString())}var fo=y("text,number,password,search,email,tel,url");function lo(t){if("string"===typeof t){var e=document.querySelector(t);return e||document.createElement("div")}return t}function po(t,e){var n=document.createElement(t);return"select"!==t||e.data&&e.data.attrs&&void 0!==e.data.attrs.multiple&&n.setAttribute("multiple","multiple"),n}function ho(t,e){return document.createElementNS(ro[t],e)}function vo(t){return document.createTextNode(t)}function yo(t){return document.createComment(t)}function mo(t,e,n){t.insertBefore(e,n)}function go(t,e){t.removeChild(e)}function _o(t,e){t.appendChild(e)}function bo(t){return t.parentNode}function wo(t){return t.nextSibling}function Co(t){return t.tagName}function xo(t,e){t.textContent=e}function Ao(t,e){t.setAttribute(e,"")}var $o=Object.freeze({createElement:po,createElementNS:ho,createTextNode:vo,createComment:yo,insertBefore:mo,removeChild:go,appendChild:_o,parentNode:bo,nextSibling:wo,tagName:Co,setTextContent:xo,setStyleScope:Ao}),ko={create:function(t,e){Oo(e)},update:function(t,e){t.data.ref!==e.data.ref&&(Oo(t,!0),Oo(e))},destroy:function(t){Oo(t,!0)}};function Oo(t,e){var n=t.data.ref;if(o(n)){var r=t.context,i=t.componentInstance||t.elm,a=r.$refs;e?Array.isArray(a[n])?g(a[n],i):a[n]===i&&(a[n]=void 0):t.data.refInFor?Array.isArray(a[n])?a[n].indexOf(i)<0&&a[n].push(i):a[n]=[i]:a[n]=i}}var So=new _t("",{},[]),Eo=["create","activate","update","remove","destroy"];function To(t,e){return t.key===e.key&&t.asyncFactory===e.asyncFactory&&(t.tag===e.tag&&t.isComment===e.isComment&&o(t.data)===o(e.data)&&jo(t,e)||i(t.isAsyncPlaceholder)&&r(e.asyncFactory.error))}function jo(t,e){if("input"!==t.tag)return!0;var n,r=o(n=t.data)&&o(n=n.attrs)&&n.type,i=o(n=e.data)&&o(n=n.attrs)&&n.type;return r===i||fo(r)&&fo(i)}function Ro(t,e,n){var r,i,a={};for(r=e;r<=n;++r)i=t[r].key,o(i)&&(a[i]=r);return a}function Po(t){var e,n,a={},c=t.modules,u=t.nodeOps;for(e=0;ev?(l=r(n[g+1])?null:n[g+1].elm,x(t,l,n,h,g,i)):h>g&&$(e,p,v)}function S(t,e,n,r){for(var i=n;i-1?qo(t,e,n):zr(e)?Jr(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):Br(e)?t.setAttribute(e,qr(e,n)):Kr(e)?Jr(n)?t.removeAttributeNS(Wr,Xr(e)):t.setAttributeNS(Wr,e,n):qo(t,e,n)}function qo(t,e,n){if(Jr(n))t.removeAttribute(e);else{if(tt&&!et&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var zo={create:Bo,update:Bo};function Wo(t,e){var n=e.elm,i=e.data,a=t.data;if(!(r(i.staticClass)&&r(i.class)&&(r(a)||r(a.staticClass)&&r(a.class)))){var s=Gr(e),c=n._transitionClasses;o(c)&&(s=Zr(s,to(c))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}var Ko,Xo={create:Wo,update:Wo},Jo="__r",Go="__c";function Qo(t){if(o(t[Jo])){var e=tt?"change":"input";t[e]=[].concat(t[Jo],t[e]||[]),delete t[Jo]}o(t[Go])&&(t.change=[].concat(t[Go],t.change||[]),delete t[Go])}function Yo(t,e,n){var r=Ko;return function o(){var i=e.apply(null,arguments);null!==i&&ei(t,o,n,r)}}var Zo=se&&!(ot&&Number(ot[1])<=53);function ti(t,e,n,r){if(Zo){var o=Xn,i=e;e=i._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=o||t.timeStamp<=0||t.target.ownerDocument!==document)return i.apply(this,arguments)}}Ko.addEventListener(t,e,at?{capture:n,passive:r}:n)}function ei(t,e,n,r){(r||Ko).removeEventListener(t,e._wrapper||e,n)}function ni(t,e){if(!r(t.data.on)||!r(e.data.on)){var n=e.data.on||{},o=t.data.on||{};Ko=e.elm,Qo(n),we(n,o,ti,ei,Yo,e.context),Ko=void 0}}var ri,oi={create:ni,update:ni};function ii(t,e){if(!r(t.data.domProps)||!r(e.data.domProps)){var n,i,a=e.elm,s=t.data.domProps||{},c=e.data.domProps||{};for(n in o(c.__ob__)&&(c=e.data.domProps=j({},c)),s)n in c||(a[n]="");for(n in c){if(i=c[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),i===s[n])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===n&&"PROGRESS"!==a.tagName){a._value=i;var u=r(i)?"":String(i);ai(a,u)&&(a.value=u)}else if("innerHTML"===n&&io(a.tagName)&&r(a.innerHTML)){ri=ri||document.createElement("div"),ri.innerHTML="";var f=ri.firstChild;while(a.firstChild)a.removeChild(a.firstChild);while(f.firstChild)a.appendChild(f.firstChild)}else if(i!==s[n])try{a[n]=i}catch(Aa){}}}}function ai(t,e){return!t.composing&&("OPTION"===t.tagName||si(t,e)||ci(t,e))}function si(t,e){var n=!0;try{n=document.activeElement!==t}catch(Aa){}return n&&t.value!==e}function ci(t,e){var n=t.value,r=t._vModifiers;if(o(r)){if(r.number)return v(n)!==v(e);if(r.trim)return n.trim()!==e.trim()}return n!==e}var ui={create:ii,update:ii},fi=w((function(t){var e={},n=/;(?![^(]*\))/g,r=/:(.+)/;return t.split(n).forEach((function(t){if(t){var n=t.split(r);n.length>1&&(e[n[0].trim()]=n[1].trim())}})),e}));function li(t){var e=pi(t.style);return t.staticStyle?j(t.staticStyle,e):e}function pi(t){return Array.isArray(t)?R(t):"string"===typeof t?fi(t):t}function di(t,e){var n,r={};if(e){var o=t;while(o.componentInstance)o=o.componentInstance._vnode,o&&o.data&&(n=li(o.data))&&j(r,n)}(n=li(t.data))&&j(r,n);var i=t;while(i=i.parent)i.data&&(n=li(i.data))&&j(r,n);return r}var hi,vi=/^--/,yi=/\s*!important$/,mi=function(t,e,n){if(vi.test(e))t.style.setProperty(e,n);else if(yi.test(n))t.style.setProperty(k(e),n.replace(yi,""),"important");else{var r=_i(e);if(Array.isArray(n))for(var o=0,i=n.length;o-1?e.split(Ci).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" "+(t.getAttribute("class")||"")+" ";n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function Ai(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(Ci).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{var n=" "+(t.getAttribute("class")||"")+" ",r=" "+e+" ";while(n.indexOf(r)>=0)n=n.replace(r," ");n=n.trim(),n?t.setAttribute("class",n):t.removeAttribute("class")}}function $i(t){if(t){if("object"===typeof t){var e={};return!1!==t.css&&j(e,ki(t.name||"v")),j(e,t),e}return"string"===typeof t?ki(t):void 0}}var ki=w((function(t){return{enterClass:t+"-enter",enterToClass:t+"-enter-to",enterActiveClass:t+"-enter-active",leaveClass:t+"-leave",leaveToClass:t+"-leave-to",leaveActiveClass:t+"-leave-active"}})),Oi=G&&!et,Si="transition",Ei="animation",Ti="transition",ji="transitionend",Ri="animation",Pi="animationend";Oi&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(Ti="WebkitTransition",ji="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(Ri="WebkitAnimation",Pi="webkitAnimationEnd"));var Ii=G?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function Li(t){Ii((function(){Ii(t)}))}function Ni(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),xi(t,e))}function Di(t,e){t._transitionClasses&&g(t._transitionClasses,e),Ai(t,e)}function Mi(t,e,n){var r=Ui(t,e),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var s=o===Si?ji:Pi,c=0,u=function(){t.removeEventListener(s,f),n()},f=function(e){e.target===t&&++c>=a&&u()};setTimeout((function(){c0&&(n=Si,f=a,l=i.length):e===Ei?u>0&&(n=Ei,f=u,l=c.length):(f=Math.max(a,u),n=f>0?a>u?Si:Ei:null,l=n?n===Si?i.length:c.length:0);var p=n===Si&&Fi.test(r[Ti+"Property"]);return{type:n,timeout:f,propCount:l,hasTransform:p}}function Vi(t,e){while(t.length1}function Ki(t,e){!0!==e.data.show&&Hi(e)}var Xi=G?{create:Ki,activate:Ki,remove:function(t,e){!0!==t.data.show?qi(t,e):e()}}:{},Ji=[zo,Xo,oi,ui,wi,Xi],Gi=Ji.concat(Vo),Qi=Po({nodeOps:$o,modules:Gi});et&&document.addEventListener("selectionchange",(function(){var t=document.activeElement;t&&t.vmodel&&ia(t,"input")}));var Yi={inserted:function(t,e,n,r){"select"===n.tag?(r.elm&&!r.elm._vOptions?Ce(n,"postpatch",(function(){Yi.componentUpdated(t,e,n)})):Zi(t,e,n.context),t._vOptions=[].map.call(t.options,na)):("textarea"===n.tag||fo(t.type))&&(t._vModifiers=e.modifiers,e.modifiers.lazy||(t.addEventListener("compositionstart",ra),t.addEventListener("compositionend",oa),t.addEventListener("change",oa),et&&(t.vmodel=!0)))},componentUpdated:function(t,e,n){if("select"===n.tag){Zi(t,e,n.context);var r=t._vOptions,o=t._vOptions=[].map.call(t.options,na);if(o.some((function(t,e){return!N(t,r[e])}))){var i=t.multiple?e.value.some((function(t){return ea(t,o)})):e.value!==e.oldValue&&ea(e.value,o);i&&ia(t,"change")}}}};function Zi(t,e,n){ta(t,e,n),(tt||nt)&&setTimeout((function(){ta(t,e,n)}),0)}function ta(t,e,n){var r=e.value,o=t.multiple;if(!o||Array.isArray(r)){for(var i,a,s=0,c=t.options.length;s-1,a.selected!==i&&(a.selected=i);else if(N(na(a),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));o||(t.selectedIndex=-1)}}function ea(t,e){return e.every((function(e){return!N(e,t)}))}function na(t){return"_value"in t?t._value:t.value}function ra(t){t.target.composing=!0}function oa(t){t.target.composing&&(t.target.composing=!1,ia(t.target,"input"))}function ia(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function aa(t){return!t.componentInstance||t.data&&t.data.transition?t:aa(t.componentInstance._vnode)}var sa={bind:function(t,e,n){var r=e.value;n=aa(n);var o=n.data&&n.data.transition,i=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&o?(n.data.show=!0,Hi(n,(function(){t.style.display=i}))):t.style.display=r?i:"none"},update:function(t,e,n){var r=e.value,o=e.oldValue;if(!r!==!o){n=aa(n);var i=n.data&&n.data.transition;i?(n.data.show=!0,r?Hi(n,(function(){t.style.display=t.__vOriginalDisplay})):qi(n,(function(){t.style.display="none"}))):t.style.display=r?t.__vOriginalDisplay:"none"}},unbind:function(t,e,n,r,o){o||(t.style.display=t.__vOriginalDisplay)}},ca={model:Yi,show:sa},ua={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function fa(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?fa(An(e.children)):t}function la(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var o=n._parentListeners;for(var i in o)e[x(i)]=o[i];return e}function pa(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}function da(t){while(t=t.parent)if(t.data.transition)return!0}function ha(t,e){return e.key===t.key&&e.tag===t.tag}var va=function(t){return t.tag||Ie(t)},ya=function(t){return"show"===t.name},ma={name:"transition",props:ua,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(va),n.length)){0;var r=this.mode;0;var o=n[0];if(da(this.$vnode))return o;var i=fa(o);if(!i)return o;if(this._leaving)return pa(t,o);var a="__transition-"+this._uid+"-";i.key=null==i.key?i.isComment?a+"comment":a+i.tag:s(i.key)?0===String(i.key).indexOf(a)?i.key:a+i.key:i.key;var c=(i.data||(i.data={})).transition=la(this),u=this._vnode,f=fa(u);if(i.data.directives&&i.data.directives.some(ya)&&(i.data.show=!0),f&&f.data&&!ha(i,f)&&!Ie(f)&&(!f.componentInstance||!f.componentInstance._vnode.isComment)){var l=f.data.transition=j({},c);if("out-in"===r)return this._leaving=!0,Ce(l,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),pa(t,o);if("in-out"===r){if(Ie(i))return u;var p,d=function(){p()};Ce(c,"afterEnter",d),Ce(c,"enterCancelled",d),Ce(l,"delayLeave",(function(t){p=t}))}}return o}}},ga=j({tag:String,moveClass:String},ua);delete ga.mode;var _a={props:ga,beforeMount:function(){var t=this,e=this._update;this._update=function(n,r){var o=Rn(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,o(),e.call(t,n,r)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=la(this),s=0;s0?u(n.join("=")):null;void 0===e[r]?e[r]=o:Array.isArray(e[r])?e[r].push(o):e[r]=[e[r],o]})),e):e}function d(t){var e=t?Object.keys(t).map((function(e){var n=t[e];if(void 0===n)return"";if(null===n)return c(e);if(Array.isArray(n)){var r=[];return n.forEach((function(t){void 0!==t&&(null===t?r.push(c(e)):r.push(c(e)+"="+c(t)))})),r.join("&")}return c(e)+"="+c(n)})).filter((function(t){return t.length>0})).join("&"):null;return e?"?"+e:""}var h=/\/?$/;function v(t,e,n,r){var o=r&&r.options.stringifyQuery,i=e.query||{};try{i=y(i)}catch(s){}var a={name:e.name||t&&t.name,meta:t&&t.meta||{},path:e.path||"/",hash:e.hash||"",query:i,params:e.params||{},fullPath:_(e,o),matched:t?g(t):[]};return n&&(a.redirectedFrom=_(n,o)),Object.freeze(a)}function y(t){if(Array.isArray(t))return t.map(y);if(t&&"object"===typeof t){var e={};for(var n in t)e[n]=y(t[n]);return e}return t}var m=v(null,{path:"/"});function g(t){var e=[];while(t)e.unshift(t),t=t.parent;return e}function _(t,e){var n=t.path,r=t.query;void 0===r&&(r={});var o=t.hash;void 0===o&&(o="");var i=e||d;return(n||"/")+i(r)+o}function b(t,e,n){return e===m?t===e:!!e&&(t.path&&e.path?t.path.replace(h,"")===e.path.replace(h,"")&&(n||t.hash===e.hash&&w(t.query,e.query)):!(!t.name||!e.name)&&(t.name===e.name&&(n||t.hash===e.hash&&w(t.query,e.query)&&w(t.params,e.params))))}function w(t,e){if(void 0===t&&(t={}),void 0===e&&(e={}),!t||!e)return t===e;var n=Object.keys(t).sort(),r=Object.keys(e).sort();return n.length===r.length&&n.every((function(n,o){var i=t[n],a=r[o];if(a!==n)return!1;var s=e[n];return null==i||null==s?i===s:"object"===typeof i&&"object"===typeof s?w(i,s):String(i)===String(s)}))}function C(t,e){return 0===t.path.replace(h,"/").indexOf(e.path.replace(h,"/"))&&(!e.hash||t.hash===e.hash)&&x(t.query,e.query)}function x(t,e){for(var n in e)if(!(n in t))return!1;return!0}function A(t){for(var e=0;e