From a9c7287b1eda424d3d1fab31436643969dbe0342 Mon Sep 17 00:00:00 2001 From: pjechris Date: Mon, 23 Oct 2023 08:23:18 +0000 Subject: [PATCH] Deploying Updated Jazzy Docs --- Classes.html | 188 ++ Classes/IdentityMap.html | 948 +++++++++ Classes/Subscription.html | 165 ++ Enums.html | 160 ++ Enums/StampError.html | 166 ++ Extensions.html | 213 +++ Extensions/Date.html | 167 ++ Extensions/Publisher.html | 251 +++ Protocols.html | 247 +++ Protocols/Aggregate.html | 167 ++ Protocols/EntityEnumWrapper.html | 186 ++ Protocols/Logger.html | 278 +++ Protocols/Observer.html | 276 +++ Structs.html | 217 +++ Structs/AliasKey.html | 166 ++ Structs/EntityObserver.html | 218 +++ Structs/PartialIdentifiableKeyPath.html | 403 ++++ Typealiases.html | 161 ++ badge.svg | 28 + css/highlight.css | 202 ++ css/jazzy.css | 439 +++++ docsets/.docset/Contents/Info.plist | 20 + .../Contents/Resources/Documents/Classes.html | 188 ++ .../Documents/Classes/IdentityMap.html | 948 +++++++++ .../Documents/Classes/Subscription.html | 165 ++ .../Contents/Resources/Documents/Enums.html | 160 ++ .../Resources/Documents/Enums/StampError.html | 166 ++ .../Resources/Documents/Extensions.html | 213 +++ .../Resources/Documents/Extensions/Date.html | 167 ++ .../Documents/Extensions/Publisher.html | 251 +++ .../Resources/Documents/Protocols.html | 247 +++ .../Documents/Protocols/Aggregate.html | 167 ++ .../Protocols/EntityEnumWrapper.html | 186 ++ .../Resources/Documents/Protocols/Logger.html | 278 +++ .../Documents/Protocols/Observer.html | 276 +++ .../Contents/Resources/Documents/Structs.html | 217 +++ .../Resources/Documents/Structs/AliasKey.html | 166 ++ .../Documents/Structs/EntityObserver.html | 218 +++ .../Structs/PartialIdentifiableKeyPath.html | 403 ++++ .../Resources/Documents/Typealiases.html | 161 ++ .../Resources/Documents/css/highlight.css | 202 ++ .../Resources/Documents/css/jazzy.css | 439 +++++ .../Resources/Documents/img/carat.png | Bin 0 -> 274 bytes .../Contents/Resources/Documents/img/dash.png | Bin 0 -> 1338 bytes .../Resources/Documents/img/spinner.gif | Bin 0 -> 1849 bytes .../Contents/Resources/Documents/index.html | 403 ++++ .../Contents/Resources/Documents/js/jazzy.js | 74 + .../Resources/Documents/js/jazzy.search.js | 74 + .../Resources/Documents/js/jquery.min.js | 2 + .../Resources/Documents/js/lunr.min.js | 6 + .../Documents/js/typeahead.jquery.js | 1694 +++++++++++++++++ .../Contents/Resources/Documents/search.json | 1 + .../.docset/Contents/Resources/docSet.dsidx | Bin 0 -> 36864 bytes docsets/.tgz | Bin 0 -> 87317 bytes img/carat.png | Bin 0 -> 274 bytes img/dash.png | Bin 0 -> 1338 bytes img/spinner.gif | Bin 0 -> 1849 bytes index.html | 403 ++++ js/jazzy.js | 74 + js/jazzy.search.js | 74 + js/jquery.min.js | 2 + js/lunr.min.js | 6 + js/typeahead.jquery.js | 1694 +++++++++++++++++ search.json | 1 + undocumented.json | 6 + 65 files changed, 14998 insertions(+) create mode 100644 Classes.html create mode 100644 Classes/IdentityMap.html create mode 100644 Classes/Subscription.html create mode 100644 Enums.html create mode 100644 Enums/StampError.html create mode 100644 Extensions.html create mode 100644 Extensions/Date.html create mode 100644 Extensions/Publisher.html create mode 100644 Protocols.html create mode 100644 Protocols/Aggregate.html create mode 100644 Protocols/EntityEnumWrapper.html create mode 100644 Protocols/Logger.html create mode 100644 Protocols/Observer.html create mode 100644 Structs.html create mode 100644 Structs/AliasKey.html create mode 100644 Structs/EntityObserver.html create mode 100644 Structs/PartialIdentifiableKeyPath.html create mode 100644 Typealiases.html create mode 100644 badge.svg create mode 100644 css/highlight.css create mode 100644 css/jazzy.css create mode 100644 docsets/.docset/Contents/Info.plist create mode 100644 docsets/.docset/Contents/Resources/Documents/Classes.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Classes/IdentityMap.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Classes/Subscription.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Enums.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Enums/StampError.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Extensions.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Extensions/Date.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Extensions/Publisher.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Protocols.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Protocols/Aggregate.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Protocols/EntityEnumWrapper.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Protocols/Logger.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Protocols/Observer.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Structs.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Structs/AliasKey.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Structs/EntityObserver.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Structs/PartialIdentifiableKeyPath.html create mode 100644 docsets/.docset/Contents/Resources/Documents/Typealiases.html create mode 100644 docsets/.docset/Contents/Resources/Documents/css/highlight.css create mode 100644 docsets/.docset/Contents/Resources/Documents/css/jazzy.css create mode 100755 docsets/.docset/Contents/Resources/Documents/img/carat.png create mode 100755 docsets/.docset/Contents/Resources/Documents/img/dash.png create mode 100644 docsets/.docset/Contents/Resources/Documents/img/spinner.gif create mode 100644 docsets/.docset/Contents/Resources/Documents/index.html create mode 100755 docsets/.docset/Contents/Resources/Documents/js/jazzy.js create mode 100644 docsets/.docset/Contents/Resources/Documents/js/jazzy.search.js create mode 100644 docsets/.docset/Contents/Resources/Documents/js/jquery.min.js create mode 100644 docsets/.docset/Contents/Resources/Documents/js/lunr.min.js create mode 100644 docsets/.docset/Contents/Resources/Documents/js/typeahead.jquery.js create mode 100644 docsets/.docset/Contents/Resources/Documents/search.json create mode 100644 docsets/.docset/Contents/Resources/docSet.dsidx create mode 100644 docsets/.tgz create mode 100755 img/carat.png create mode 100755 img/dash.png create mode 100644 img/spinner.gif create mode 100644 index.html create mode 100755 js/jazzy.js create mode 100644 js/jazzy.search.js create mode 100644 js/jquery.min.js create mode 100644 js/lunr.min.js create mode 100644 js/typeahead.jquery.js create mode 100644 search.json create mode 100644 undocumented.json diff --git a/Classes.html b/Classes.html new file mode 100644 index 0000000..a682029 --- /dev/null +++ b/Classes.html @@ -0,0 +1,188 @@ + + + + Classes Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Classes

+

The following classes are available globally.

+ +
+
+
+
    +
  • +
    + + + + IdentityMap + +
    +
    +
    +
    +
    +
    +

    Manages entities lifecycle and synchronisation

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public class IdentityMap
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + Subscription + +
    +
    +
    +
    +
    +
    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public class Subscription
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Classes/IdentityMap.html b/Classes/IdentityMap.html new file mode 100644 index 0000000..33eb73d --- /dev/null +++ b/Classes/IdentityMap.html @@ -0,0 +1,948 @@ + + + + IdentityMap Class Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

IdentityMap

+
+
+ +
public class IdentityMap
+ +
+
+

Manages entities lifecycle and synchronisation

+ +
+
+
+
    +
  • +
    + + + + Update + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public typealias Update<T> = (inout T) -> Void
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(queue:logger:) + +
    +
    +
    +
    +
    +
    +

    Create a new IdentityMap instance optionally with a queue and a logger

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public convenience init(queue: DispatchQueue? = nil, logger: Logger? = nil)
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + queue + + +
    +

    the queue on which to receive updates. If nil identitymap will create its own.

    +
    +
    + + logger + + +
    +

    a logger to follow/debug identity internal state

    +
    +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Store an entity in the storage. Entity will be stored only if stamp (modifiedAt) is higher than in previous +insertion.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store<T: Identifiable>(
    +    entity: T,
    +    named: AliasKey<T>? = nil,
    +    modifiedAt: Stamp? = nil,
    +    ifPresent update: Update<T>? = nil
    +) -> EntityObserver<T>
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + + + + + + + + + +
    + + entity + + +
    +

    the element to store in the identity map

    +
    +
    + + named + + +
    +

    an alias to reference the entity and retrieve it using it

    +
    +
    + + modifiedAt + + +
    +

    if entity was already stored it will be used to determine if the update should be applied or discarded

    +
    +
    + + ifPresent + + +
    +

    applies the closure before storing it if it’s already been stored. In this case this is similar as +calling update

    +
    +
    +
    +
    +

    Return Value

    +

    an object to observe changes on the entity

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Store an aggregate in the storage. Each aggregate entities will be stored only if stamp (modifiedAt) is higher than in previous +insertion. Finally aggregate will be stored accordingly to each of its entities.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store<T: Aggregate>(
    +    entity: T,
    +    named: AliasKey<T>? = nil,
    +    modifiedAt: Stamp? = nil,
    +    ifPresent update: Update<T>? = nil
    +) -> EntityObserver<T>
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + + + + + + + + + +
    + + entity + + +
    +

    the aggregate to store in the identity map

    +
    +
    + + named + + +
    +

    an alias to reference the aggregate and retrieve it using it

    +
    +
    + + modifiedAt + + +
    +

    if aggregate was already stored it will be used to determine if the update should be applied or discarded

    +
    +
    + + ifPresent + + +
    +

    applies the closure before storing it if it’s already been stored. In this case this is similar as +calling update

    +
    +
    +
    +
    +

    Return Value

    +

    an object to observe changes on the entity

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Store multiple entities at once

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store<C: Collection>(entities: C, named: AliasKey<C>? = nil, modifiedAt: Stamp? = nil)
    +-> EntityObserver<[C.Element]> where C.Element: Identifiable
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    store multiple aggregates at once

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store<C: Collection>(entities: C, named: AliasKey<C>? = nil, modifiedAt: Stamp? = nil)
    +-> EntityObserver<[C.Element]> where C.Element: Aggregate
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + find(_:id:) + +
    +
    +
    +
    +
    +
    +

    Try to find an entity/aggregate in the storage.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func find<T>(_ type: T.Type, id: T.ID) -> EntityObserver<T>? where T : Identifiable
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + type + + +
    +

    the entity type

    +
    +
    + + id + + +
    +

    the entity id

    +
    +
    +
    +
    +

    Return Value

    +

    nil if not found, an EntityObserver` otherwise

    +
    +
    +
    +
  • +
  • +
    + + + + find(named:) + +
    +
    +
    +
    +
    +
    +

    Try to find an entity/aggregate registered under named alias

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func find<T>(named: AliasKey<T>) -> EntityObserver<T?> where T : Identifiable
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + named + + +
    +

    the alias to look for

    +
    +
    +
    +
    +
    +
  • +
  • +
    + + + + find(named:) + +
    +
    +
    +
    +
    +
    +

    Try to find a collected registered under named alias

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func find<C>(named: AliasKey<C>) -> EntityObserver<C?> where C : Collection
    + +
    +
    +
    +

    Return Value

    +

    an observer returning the alias value. Note that the value will be an Array

    +
    +
    +
    +
  • +
+
+
+
+ + +
+ +

Update +

+
+
+
    +
  • + +
    +
    +
    +
    +
    +

    Updates an already stored entity using a closure. Useful to update a few properties or when you assume the entity +should already be stored. +Note: the closure is evaluated before checking modifiedAt. As such the closure execution does not mean +the change was applied

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    @discardableResult
    +public func update<T>(_ type: T.Type, id: T.ID, modifiedAt: Stamp? = nil, update: Update<T>) -> Bool where T : Identifiable
    + +
    +
    +
    +

    Return Value

    +

    true if entity exists and might be updated, false otherwise. The update might not be applied if modifiedAt is too old

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Updates an already stored alias using a closure. This is useful if you don’t have a full entity for update +but just a few attributes/modifications. +Note: the closure is evaluated before checking modifiedAt. As such the closure execution does not mean +the change was applied

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    @discardableResult
    +public func update<T>(_ type: T.Type, id: T.ID, modifiedAt: Stamp? = nil, _ update: Update<T>) -> Bool where T : Aggregate
    + +
    +
    +
    +

    Return Value

    +

    true if entity exists and might be updated, false otherwise. The update might not be applied if modifiedAt is too old

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Updates an already stored alias using a closure. +Note: the closure is evaluated before checking modifiedAt. As such the closure execution does not mean +the change was applied

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    @discardableResult
    +public func update<T>(named: AliasKey<T>, modifiedAt: Stamp? = nil, update: Update<T>) -> Bool where T : Identifiable
    + +
    +
    +
    +

    Return Value

    +

    true if entity exists and might be updated, false otherwise. The update might not be applied if modifiedAt is too old

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Updates an already stored alias using a closure. +Note: the closure is evaluated before checking modifiedAt. As such the closure execution does not mean +the change was applied

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    @discardableResult
    +public func update<T>(named: AliasKey<T>, modifiedAt: Stamp? = nil, update: Update<T>) -> Bool where T : Aggregate
    + +
    +
    +
    +

    Return Value

    +

    true if entity exists and might be updated, false otherwise. The update might not be applied if modifiedAt is too old

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Updates an already existing collection alias content +Note: the closure is evaluated before checking modifiedAt. As such the closure execution does not mean +the change was applied

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    @discardableResult
    +public func update<C: Collection>(named: AliasKey<C>, modifiedAt: Stamp? = nil, update: Update<C>)
    +-> Bool where C.Element: Identifiable
    + +
    +
    +
    +

    Return Value

    +

    true if entity exists and might be updated, false otherwise. The update might not be applied if modifiedAt is too old

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Updates an already existing collection alias content + Note: the closure is evaluated before checking modifiedAt. As such the closure execution does not mean +the change was applied

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    @discardableResult
    +public func update<C: Collection>(named: AliasKey<C>, modifiedAt: Stamp? = nil, update: Update<C>)
    +-> Bool where C.Element: Aggregate
    + +
    +
    +
    +

    Return Value

    +

    true if entity exists and might be updated, false otherwise. The update might not be applied if modifiedAt is too old

    +
    +
    +
    +
  • +
+
+
+
+ + +
+ +

Delete +

+
+
+
    +
  • +
    + + + + removeAlias(named:) + +
    +
    +
    +
    +
    +
    +

    Removes an alias from the storage

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func removeAlias<T>(named: AliasKey<T>)
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + removeAlias(named:) + +
    +
    +
    +
    +
    +
    +

    Removes an alias from the storage

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func removeAlias<C>(named: AliasKey<C>) where C : Collection
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + removeAllAlias() + +
    +
    +
    +
    +
    +
    +

    Removes all alias from identity map

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func removeAllAlias()
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + removeAll() + +
    +
    +
    +
    +
    +
    +

    Removes all alias AND all objects stored weakly. You should not need this method and rather use removeAlias. +But this can be useful if you fear retain cycles

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func removeAll()
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Classes/Subscription.html b/Classes/Subscription.html new file mode 100644 index 0000000..3abec9a --- /dev/null +++ b/Classes/Subscription.html @@ -0,0 +1,165 @@ + + + + Subscription Class Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Subscription

+
+
+ +
public class Subscription
+ +
+
+ +
+
+
+
    +
  • +
    + + + + unsubscribe + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public let unsubscribe: () -> Void
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Enums.html b/Enums.html new file mode 100644 index 0000000..38c8687 --- /dev/null +++ b/Enums.html @@ -0,0 +1,160 @@ + + + + Enumerations Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Enumerations

+

The following enumerations are available globally.

+ +
+
+
+
    +
  • +
    + + + + StampError + +
    +
    +
    +
    +
    +
    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public enum StampError : Error
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Enums/StampError.html b/Enums/StampError.html new file mode 100644 index 0000000..29e31f7 --- /dev/null +++ b/Enums/StampError.html @@ -0,0 +1,166 @@ + + + + StampError Enumeration Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

StampError

+
+
+ +
public enum StampError : Error
+ +
+
+ +
+
+
+
    +
  • + +
    +
    +
    +
    +
    +

    received stamp is smaller than current stamp

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case tooOld(current: Stamp, received: Stamp)
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Extensions.html b/Extensions.html new file mode 100644 index 0000000..cc6b23b --- /dev/null +++ b/Extensions.html @@ -0,0 +1,213 @@ + + + + Extensions Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Extensions

+

The following extensions are available globally.

+ +
+
+
+
    +
  • +
    + + + + Publisher + +
    +
    +
    +
    +
    +
    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    extension Publisher
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + Date + +
    +
    +
    +
    +
    +
    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    extension Date
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + EntityNode + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    extension EntityNode: Hashable
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Extensions/Date.html b/Extensions/Date.html new file mode 100644 index 0000000..b02b25d --- /dev/null +++ b/Extensions/Date.html @@ -0,0 +1,167 @@ + + + + Date Extension Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Date

+
+
+ +
extension Date
+ +
+
+ +
+
+
+
    +
  • +
    + + + + stamp + +
    +
    +
    +
    +
    +
    +

    Generate a stamp suitable to use in IdentityMap. +Don’t suppose it equals unix timestamp (it is not)

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public var stamp: Stamp { get }
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Extensions/Publisher.html b/Extensions/Publisher.html new file mode 100644 index 0000000..2af8e1f --- /dev/null +++ b/Extensions/Publisher.html @@ -0,0 +1,251 @@ + + + + Publisher Extension Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Publisher

+
+
+ +
extension Publisher
+ +
+
+ +
+
+
+
    +
  • + +
    +
    +
    +
    +
    +

    Stores the Identifiable upstream into an identityMap

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store(in identityMap: IdentityMap, named: AliasKey<Output>? = nil, modifiedAt: Stamp = Date().stamp)
    +-> AnyPublisher<Output, Failure> where Output: Identifiable
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Stores the Aggregate upstream into an identityMap

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store(in identityMap: IdentityMap, named: AliasKey<Output>? = nil, modifiedAt: Stamp = Date().stamp)
    +-> AnyPublisher<Output, Failure> where Output: Aggregate
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Stores the upstream collection into an identityMap

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store(in identityMap: IdentityMap, named: AliasKey<Output>? = nil, modifiedAt: Stamp = Date().stamp)
    +-> AnyPublisher<[Output.Element], Failure> where Output: Collection, Output.Element: Identifiable
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Stores the upstream collection into an identityMap

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store(in identityMap: IdentityMap, named: AliasKey<Output>? = nil, modifiedAt: Stamp = Date().stamp)
    +-> AnyPublisher<[Output.Element], Failure> where Output: Collection, Output.Element: Aggregate
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Protocols.html b/Protocols.html new file mode 100644 index 0000000..c0794ff --- /dev/null +++ b/Protocols.html @@ -0,0 +1,247 @@ + + + + Protocols Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Protocols

+

The following protocols are available globally.

+ +
+
+
+
    +
  • +
    + + + + Observer + +
    +
    +
    +
    +
    +
    +

    A protocol allowing to observe a value returned from the IdentityMap

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public protocol Observer
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + Aggregate + +
    +
    +
    +
    +
    +
    +

    An Identifiable model containing nested models

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public protocol Aggregate : Identifiable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + EntityEnumWrapper + +
    +
    +
    +
    +
    +
    +

    a type wrapping one or more Identifiable types. As the name indicates you should use this type only on enums: +this is the easiest way to extract types they are containing. If you facing a non enum case where you feel you need +this type: rethink about it ;)

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public protocol EntityEnumWrapper
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + Logger + +
    +
    +
    +
    +
    +
    +

    a protocol reporting IdentityMap internal information

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public protocol Logger
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Protocols/Aggregate.html b/Protocols/Aggregate.html new file mode 100644 index 0000000..eeb053f --- /dev/null +++ b/Protocols/Aggregate.html @@ -0,0 +1,167 @@ + + + + Aggregate Protocol Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Aggregate

+
+
+ +
public protocol Aggregate : Identifiable
+ +
+
+

An Identifiable model containing nested models

+ +
+
+
+ +
+
+
+ +
+
+ + diff --git a/Protocols/EntityEnumWrapper.html b/Protocols/EntityEnumWrapper.html new file mode 100644 index 0000000..42ddee8 --- /dev/null +++ b/Protocols/EntityEnumWrapper.html @@ -0,0 +1,186 @@ + + + + EntityEnumWrapper Protocol Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

EntityEnumWrapper

+
+
+ +
public protocol EntityEnumWrapper
+ +
+
+

a type wrapping one or more Identifiable types. As the name indicates you should use this type only on enums: +this is the easiest way to extract types they are containing. If you facing a non enum case where you feel you need +this type: rethink about it ;)

+ +
+
+
+
    +
  • + +
    +
    +
    +
    +
    +

    Entities contained by all cases relative to the parent container

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func wrappedEntitiesKeyPaths<Root>(relativeTo parent: WritableKeyPath<Root, Self>) -> [PartialIdentifiableKeyPath<Root>]
    + +
    +
    +
    +

    Return Value

    +

    entities contained in the enum +/ +Example: +/ “`swift +enum MyEnum: EntityEnumWrapper { + case a(A) + case b(B)

    + +

    // you would also need to create computed getter/setter for a and b +func wrappedEntitiesKeyPaths(relativeTo root: WritableKeyPath) -> [PartialIdentifiableKeyPath] { + [.init(root.appending(.a)), .init(root.appending(.b))] +} +}

    +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Protocols/Logger.html b/Protocols/Logger.html new file mode 100644 index 0000000..487aad3 --- /dev/null +++ b/Protocols/Logger.html @@ -0,0 +1,278 @@ + + + + Logger Protocol Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Logger

+
+
+ +
public protocol Logger
+ +
+
+

a protocol reporting IdentityMap internal information

+ +
+
+
+
    +
  • +
    + + + + didStore(_:id:) + +
    +
    +
    +
    +
    +
    +

    Notify when an entity was stored in the identity map

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func didStore<T>(_ type: T.Type, id: T.ID) where T : Identifiable
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + type + + +
    +

    the entity type

    +
    +
    + + id + + +
    +

    id of the stored entity

    +
    +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func didFailedToStore<T>(_ type: T.Type, id: T.ID, error: Error) where T : Identifiable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + didRegisterAlias(_:) + +
    +
    +
    +
    +
    +
    +

    Notify an alias is registered with new entities

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func didRegisterAlias<T>(_ alias: AliasKey<T>)
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Notify an alias is suppressed from the identity map

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func didUnregisterAlias<T>(_ alias: AliasKey<T>)
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Protocols/Observer.html b/Protocols/Observer.html new file mode 100644 index 0000000..ba2e678 --- /dev/null +++ b/Protocols/Observer.html @@ -0,0 +1,276 @@ + + + + Observer Protocol Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Observer

+
+
+ +
public protocol Observer
+ +
+
+

A protocol allowing to observe a value returned from the IdentityMap

+ +
+
+
+
    +
  • +
    + + + + T + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    associatedtype T
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + value + +
    +
    +
    +
    +
    +
    +

    The value at the time the observer creation. +If you want realtime value use `observe to get notified of changes

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    var value: T { get }
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + observe(onChange:) + +
    +
    +
    +
    +
    +
    +

    Add an observer being notified when entity change. +Alternatively you can use asPublisher to observe using Combine.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func observe(onChange: @escaping (T) -> Void) -> Subscription
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + onChange + + +
    +

    a closure called when value changed

    +
    +
    +
    +
    +

    Return Value

    +

    a subscription to cancel observation. Observation is automatically cancelled if subscription is deinit. +As long as the subscription is alived the entity should be kept in IdentityMap.

    +
    +
    +
    +
  • +
  • +
    + + + + asPublisher + + + Extension method + +
    +
    +
    +
    +
    +
    +

    A Publisher emitting the observer current value and subscribing to any subsequents new values

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public var asPublisher: AnyPublisher<T, Never> { get }
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Structs.html b/Structs.html new file mode 100644 index 0000000..c85646e --- /dev/null +++ b/Structs.html @@ -0,0 +1,217 @@ + + + + Structures Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Structures

+

The following structures are available globally.

+ +
+
+
+
    +
  • +
    + + + + AliasKey + +
    +
    +
    +
    +
    +
    +

    A value representing an Entity or set of Entity

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public struct AliasKey<T> : Hashable
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    A KeyPath wrapper allowing only Identifiable/Aggregate keypaths

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public struct PartialIdentifiableKeyPath<Root>
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + EntityObserver + +
    +
    +
    +
    +
    +
    +

    A type registering observers on a given entity from identity storage

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public struct EntityObserver<T> : Observer
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Structs/AliasKey.html b/Structs/AliasKey.html new file mode 100644 index 0000000..beed307 --- /dev/null +++ b/Structs/AliasKey.html @@ -0,0 +1,166 @@ + + + + AliasKey Structure Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

AliasKey

+
+
+ +
public struct AliasKey<T> : Hashable
+ +
+
+

A value representing an Entity or set of Entity

+ +
+
+
+
    +
  • +
    + + + + init(named:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init(named value: String)
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Structs/EntityObserver.html b/Structs/EntityObserver.html new file mode 100644 index 0000000..958e84f --- /dev/null +++ b/Structs/EntityObserver.html @@ -0,0 +1,218 @@ + + + + EntityObserver Structure Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

EntityObserver

+
+
+ +
public struct EntityObserver<T> : Observer
+ +
+
+

A type registering observers on a given entity from identity storage

+ +
+
+
+
    +
  • +
    + + + + OnChange + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public typealias OnChange = (T) -> Void
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + value + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public let value: T
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + observe(onChange:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func observe(onChange: @escaping OnChange) -> Subscription
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Structs/PartialIdentifiableKeyPath.html b/Structs/PartialIdentifiableKeyPath.html new file mode 100644 index 0000000..b7c9ee5 --- /dev/null +++ b/Structs/PartialIdentifiableKeyPath.html @@ -0,0 +1,403 @@ + + + + PartialIdentifiableKeyPath Structure Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

PartialIdentifiableKeyPath

+
+
+ +
public struct PartialIdentifiableKeyPath<Root>
+ +
+
+

A KeyPath wrapper allowing only Identifiable/Aggregate keypaths

+ +
+
+
+
    +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    +

    Creates an instance referencing an Identifiable keyPath

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<T>(_ keyPath: WritableKeyPath<Root, T>) where T : Identifiable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    +

    Creates an instance referencing an Aggregate keyPath

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<T>(_ keyPath: WritableKeyPath<Root, T>) where T : Aggregate
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    +

    Creates an instance referencing an optional Identifiable keyPath

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<T>(_ keyPath: WritableKeyPath<Root, T?>) where T : Identifiable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<T>(_ keyPath: WritableKeyPath<Root, T?>) where T : Aggregate
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<C>(_ keyPath: WritableKeyPath<Root, C>) where C : MutableCollection, C.Element : Identifiable, C.Index : Hashable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<C>(_ keyPath: WritableKeyPath<Root, C?>) where C : MutableCollection, C.Element : Identifiable, C.Index : Hashable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<C>(_ keyPath: WritableKeyPath<Root, C>) where C : MutableCollection, C.Element : Aggregate, C.Index : Hashable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<C>(_ keyPath: WritableKeyPath<Root, C?>) where C : MutableCollection, C.Element : Aggregate, C.Index : Hashable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(wrapper:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<W>(wrapper keyPath: WritableKeyPath<Root, W>) where W : EntityEnumWrapper
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(wrapper:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<W>(wrapper keyPath: WritableKeyPath<Root, W?>) where W : EntityEnumWrapper
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/Typealiases.html b/Typealiases.html new file mode 100644 index 0000000..5c3dd88 --- /dev/null +++ b/Typealiases.html @@ -0,0 +1,161 @@ + + + + Type Aliases Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Type Aliases

+

The following type aliases are available globally.

+ +
+
+
+
    +
  • +
    + + + + Stamp + +
    +
    +
    +
    +
    +
    +

    A type used to annotate track object modifications through time. +Most of the time you’ll just use date as stamp using Date().stamp method

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public typealias Stamp = Double
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/badge.svg b/badge.svg new file mode 100644 index 0000000..a096fec --- /dev/null +++ b/badge.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + documentation + + + documentation + + + 100% + + + 100% + + + diff --git a/css/highlight.css b/css/highlight.css new file mode 100644 index 0000000..c170357 --- /dev/null +++ b/css/highlight.css @@ -0,0 +1,202 @@ +/*! Jazzy - https://github.com/realm/jazzy + * Copyright Realm Inc. + * SPDX-License-Identifier: MIT + */ +/* Credit to https://gist.github.com/wataru420/2048287 */ +.highlight .c { + color: #999988; + font-style: italic; } + +.highlight .err { + color: #a61717; + background-color: #e3d2d2; } + +.highlight .k { + color: #000000; + font-weight: bold; } + +.highlight .o { + color: #000000; + font-weight: bold; } + +.highlight .cm { + color: #999988; + font-style: italic; } + +.highlight .cp { + color: #999999; + font-weight: bold; } + +.highlight .c1 { + color: #999988; + font-style: italic; } + +.highlight .cs { + color: #999999; + font-weight: bold; + font-style: italic; } + +.highlight .gd { + color: #000000; + background-color: #ffdddd; } + +.highlight .gd .x { + color: #000000; + background-color: #ffaaaa; } + +.highlight .ge { + color: #000000; + font-style: italic; } + +.highlight .gr { + color: #aa0000; } + +.highlight .gh { + color: #999999; } + +.highlight .gi { + color: #000000; + background-color: #ddffdd; } + +.highlight .gi .x { + color: #000000; + background-color: #aaffaa; } + +.highlight .go { + color: #888888; } + +.highlight .gp { + color: #555555; } + +.highlight .gs { + font-weight: bold; } + +.highlight .gu { + color: #aaaaaa; } + +.highlight .gt { + color: #aa0000; } + +.highlight .kc { + color: #000000; + font-weight: bold; } + +.highlight .kd { + color: #000000; + font-weight: bold; } + +.highlight .kp { + color: #000000; + font-weight: bold; } + +.highlight .kr { + color: #000000; + font-weight: bold; } + +.highlight .kt { + color: #445588; } + +.highlight .m { + color: #009999; } + +.highlight .s { + color: #d14; } + +.highlight .na { + color: #008080; } + +.highlight .nb { + color: #0086B3; } + +.highlight .nc { + color: #445588; + font-weight: bold; } + +.highlight .no { + color: #008080; } + +.highlight .ni { + color: #800080; } + +.highlight .ne { + color: #990000; + font-weight: bold; } + +.highlight .nf { + color: #990000; } + +.highlight .nn { + color: #555555; } + +.highlight .nt { + color: #000080; } + +.highlight .nv { + color: #008080; } + +.highlight .ow { + color: #000000; + font-weight: bold; } + +.highlight .w { + color: #bbbbbb; } + +.highlight .mf { + color: #009999; } + +.highlight .mh { + color: #009999; } + +.highlight .mi { + color: #009999; } + +.highlight .mo { + color: #009999; } + +.highlight .sb { + color: #d14; } + +.highlight .sc { + color: #d14; } + +.highlight .sd { + color: #d14; } + +.highlight .s2 { + color: #d14; } + +.highlight .se { + color: #d14; } + +.highlight .sh { + color: #d14; } + +.highlight .si { + color: #d14; } + +.highlight .sx { + color: #d14; } + +.highlight .sr { + color: #009926; } + +.highlight .s1 { + color: #d14; } + +.highlight .ss { + color: #990073; } + +.highlight .bp { + color: #999999; } + +.highlight .vc { + color: #008080; } + +.highlight .vg { + color: #008080; } + +.highlight .vi { + color: #008080; } + +.highlight .il { + color: #009999; } diff --git a/css/jazzy.css b/css/jazzy.css new file mode 100644 index 0000000..2e38713 --- /dev/null +++ b/css/jazzy.css @@ -0,0 +1,439 @@ +/*! Jazzy - https://github.com/realm/jazzy + * Copyright Realm Inc. + * SPDX-License-Identifier: MIT + */ +html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { + background: transparent; + border: 0; + margin: 0; + outline: 0; + padding: 0; + vertical-align: baseline; } + +body { + background-color: #f2f2f2; + font-family: Helvetica, freesans, Arial, sans-serif; + font-size: 14px; + -webkit-font-smoothing: subpixel-antialiased; + word-wrap: break-word; } + +h1, h2, h3 { + margin-top: 0.8em; + margin-bottom: 0.3em; + font-weight: 100; + color: black; } + +h1 { + font-size: 2.5em; } + +h2 { + font-size: 2em; + border-bottom: 1px solid #e2e2e2; } + +h4 { + font-size: 13px; + line-height: 1.5; + margin-top: 21px; } + +h5 { + font-size: 1.1em; } + +h6 { + font-size: 1.1em; + color: #777; } + +.section-name { + color: gray; + display: block; + font-family: Helvetica; + font-size: 22px; + font-weight: 100; + margin-bottom: 15px; } + +pre, code { + font: 0.95em Menlo, monospace; + color: #777; + word-wrap: normal; } + +p code, li code { + background-color: #eee; + padding: 2px 4px; + border-radius: 4px; } + +pre > code { + padding: 0; } + +a { + color: #0088cc; + text-decoration: none; } + a code { + color: inherit; } + +ul { + padding-left: 15px; } + +li { + line-height: 1.8em; } + +img { + max-width: 100%; } + +blockquote { + margin-left: 0; + padding: 0 10px; + border-left: 4px solid #ccc; } + +hr { + height: 1px; + border: none; + background-color: #e2e2e2; } + +.footnote-ref { + display: inline-block; + scroll-margin-top: 70px; } + +.footnote-def { + scroll-margin-top: 70px; } + +.content-wrapper { + margin: 0 auto; + width: 980px; } + +header { + font-size: 0.85em; + line-height: 32px; + background-color: #414141; + position: fixed; + width: 100%; + z-index: 3; } + header img { + padding-right: 6px; + vertical-align: -3px; + height: 16px; } + header a { + color: #fff; } + header p { + float: left; + color: #999; } + header .header-right { + float: right; + margin-left: 16px; } + +#breadcrumbs { + background-color: #f2f2f2; + height: 21px; + padding-top: 17px; + position: fixed; + width: 100%; + z-index: 2; + margin-top: 32px; } + #breadcrumbs #carat { + height: 10px; + margin: 0 5px; } + +.sidebar { + background-color: #f9f9f9; + border: 1px solid #e2e2e2; + overflow-y: auto; + overflow-x: hidden; + position: fixed; + top: 70px; + bottom: 0; + width: 230px; + word-wrap: normal; } + +.nav-groups { + list-style-type: none; + background: #fff; + padding-left: 0; } + +.nav-group-name { + border-bottom: 1px solid #e2e2e2; + font-size: 1.1em; + font-weight: 100; + padding: 15px 0 15px 20px; } + .nav-group-name > a { + color: #333; } + +.nav-group-tasks { + margin-top: 5px; } + +.nav-group-task { + font-size: 0.9em; + list-style-type: none; + white-space: nowrap; } + .nav-group-task a { + color: #888; } + +.main-content { + background-color: #fff; + border: 1px solid #e2e2e2; + margin-left: 246px; + position: absolute; + overflow: hidden; + padding-bottom: 20px; + top: 70px; + width: 734px; } + .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { + margin-bottom: 1em; } + .main-content p { + line-height: 1.8em; } + .main-content section .section:first-child { + margin-top: 0; + padding-top: 0; } + .main-content section .task-group-section .task-group:first-of-type { + padding-top: 10px; } + .main-content section .task-group-section .task-group:first-of-type .section-name { + padding-top: 15px; } + .main-content section .heading:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + .main-content .section-name p { + margin-bottom: inherit; + line-height: inherit; } + .main-content .section-name code { + background-color: inherit; + padding: inherit; + color: inherit; } + +.section { + padding: 0 25px; } + +.highlight { + background-color: #eee; + padding: 10px 12px; + border: 1px solid #e2e2e2; + border-radius: 4px; + overflow-x: auto; } + +.declaration .highlight { + overflow-x: initial; + padding: 0 40px 40px 0; + margin-bottom: -25px; + background-color: transparent; + border: none; } + +.section-name { + margin: 0; + margin-left: 18px; } + +.task-group-section { + margin-top: 10px; + padding-left: 6px; + border-top: 1px solid #e2e2e2; } + +.task-group { + padding-top: 0px; } + +.task-name-container a[name]:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + +.section-name-container { + position: relative; + display: inline-block; } + .section-name-container .section-name-link { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin-bottom: 0; } + .section-name-container .section-name { + position: relative; + pointer-events: none; + z-index: 1; } + .section-name-container .section-name a { + pointer-events: auto; } + +.item { + padding-top: 8px; + width: 100%; + list-style-type: none; } + .item a[name]:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + .item code { + background-color: transparent; + padding: 0; } + .item .token, .item .direct-link { + display: inline-block; + text-indent: -20px; + padding-left: 3px; + margin-left: 35px; + font-size: 11.9px; + transition: all 300ms; } + .item .token-open { + margin-left: 20px; } + .item .discouraged { + text-decoration: line-through; } + .item .declaration-note { + font-size: .85em; + color: gray; + font-style: italic; } + +.pointer-container { + border-bottom: 1px solid #e2e2e2; + left: -23px; + padding-bottom: 13px; + position: relative; + width: 110%; } + +.pointer { + background: #f9f9f9; + border-left: 1px solid #e2e2e2; + border-top: 1px solid #e2e2e2; + height: 12px; + left: 21px; + top: -7px; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + position: absolute; + width: 12px; } + +.height-container { + display: none; + left: -25px; + padding: 0 25px; + position: relative; + width: 100%; + overflow: hidden; } + .height-container .section { + background: #f9f9f9; + border-bottom: 1px solid #e2e2e2; + left: -25px; + position: relative; + width: 100%; + padding-top: 10px; + padding-bottom: 5px; } + +.aside, .language { + padding: 6px 12px; + margin: 12px 0; + border-left: 5px solid #dddddd; + overflow-y: hidden; } + .aside .aside-title, .language .aside-title { + font-size: 9px; + letter-spacing: 2px; + text-transform: uppercase; + padding-bottom: 0; + margin: 0; + color: #aaa; + -webkit-user-select: none; } + .aside p:last-child, .language p:last-child { + margin-bottom: 0; } + +.language { + border-left: 5px solid #cde9f4; } + .language .aside-title { + color: #4b8afb; } + +.aside-warning, .aside-deprecated, .aside-unavailable { + border-left: 5px solid #ff6666; } + .aside-warning .aside-title, .aside-deprecated .aside-title, .aside-unavailable .aside-title { + color: #ff0000; } + +.graybox { + border-collapse: collapse; + width: 100%; } + .graybox p { + margin: 0; + word-break: break-word; + min-width: 50px; } + .graybox td { + border: 1px solid #e2e2e2; + padding: 5px 25px 5px 10px; + vertical-align: middle; } + .graybox tr td:first-of-type { + text-align: right; + padding: 7px; + vertical-align: top; + word-break: normal; + width: 40px; } + +.slightly-smaller { + font-size: 0.9em; } + +#footer { + position: relative; + top: 10px; + bottom: 0px; + margin-left: 25px; } + #footer p { + margin: 0; + color: #aaa; + font-size: 0.8em; } + +html.dash header, html.dash #breadcrumbs, html.dash .sidebar { + display: none; } + +html.dash .main-content { + width: 980px; + margin-left: 0; + border: none; + width: 100%; + top: 0; + padding-bottom: 0; } + +html.dash .height-container { + display: block; } + +html.dash .item .token { + margin-left: 0; } + +html.dash .content-wrapper { + width: auto; } + +html.dash #footer { + position: static; } + +form[role=search] { + float: right; } + form[role=search] input { + font: Helvetica, freesans, Arial, sans-serif; + margin-top: 6px; + font-size: 13px; + line-height: 20px; + padding: 0px 10px; + border: none; + border-radius: 1em; } + .loading form[role=search] input { + background: white url(../img/spinner.gif) center right 4px no-repeat; } + form[role=search] .tt-menu { + margin: 0; + min-width: 300px; + background: #fff; + color: #333; + border: 1px solid #e2e2e2; + z-index: 4; } + form[role=search] .tt-highlight { + font-weight: bold; } + form[role=search] .tt-suggestion { + font: Helvetica, freesans, Arial, sans-serif; + font-size: 14px; + padding: 0 8px; } + form[role=search] .tt-suggestion span { + display: table-cell; + white-space: nowrap; } + form[role=search] .tt-suggestion .doc-parent-name { + width: 100%; + text-align: right; + font-weight: normal; + font-size: 0.9em; + padding-left: 16px; } + form[role=search] .tt-suggestion:hover, + form[role=search] .tt-suggestion.tt-cursor { + cursor: pointer; + background-color: #4183c4; + color: #fff; } + form[role=search] .tt-suggestion:hover .doc-parent-name, + form[role=search] .tt-suggestion.tt-cursor .doc-parent-name { + color: #fff; } diff --git a/docsets/.docset/Contents/Info.plist b/docsets/.docset/Contents/Info.plist new file mode 100644 index 0000000..61863ec --- /dev/null +++ b/docsets/.docset/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleIdentifier + com.jazzy. + CFBundleName + + DocSetPlatformFamily + + isDashDocset + + dashIndexFilePath + index.html + isJavaScriptEnabled + + DashDocSetFamily + dashtoc + + diff --git a/docsets/.docset/Contents/Resources/Documents/Classes.html b/docsets/.docset/Contents/Resources/Documents/Classes.html new file mode 100644 index 0000000..a682029 --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Classes.html @@ -0,0 +1,188 @@ + + + + Classes Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Classes

+

The following classes are available globally.

+ +
+
+
+
    +
  • +
    + + + + IdentityMap + +
    +
    +
    +
    +
    +
    +

    Manages entities lifecycle and synchronisation

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public class IdentityMap
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + Subscription + +
    +
    +
    +
    +
    +
    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public class Subscription
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Classes/IdentityMap.html b/docsets/.docset/Contents/Resources/Documents/Classes/IdentityMap.html new file mode 100644 index 0000000..33eb73d --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Classes/IdentityMap.html @@ -0,0 +1,948 @@ + + + + IdentityMap Class Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

IdentityMap

+
+
+ +
public class IdentityMap
+ +
+
+

Manages entities lifecycle and synchronisation

+ +
+
+
+
    +
  • +
    + + + + Update + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public typealias Update<T> = (inout T) -> Void
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(queue:logger:) + +
    +
    +
    +
    +
    +
    +

    Create a new IdentityMap instance optionally with a queue and a logger

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public convenience init(queue: DispatchQueue? = nil, logger: Logger? = nil)
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + queue + + +
    +

    the queue on which to receive updates. If nil identitymap will create its own.

    +
    +
    + + logger + + +
    +

    a logger to follow/debug identity internal state

    +
    +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Store an entity in the storage. Entity will be stored only if stamp (modifiedAt) is higher than in previous +insertion.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store<T: Identifiable>(
    +    entity: T,
    +    named: AliasKey<T>? = nil,
    +    modifiedAt: Stamp? = nil,
    +    ifPresent update: Update<T>? = nil
    +) -> EntityObserver<T>
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + + + + + + + + + +
    + + entity + + +
    +

    the element to store in the identity map

    +
    +
    + + named + + +
    +

    an alias to reference the entity and retrieve it using it

    +
    +
    + + modifiedAt + + +
    +

    if entity was already stored it will be used to determine if the update should be applied or discarded

    +
    +
    + + ifPresent + + +
    +

    applies the closure before storing it if it’s already been stored. In this case this is similar as +calling update

    +
    +
    +
    +
    +

    Return Value

    +

    an object to observe changes on the entity

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Store an aggregate in the storage. Each aggregate entities will be stored only if stamp (modifiedAt) is higher than in previous +insertion. Finally aggregate will be stored accordingly to each of its entities.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store<T: Aggregate>(
    +    entity: T,
    +    named: AliasKey<T>? = nil,
    +    modifiedAt: Stamp? = nil,
    +    ifPresent update: Update<T>? = nil
    +) -> EntityObserver<T>
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + + + + + + + + + +
    + + entity + + +
    +

    the aggregate to store in the identity map

    +
    +
    + + named + + +
    +

    an alias to reference the aggregate and retrieve it using it

    +
    +
    + + modifiedAt + + +
    +

    if aggregate was already stored it will be used to determine if the update should be applied or discarded

    +
    +
    + + ifPresent + + +
    +

    applies the closure before storing it if it’s already been stored. In this case this is similar as +calling update

    +
    +
    +
    +
    +

    Return Value

    +

    an object to observe changes on the entity

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Store multiple entities at once

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store<C: Collection>(entities: C, named: AliasKey<C>? = nil, modifiedAt: Stamp? = nil)
    +-> EntityObserver<[C.Element]> where C.Element: Identifiable
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    store multiple aggregates at once

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store<C: Collection>(entities: C, named: AliasKey<C>? = nil, modifiedAt: Stamp? = nil)
    +-> EntityObserver<[C.Element]> where C.Element: Aggregate
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + find(_:id:) + +
    +
    +
    +
    +
    +
    +

    Try to find an entity/aggregate in the storage.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func find<T>(_ type: T.Type, id: T.ID) -> EntityObserver<T>? where T : Identifiable
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + type + + +
    +

    the entity type

    +
    +
    + + id + + +
    +

    the entity id

    +
    +
    +
    +
    +

    Return Value

    +

    nil if not found, an EntityObserver` otherwise

    +
    +
    +
    +
  • +
  • +
    + + + + find(named:) + +
    +
    +
    +
    +
    +
    +

    Try to find an entity/aggregate registered under named alias

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func find<T>(named: AliasKey<T>) -> EntityObserver<T?> where T : Identifiable
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + named + + +
    +

    the alias to look for

    +
    +
    +
    +
    +
    +
  • +
  • +
    + + + + find(named:) + +
    +
    +
    +
    +
    +
    +

    Try to find a collected registered under named alias

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func find<C>(named: AliasKey<C>) -> EntityObserver<C?> where C : Collection
    + +
    +
    +
    +

    Return Value

    +

    an observer returning the alias value. Note that the value will be an Array

    +
    +
    +
    +
  • +
+
+
+
+ + +
+ +

Update +

+
+
+
    +
  • + +
    +
    +
    +
    +
    +

    Updates an already stored entity using a closure. Useful to update a few properties or when you assume the entity +should already be stored. +Note: the closure is evaluated before checking modifiedAt. As such the closure execution does not mean +the change was applied

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    @discardableResult
    +public func update<T>(_ type: T.Type, id: T.ID, modifiedAt: Stamp? = nil, update: Update<T>) -> Bool where T : Identifiable
    + +
    +
    +
    +

    Return Value

    +

    true if entity exists and might be updated, false otherwise. The update might not be applied if modifiedAt is too old

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Updates an already stored alias using a closure. This is useful if you don’t have a full entity for update +but just a few attributes/modifications. +Note: the closure is evaluated before checking modifiedAt. As such the closure execution does not mean +the change was applied

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    @discardableResult
    +public func update<T>(_ type: T.Type, id: T.ID, modifiedAt: Stamp? = nil, _ update: Update<T>) -> Bool where T : Aggregate
    + +
    +
    +
    +

    Return Value

    +

    true if entity exists and might be updated, false otherwise. The update might not be applied if modifiedAt is too old

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Updates an already stored alias using a closure. +Note: the closure is evaluated before checking modifiedAt. As such the closure execution does not mean +the change was applied

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    @discardableResult
    +public func update<T>(named: AliasKey<T>, modifiedAt: Stamp? = nil, update: Update<T>) -> Bool where T : Identifiable
    + +
    +
    +
    +

    Return Value

    +

    true if entity exists and might be updated, false otherwise. The update might not be applied if modifiedAt is too old

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Updates an already stored alias using a closure. +Note: the closure is evaluated before checking modifiedAt. As such the closure execution does not mean +the change was applied

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    @discardableResult
    +public func update<T>(named: AliasKey<T>, modifiedAt: Stamp? = nil, update: Update<T>) -> Bool where T : Aggregate
    + +
    +
    +
    +

    Return Value

    +

    true if entity exists and might be updated, false otherwise. The update might not be applied if modifiedAt is too old

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Updates an already existing collection alias content +Note: the closure is evaluated before checking modifiedAt. As such the closure execution does not mean +the change was applied

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    @discardableResult
    +public func update<C: Collection>(named: AliasKey<C>, modifiedAt: Stamp? = nil, update: Update<C>)
    +-> Bool where C.Element: Identifiable
    + +
    +
    +
    +

    Return Value

    +

    true if entity exists and might be updated, false otherwise. The update might not be applied if modifiedAt is too old

    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Updates an already existing collection alias content + Note: the closure is evaluated before checking modifiedAt. As such the closure execution does not mean +the change was applied

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    @discardableResult
    +public func update<C: Collection>(named: AliasKey<C>, modifiedAt: Stamp? = nil, update: Update<C>)
    +-> Bool where C.Element: Aggregate
    + +
    +
    +
    +

    Return Value

    +

    true if entity exists and might be updated, false otherwise. The update might not be applied if modifiedAt is too old

    +
    +
    +
    +
  • +
+
+
+
+ + +
+ +

Delete +

+
+
+
    +
  • +
    + + + + removeAlias(named:) + +
    +
    +
    +
    +
    +
    +

    Removes an alias from the storage

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func removeAlias<T>(named: AliasKey<T>)
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + removeAlias(named:) + +
    +
    +
    +
    +
    +
    +

    Removes an alias from the storage

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func removeAlias<C>(named: AliasKey<C>) where C : Collection
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + removeAllAlias() + +
    +
    +
    +
    +
    +
    +

    Removes all alias from identity map

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func removeAllAlias()
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + removeAll() + +
    +
    +
    +
    +
    +
    +

    Removes all alias AND all objects stored weakly. You should not need this method and rather use removeAlias. +But this can be useful if you fear retain cycles

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func removeAll()
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Classes/Subscription.html b/docsets/.docset/Contents/Resources/Documents/Classes/Subscription.html new file mode 100644 index 0000000..3abec9a --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Classes/Subscription.html @@ -0,0 +1,165 @@ + + + + Subscription Class Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Subscription

+
+
+ +
public class Subscription
+ +
+
+ +
+
+
+
    +
  • +
    + + + + unsubscribe + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public let unsubscribe: () -> Void
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Enums.html b/docsets/.docset/Contents/Resources/Documents/Enums.html new file mode 100644 index 0000000..38c8687 --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Enums.html @@ -0,0 +1,160 @@ + + + + Enumerations Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Enumerations

+

The following enumerations are available globally.

+ +
+
+
+
    +
  • +
    + + + + StampError + +
    +
    +
    +
    +
    +
    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public enum StampError : Error
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Enums/StampError.html b/docsets/.docset/Contents/Resources/Documents/Enums/StampError.html new file mode 100644 index 0000000..29e31f7 --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Enums/StampError.html @@ -0,0 +1,166 @@ + + + + StampError Enumeration Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

StampError

+
+
+ +
public enum StampError : Error
+ +
+
+ +
+
+
+
    +
  • + +
    +
    +
    +
    +
    +

    received stamp is smaller than current stamp

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case tooOld(current: Stamp, received: Stamp)
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Extensions.html b/docsets/.docset/Contents/Resources/Documents/Extensions.html new file mode 100644 index 0000000..cc6b23b --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Extensions.html @@ -0,0 +1,213 @@ + + + + Extensions Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Extensions

+

The following extensions are available globally.

+ +
+
+
+
    +
  • +
    + + + + Publisher + +
    +
    +
    +
    +
    +
    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    extension Publisher
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + Date + +
    +
    +
    +
    +
    +
    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    extension Date
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + EntityNode + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    extension EntityNode: Hashable
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Extensions/Date.html b/docsets/.docset/Contents/Resources/Documents/Extensions/Date.html new file mode 100644 index 0000000..b02b25d --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Extensions/Date.html @@ -0,0 +1,167 @@ + + + + Date Extension Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Date

+
+
+ +
extension Date
+ +
+
+ +
+
+
+
    +
  • +
    + + + + stamp + +
    +
    +
    +
    +
    +
    +

    Generate a stamp suitable to use in IdentityMap. +Don’t suppose it equals unix timestamp (it is not)

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public var stamp: Stamp { get }
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Extensions/Publisher.html b/docsets/.docset/Contents/Resources/Documents/Extensions/Publisher.html new file mode 100644 index 0000000..2af8e1f --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Extensions/Publisher.html @@ -0,0 +1,251 @@ + + + + Publisher Extension Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Publisher

+
+
+ +
extension Publisher
+ +
+
+ +
+
+
+
    +
  • + +
    +
    +
    +
    +
    +

    Stores the Identifiable upstream into an identityMap

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store(in identityMap: IdentityMap, named: AliasKey<Output>? = nil, modifiedAt: Stamp = Date().stamp)
    +-> AnyPublisher<Output, Failure> where Output: Identifiable
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Stores the Aggregate upstream into an identityMap

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store(in identityMap: IdentityMap, named: AliasKey<Output>? = nil, modifiedAt: Stamp = Date().stamp)
    +-> AnyPublisher<Output, Failure> where Output: Aggregate
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Stores the upstream collection into an identityMap

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store(in identityMap: IdentityMap, named: AliasKey<Output>? = nil, modifiedAt: Stamp = Date().stamp)
    +-> AnyPublisher<[Output.Element], Failure> where Output: Collection, Output.Element: Identifiable
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Stores the upstream collection into an identityMap

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func store(in identityMap: IdentityMap, named: AliasKey<Output>? = nil, modifiedAt: Stamp = Date().stamp)
    +-> AnyPublisher<[Output.Element], Failure> where Output: Collection, Output.Element: Aggregate
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Protocols.html b/docsets/.docset/Contents/Resources/Documents/Protocols.html new file mode 100644 index 0000000..c0794ff --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Protocols.html @@ -0,0 +1,247 @@ + + + + Protocols Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Protocols

+

The following protocols are available globally.

+ +
+
+
+
    +
  • +
    + + + + Observer + +
    +
    +
    +
    +
    +
    +

    A protocol allowing to observe a value returned from the IdentityMap

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public protocol Observer
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + Aggregate + +
    +
    +
    +
    +
    +
    +

    An Identifiable model containing nested models

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public protocol Aggregate : Identifiable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + EntityEnumWrapper + +
    +
    +
    +
    +
    +
    +

    a type wrapping one or more Identifiable types. As the name indicates you should use this type only on enums: +this is the easiest way to extract types they are containing. If you facing a non enum case where you feel you need +this type: rethink about it ;)

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public protocol EntityEnumWrapper
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + Logger + +
    +
    +
    +
    +
    +
    +

    a protocol reporting IdentityMap internal information

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public protocol Logger
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Protocols/Aggregate.html b/docsets/.docset/Contents/Resources/Documents/Protocols/Aggregate.html new file mode 100644 index 0000000..eeb053f --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Protocols/Aggregate.html @@ -0,0 +1,167 @@ + + + + Aggregate Protocol Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Aggregate

+
+
+ +
public protocol Aggregate : Identifiable
+ +
+
+

An Identifiable model containing nested models

+ +
+
+
+ +
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Protocols/EntityEnumWrapper.html b/docsets/.docset/Contents/Resources/Documents/Protocols/EntityEnumWrapper.html new file mode 100644 index 0000000..42ddee8 --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Protocols/EntityEnumWrapper.html @@ -0,0 +1,186 @@ + + + + EntityEnumWrapper Protocol Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

EntityEnumWrapper

+
+
+ +
public protocol EntityEnumWrapper
+ +
+
+

a type wrapping one or more Identifiable types. As the name indicates you should use this type only on enums: +this is the easiest way to extract types they are containing. If you facing a non enum case where you feel you need +this type: rethink about it ;)

+ +
+
+
+
    +
  • + +
    +
    +
    +
    +
    +

    Entities contained by all cases relative to the parent container

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func wrappedEntitiesKeyPaths<Root>(relativeTo parent: WritableKeyPath<Root, Self>) -> [PartialIdentifiableKeyPath<Root>]
    + +
    +
    +
    +

    Return Value

    +

    entities contained in the enum +/ +Example: +/ “`swift +enum MyEnum: EntityEnumWrapper { + case a(A) + case b(B)

    + +

    // you would also need to create computed getter/setter for a and b +func wrappedEntitiesKeyPaths(relativeTo root: WritableKeyPath) -> [PartialIdentifiableKeyPath] { + [.init(root.appending(.a)), .init(root.appending(.b))] +} +}

    +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Protocols/Logger.html b/docsets/.docset/Contents/Resources/Documents/Protocols/Logger.html new file mode 100644 index 0000000..487aad3 --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Protocols/Logger.html @@ -0,0 +1,278 @@ + + + + Logger Protocol Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Logger

+
+
+ +
public protocol Logger
+ +
+
+

a protocol reporting IdentityMap internal information

+ +
+
+
+
    +
  • +
    + + + + didStore(_:id:) + +
    +
    +
    +
    +
    +
    +

    Notify when an entity was stored in the identity map

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func didStore<T>(_ type: T.Type, id: T.ID) where T : Identifiable
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + type + + +
    +

    the entity type

    +
    +
    + + id + + +
    +

    id of the stored entity

    +
    +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func didFailedToStore<T>(_ type: T.Type, id: T.ID, error: Error) where T : Identifiable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + didRegisterAlias(_:) + +
    +
    +
    +
    +
    +
    +

    Notify an alias is registered with new entities

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func didRegisterAlias<T>(_ alias: AliasKey<T>)
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Notify an alias is suppressed from the identity map

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func didUnregisterAlias<T>(_ alias: AliasKey<T>)
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Protocols/Observer.html b/docsets/.docset/Contents/Resources/Documents/Protocols/Observer.html new file mode 100644 index 0000000..ba2e678 --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Protocols/Observer.html @@ -0,0 +1,276 @@ + + + + Observer Protocol Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Observer

+
+
+ +
public protocol Observer
+ +
+
+

A protocol allowing to observe a value returned from the IdentityMap

+ +
+
+
+
    +
  • +
    + + + + T + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    associatedtype T
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + value + +
    +
    +
    +
    +
    +
    +

    The value at the time the observer creation. +If you want realtime value use `observe to get notified of changes

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    var value: T { get }
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + observe(onChange:) + +
    +
    +
    +
    +
    +
    +

    Add an observer being notified when entity change. +Alternatively you can use asPublisher to observe using Combine.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func observe(onChange: @escaping (T) -> Void) -> Subscription
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + onChange + + +
    +

    a closure called when value changed

    +
    +
    +
    +
    +

    Return Value

    +

    a subscription to cancel observation. Observation is automatically cancelled if subscription is deinit. +As long as the subscription is alived the entity should be kept in IdentityMap.

    +
    +
    +
    +
  • +
  • +
    + + + + asPublisher + + + Extension method + +
    +
    +
    +
    +
    +
    +

    A Publisher emitting the observer current value and subscribing to any subsequents new values

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public var asPublisher: AnyPublisher<T, Never> { get }
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Structs.html b/docsets/.docset/Contents/Resources/Documents/Structs.html new file mode 100644 index 0000000..c85646e --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Structs.html @@ -0,0 +1,217 @@ + + + + Structures Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Structures

+

The following structures are available globally.

+ +
+
+
+
    +
  • +
    + + + + AliasKey + +
    +
    +
    +
    +
    +
    +

    A value representing an Entity or set of Entity

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public struct AliasKey<T> : Hashable
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    A KeyPath wrapper allowing only Identifiable/Aggregate keypaths

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public struct PartialIdentifiableKeyPath<Root>
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + EntityObserver + +
    +
    +
    +
    +
    +
    +

    A type registering observers on a given entity from identity storage

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public struct EntityObserver<T> : Observer
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Structs/AliasKey.html b/docsets/.docset/Contents/Resources/Documents/Structs/AliasKey.html new file mode 100644 index 0000000..beed307 --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Structs/AliasKey.html @@ -0,0 +1,166 @@ + + + + AliasKey Structure Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

AliasKey

+
+
+ +
public struct AliasKey<T> : Hashable
+ +
+
+

A value representing an Entity or set of Entity

+ +
+
+
+
    +
  • +
    + + + + init(named:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init(named value: String)
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Structs/EntityObserver.html b/docsets/.docset/Contents/Resources/Documents/Structs/EntityObserver.html new file mode 100644 index 0000000..958e84f --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Structs/EntityObserver.html @@ -0,0 +1,218 @@ + + + + EntityObserver Structure Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

EntityObserver

+
+
+ +
public struct EntityObserver<T> : Observer
+ +
+
+

A type registering observers on a given entity from identity storage

+ +
+
+
+
    +
  • +
    + + + + OnChange + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public typealias OnChange = (T) -> Void
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + value + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public let value: T
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + observe(onChange:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func observe(onChange: @escaping OnChange) -> Subscription
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Structs/PartialIdentifiableKeyPath.html b/docsets/.docset/Contents/Resources/Documents/Structs/PartialIdentifiableKeyPath.html new file mode 100644 index 0000000..b7c9ee5 --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Structs/PartialIdentifiableKeyPath.html @@ -0,0 +1,403 @@ + + + + PartialIdentifiableKeyPath Structure Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

PartialIdentifiableKeyPath

+
+
+ +
public struct PartialIdentifiableKeyPath<Root>
+ +
+
+

A KeyPath wrapper allowing only Identifiable/Aggregate keypaths

+ +
+
+
+
    +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    +

    Creates an instance referencing an Identifiable keyPath

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<T>(_ keyPath: WritableKeyPath<Root, T>) where T : Identifiable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    +

    Creates an instance referencing an Aggregate keyPath

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<T>(_ keyPath: WritableKeyPath<Root, T>) where T : Aggregate
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    +

    Creates an instance referencing an optional Identifiable keyPath

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<T>(_ keyPath: WritableKeyPath<Root, T?>) where T : Identifiable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<T>(_ keyPath: WritableKeyPath<Root, T?>) where T : Aggregate
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<C>(_ keyPath: WritableKeyPath<Root, C>) where C : MutableCollection, C.Element : Identifiable, C.Index : Hashable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<C>(_ keyPath: WritableKeyPath<Root, C?>) where C : MutableCollection, C.Element : Identifiable, C.Index : Hashable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<C>(_ keyPath: WritableKeyPath<Root, C>) where C : MutableCollection, C.Element : Aggregate, C.Index : Hashable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(_:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<C>(_ keyPath: WritableKeyPath<Root, C?>) where C : MutableCollection, C.Element : Aggregate, C.Index : Hashable
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(wrapper:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<W>(wrapper keyPath: WritableKeyPath<Root, W>) where W : EntityEnumWrapper
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(wrapper:) + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init<W>(wrapper keyPath: WritableKeyPath<Root, W?>) where W : EntityEnumWrapper
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/Typealiases.html b/docsets/.docset/Contents/Resources/Documents/Typealiases.html new file mode 100644 index 0000000..5c3dd88 --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/Typealiases.html @@ -0,0 +1,161 @@ + + + + Type Aliases Reference + + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+

Type Aliases

+

The following type aliases are available globally.

+ +
+
+
+
    +
  • +
    + + + + Stamp + +
    +
    +
    +
    +
    +
    +

    A type used to annotate track object modifications through time. +Most of the time you’ll just use date as stamp using Date().stamp method

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public typealias Stamp = Double
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/css/highlight.css b/docsets/.docset/Contents/Resources/Documents/css/highlight.css new file mode 100644 index 0000000..c170357 --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/css/highlight.css @@ -0,0 +1,202 @@ +/*! Jazzy - https://github.com/realm/jazzy + * Copyright Realm Inc. + * SPDX-License-Identifier: MIT + */ +/* Credit to https://gist.github.com/wataru420/2048287 */ +.highlight .c { + color: #999988; + font-style: italic; } + +.highlight .err { + color: #a61717; + background-color: #e3d2d2; } + +.highlight .k { + color: #000000; + font-weight: bold; } + +.highlight .o { + color: #000000; + font-weight: bold; } + +.highlight .cm { + color: #999988; + font-style: italic; } + +.highlight .cp { + color: #999999; + font-weight: bold; } + +.highlight .c1 { + color: #999988; + font-style: italic; } + +.highlight .cs { + color: #999999; + font-weight: bold; + font-style: italic; } + +.highlight .gd { + color: #000000; + background-color: #ffdddd; } + +.highlight .gd .x { + color: #000000; + background-color: #ffaaaa; } + +.highlight .ge { + color: #000000; + font-style: italic; } + +.highlight .gr { + color: #aa0000; } + +.highlight .gh { + color: #999999; } + +.highlight .gi { + color: #000000; + background-color: #ddffdd; } + +.highlight .gi .x { + color: #000000; + background-color: #aaffaa; } + +.highlight .go { + color: #888888; } + +.highlight .gp { + color: #555555; } + +.highlight .gs { + font-weight: bold; } + +.highlight .gu { + color: #aaaaaa; } + +.highlight .gt { + color: #aa0000; } + +.highlight .kc { + color: #000000; + font-weight: bold; } + +.highlight .kd { + color: #000000; + font-weight: bold; } + +.highlight .kp { + color: #000000; + font-weight: bold; } + +.highlight .kr { + color: #000000; + font-weight: bold; } + +.highlight .kt { + color: #445588; } + +.highlight .m { + color: #009999; } + +.highlight .s { + color: #d14; } + +.highlight .na { + color: #008080; } + +.highlight .nb { + color: #0086B3; } + +.highlight .nc { + color: #445588; + font-weight: bold; } + +.highlight .no { + color: #008080; } + +.highlight .ni { + color: #800080; } + +.highlight .ne { + color: #990000; + font-weight: bold; } + +.highlight .nf { + color: #990000; } + +.highlight .nn { + color: #555555; } + +.highlight .nt { + color: #000080; } + +.highlight .nv { + color: #008080; } + +.highlight .ow { + color: #000000; + font-weight: bold; } + +.highlight .w { + color: #bbbbbb; } + +.highlight .mf { + color: #009999; } + +.highlight .mh { + color: #009999; } + +.highlight .mi { + color: #009999; } + +.highlight .mo { + color: #009999; } + +.highlight .sb { + color: #d14; } + +.highlight .sc { + color: #d14; } + +.highlight .sd { + color: #d14; } + +.highlight .s2 { + color: #d14; } + +.highlight .se { + color: #d14; } + +.highlight .sh { + color: #d14; } + +.highlight .si { + color: #d14; } + +.highlight .sx { + color: #d14; } + +.highlight .sr { + color: #009926; } + +.highlight .s1 { + color: #d14; } + +.highlight .ss { + color: #990073; } + +.highlight .bp { + color: #999999; } + +.highlight .vc { + color: #008080; } + +.highlight .vg { + color: #008080; } + +.highlight .vi { + color: #008080; } + +.highlight .il { + color: #009999; } diff --git a/docsets/.docset/Contents/Resources/Documents/css/jazzy.css b/docsets/.docset/Contents/Resources/Documents/css/jazzy.css new file mode 100644 index 0000000..2e38713 --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/css/jazzy.css @@ -0,0 +1,439 @@ +/*! Jazzy - https://github.com/realm/jazzy + * Copyright Realm Inc. + * SPDX-License-Identifier: MIT + */ +html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { + background: transparent; + border: 0; + margin: 0; + outline: 0; + padding: 0; + vertical-align: baseline; } + +body { + background-color: #f2f2f2; + font-family: Helvetica, freesans, Arial, sans-serif; + font-size: 14px; + -webkit-font-smoothing: subpixel-antialiased; + word-wrap: break-word; } + +h1, h2, h3 { + margin-top: 0.8em; + margin-bottom: 0.3em; + font-weight: 100; + color: black; } + +h1 { + font-size: 2.5em; } + +h2 { + font-size: 2em; + border-bottom: 1px solid #e2e2e2; } + +h4 { + font-size: 13px; + line-height: 1.5; + margin-top: 21px; } + +h5 { + font-size: 1.1em; } + +h6 { + font-size: 1.1em; + color: #777; } + +.section-name { + color: gray; + display: block; + font-family: Helvetica; + font-size: 22px; + font-weight: 100; + margin-bottom: 15px; } + +pre, code { + font: 0.95em Menlo, monospace; + color: #777; + word-wrap: normal; } + +p code, li code { + background-color: #eee; + padding: 2px 4px; + border-radius: 4px; } + +pre > code { + padding: 0; } + +a { + color: #0088cc; + text-decoration: none; } + a code { + color: inherit; } + +ul { + padding-left: 15px; } + +li { + line-height: 1.8em; } + +img { + max-width: 100%; } + +blockquote { + margin-left: 0; + padding: 0 10px; + border-left: 4px solid #ccc; } + +hr { + height: 1px; + border: none; + background-color: #e2e2e2; } + +.footnote-ref { + display: inline-block; + scroll-margin-top: 70px; } + +.footnote-def { + scroll-margin-top: 70px; } + +.content-wrapper { + margin: 0 auto; + width: 980px; } + +header { + font-size: 0.85em; + line-height: 32px; + background-color: #414141; + position: fixed; + width: 100%; + z-index: 3; } + header img { + padding-right: 6px; + vertical-align: -3px; + height: 16px; } + header a { + color: #fff; } + header p { + float: left; + color: #999; } + header .header-right { + float: right; + margin-left: 16px; } + +#breadcrumbs { + background-color: #f2f2f2; + height: 21px; + padding-top: 17px; + position: fixed; + width: 100%; + z-index: 2; + margin-top: 32px; } + #breadcrumbs #carat { + height: 10px; + margin: 0 5px; } + +.sidebar { + background-color: #f9f9f9; + border: 1px solid #e2e2e2; + overflow-y: auto; + overflow-x: hidden; + position: fixed; + top: 70px; + bottom: 0; + width: 230px; + word-wrap: normal; } + +.nav-groups { + list-style-type: none; + background: #fff; + padding-left: 0; } + +.nav-group-name { + border-bottom: 1px solid #e2e2e2; + font-size: 1.1em; + font-weight: 100; + padding: 15px 0 15px 20px; } + .nav-group-name > a { + color: #333; } + +.nav-group-tasks { + margin-top: 5px; } + +.nav-group-task { + font-size: 0.9em; + list-style-type: none; + white-space: nowrap; } + .nav-group-task a { + color: #888; } + +.main-content { + background-color: #fff; + border: 1px solid #e2e2e2; + margin-left: 246px; + position: absolute; + overflow: hidden; + padding-bottom: 20px; + top: 70px; + width: 734px; } + .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { + margin-bottom: 1em; } + .main-content p { + line-height: 1.8em; } + .main-content section .section:first-child { + margin-top: 0; + padding-top: 0; } + .main-content section .task-group-section .task-group:first-of-type { + padding-top: 10px; } + .main-content section .task-group-section .task-group:first-of-type .section-name { + padding-top: 15px; } + .main-content section .heading:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + .main-content .section-name p { + margin-bottom: inherit; + line-height: inherit; } + .main-content .section-name code { + background-color: inherit; + padding: inherit; + color: inherit; } + +.section { + padding: 0 25px; } + +.highlight { + background-color: #eee; + padding: 10px 12px; + border: 1px solid #e2e2e2; + border-radius: 4px; + overflow-x: auto; } + +.declaration .highlight { + overflow-x: initial; + padding: 0 40px 40px 0; + margin-bottom: -25px; + background-color: transparent; + border: none; } + +.section-name { + margin: 0; + margin-left: 18px; } + +.task-group-section { + margin-top: 10px; + padding-left: 6px; + border-top: 1px solid #e2e2e2; } + +.task-group { + padding-top: 0px; } + +.task-name-container a[name]:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + +.section-name-container { + position: relative; + display: inline-block; } + .section-name-container .section-name-link { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin-bottom: 0; } + .section-name-container .section-name { + position: relative; + pointer-events: none; + z-index: 1; } + .section-name-container .section-name a { + pointer-events: auto; } + +.item { + padding-top: 8px; + width: 100%; + list-style-type: none; } + .item a[name]:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + .item code { + background-color: transparent; + padding: 0; } + .item .token, .item .direct-link { + display: inline-block; + text-indent: -20px; + padding-left: 3px; + margin-left: 35px; + font-size: 11.9px; + transition: all 300ms; } + .item .token-open { + margin-left: 20px; } + .item .discouraged { + text-decoration: line-through; } + .item .declaration-note { + font-size: .85em; + color: gray; + font-style: italic; } + +.pointer-container { + border-bottom: 1px solid #e2e2e2; + left: -23px; + padding-bottom: 13px; + position: relative; + width: 110%; } + +.pointer { + background: #f9f9f9; + border-left: 1px solid #e2e2e2; + border-top: 1px solid #e2e2e2; + height: 12px; + left: 21px; + top: -7px; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + position: absolute; + width: 12px; } + +.height-container { + display: none; + left: -25px; + padding: 0 25px; + position: relative; + width: 100%; + overflow: hidden; } + .height-container .section { + background: #f9f9f9; + border-bottom: 1px solid #e2e2e2; + left: -25px; + position: relative; + width: 100%; + padding-top: 10px; + padding-bottom: 5px; } + +.aside, .language { + padding: 6px 12px; + margin: 12px 0; + border-left: 5px solid #dddddd; + overflow-y: hidden; } + .aside .aside-title, .language .aside-title { + font-size: 9px; + letter-spacing: 2px; + text-transform: uppercase; + padding-bottom: 0; + margin: 0; + color: #aaa; + -webkit-user-select: none; } + .aside p:last-child, .language p:last-child { + margin-bottom: 0; } + +.language { + border-left: 5px solid #cde9f4; } + .language .aside-title { + color: #4b8afb; } + +.aside-warning, .aside-deprecated, .aside-unavailable { + border-left: 5px solid #ff6666; } + .aside-warning .aside-title, .aside-deprecated .aside-title, .aside-unavailable .aside-title { + color: #ff0000; } + +.graybox { + border-collapse: collapse; + width: 100%; } + .graybox p { + margin: 0; + word-break: break-word; + min-width: 50px; } + .graybox td { + border: 1px solid #e2e2e2; + padding: 5px 25px 5px 10px; + vertical-align: middle; } + .graybox tr td:first-of-type { + text-align: right; + padding: 7px; + vertical-align: top; + word-break: normal; + width: 40px; } + +.slightly-smaller { + font-size: 0.9em; } + +#footer { + position: relative; + top: 10px; + bottom: 0px; + margin-left: 25px; } + #footer p { + margin: 0; + color: #aaa; + font-size: 0.8em; } + +html.dash header, html.dash #breadcrumbs, html.dash .sidebar { + display: none; } + +html.dash .main-content { + width: 980px; + margin-left: 0; + border: none; + width: 100%; + top: 0; + padding-bottom: 0; } + +html.dash .height-container { + display: block; } + +html.dash .item .token { + margin-left: 0; } + +html.dash .content-wrapper { + width: auto; } + +html.dash #footer { + position: static; } + +form[role=search] { + float: right; } + form[role=search] input { + font: Helvetica, freesans, Arial, sans-serif; + margin-top: 6px; + font-size: 13px; + line-height: 20px; + padding: 0px 10px; + border: none; + border-radius: 1em; } + .loading form[role=search] input { + background: white url(../img/spinner.gif) center right 4px no-repeat; } + form[role=search] .tt-menu { + margin: 0; + min-width: 300px; + background: #fff; + color: #333; + border: 1px solid #e2e2e2; + z-index: 4; } + form[role=search] .tt-highlight { + font-weight: bold; } + form[role=search] .tt-suggestion { + font: Helvetica, freesans, Arial, sans-serif; + font-size: 14px; + padding: 0 8px; } + form[role=search] .tt-suggestion span { + display: table-cell; + white-space: nowrap; } + form[role=search] .tt-suggestion .doc-parent-name { + width: 100%; + text-align: right; + font-weight: normal; + font-size: 0.9em; + padding-left: 16px; } + form[role=search] .tt-suggestion:hover, + form[role=search] .tt-suggestion.tt-cursor { + cursor: pointer; + background-color: #4183c4; + color: #fff; } + form[role=search] .tt-suggestion:hover .doc-parent-name, + form[role=search] .tt-suggestion.tt-cursor .doc-parent-name { + color: #fff; } diff --git a/docsets/.docset/Contents/Resources/Documents/img/carat.png b/docsets/.docset/Contents/Resources/Documents/img/carat.png new file mode 100755 index 0000000000000000000000000000000000000000..29d2f7fd4955fca6bc6fb740e0373a2c358c398e GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRo!3HEV4DF?Wlw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6JlqAi{-jv*Ddl5#RKJQ5NTUZgiPI4RUKGIKU?u8L&ndhX1t za+0CMVUnT(Gnb}ei=c~x==tMH^F1_tBocXwcoSWoO-SZY-o>!8%^=Bms)(~h;m_U( zXNixk28L}0LS5-jKyq@#2gyS|J&f#pGCLkTc<@2s1dqeyqJ*Rc0tSIETAgmODY;(s z2y|Mcp&2}7rpBprBBB~1qM1`N+}4SoxYVPqsXi&l`rxZp{(w0iSy$Nv5*Vy!RapG^ S^0y4=eg;ohKbLh*2~7a!Pg}VF literal 0 HcmV?d00001 diff --git a/docsets/.docset/Contents/Resources/Documents/img/dash.png b/docsets/.docset/Contents/Resources/Documents/img/dash.png new file mode 100755 index 0000000000000000000000000000000000000000..6f694c7a012b417908da3687a0a39aa182e91c74 GIT binary patch literal 1338 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 literal 0 HcmV?d00001 diff --git a/docsets/.docset/Contents/Resources/Documents/index.html b/docsets/.docset/Contents/Resources/Documents/index.html new file mode 100644 index 0000000..d27177b --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/index.html @@ -0,0 +1,403 @@ + + + + Reference + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+ +

CohesionKit - Single Source of Truth

+ +

+ swift + platforms + test + + twitter + +

+ +

Keep your models synchronized in your app and never have any inconsistency anymore. Designed using latest Swift features.

+

Why using CohesionKit?

+ +
    +
  • 🔁 You need realtime synchronisation (websockets)
  • +
  • 🌐 You have multiple data sources (REST, CoreData, websocket, phone Contacts, Google Maps, etc…)
  • +
  • 🪶 You look for a full Swift lightweight tool
  • +
  • 🗃️ You want to use structs
  • +
+

Features

+ +
    +
  • [x] 🦺 Thread safe
  • +
  • [x] 🪶 Lighweight (< 600 lines of code)
  • +
  • [x] 🪪 Working with plain Swift struct and Identifiable objects
  • +
  • [x] 🔀 Support for Combine
  • +
  • [x] 🧠 In-memory storage
  • +
  • [x] 🐾 Low memory footprint
  • +
  • [x] 🐪 Strongly typed
  • +
+

Where to put CohesionKit in my stack?

+ +

CohesionKit being a Single Source of Truth solution it handles your objects lifecycle and synchronization from any source.

+ +

You should put CohesionKit in front of your data sources (REST API, GraphQL, …) before returning data to your app.

+
sequenceDiagram
+    autonumber
+
+        YourApp ->>DataSource: findBooks
+        DataSource ->>GraphQL: query findBooks
+        GraphQL -->>DataSource: FindBooksQueryResult
+        DataSource ->>CohesionKit: store books [A,B,C]
+        CohesionKit -->> YourApp: Publisher<[A,B,C]>
+
+        WebSocket ->> WebSocketListener: book A updated
+        WebSocketListener ->> CohesionKit: update book A
+        CohesionKit -->> YourApp: Publisher<[A,B,C]>
+
+

Installation

+ +
    +
  • Swift Package Manager
  • +
+
dependencies: [
+    .package(url: "https://github.com/pjechris/CohesionKit.git", .upToNextMajor(from: "0.7.0"))
+]
+
+

Examples

+ +

Library comes with an example project so you can see a real case usage. It mostly shows:

+ +
    +
  • How to store data in the library
  • +
  • How to retrieve and update that data for realtime
  • +
  • How data is synchronised throughout multiple screens
  • +
+

Getting started

+

Storing an object

+ +

First create an instance of IdentityMap:

+
let identityMap = IdentityMap()
+
+ +

IdentityMap let you store Identifiable objects:

+
struct Book: Identifiable {
+  let id: String
+  let title: String
+}
+
+let book = Book(id: "ABCD", name: "My Book")
+
+identityMap.store(book)
+
+ +

Then You can retrieve the object from anywhere in your code:

+
// somewhere else in the code
+identityMap.find(Book.self, id: "ABCD") // return Book(id: "ABCD", name: "My Book")
+
+

Observing changes

+ +

Every time data is updated in IdentityMap triggers a notification to any registered observer. To register yourself as an observer just use result from store or find methods:

+
func findBooks() -> some Publisher<[Book], Error> {
+  // 1. load data using URLSession
+  URLSession(...)
+  // 2. store data inside our identityMap
+    .store(in: identityMap)
+    .sink { ... }
+    .store(in: &cancellables)
+}
+
+
identityMap.find(Book.self, id: 1)?
+  .asPublisher
+  .sink { ... }
+  .store(in: &cancellables)
+
+ +
+

CohesionKit has a weak memory policy you should read about. As such, returned value from identityMap.store must be strongly retained to not lose value.

+ +

For brievety, next examples will omit .sink { ... }.store(in:&cancellables).

+
+

Relational objects

+ +

To store objects containing nested identity objects you need to make them conform to one protocol: Aggregate.

+
struct AuthorBooks: Aggregate {
+  var id: Author.ID { author.id }
+
+  var author: Author
+  var books: [Book]
+
+  // `nestedEntitiesKeyPaths` must list all Identifiable/Aggregate this object contain
+  var nestedEntitiesKeyPaths: [PartialIdentifiableKeyPath<Self>] {
+    [.init(\.author), .init(\.books)]
+  }
+}
+
+ +

CohesionKit then handles synchronisation for the three entities:

+ +
    +
  • AuthorBook
  • +
+

Author

+ Author + +
    +
  • Book
  • +
+ +

This gives you the ability to retrieve them independently from each other:

+
let authorBooks = AuthorBooks(
+    author: Author(id: 1, name: "George R.R Martin"),
+    books: [
+      Book(id: "ACK", title: "A Clash of Kings"),
+      Book(id: "ADD", title: "A Dance with Dragons")
+    ]
+)
+
+identityMap.store(authorBooks)
+
+identityMap.find(Author.self, id: 1) // George R.R Martin
+identityMap.find(Book.self, id: "ACK") // A Clash of Kings
+identityMap.find(Book.self, id: "ADD") // A Dance with Dragons
+
+ +

You can also modify any of them however you want. Notice the change is visible from the object itself AND from aggregate objects:

+
let newAuthor = Author(id: 1, name: "George R.R MartinI")
+
+identityMap.store(newAuthor)
+
+identityMap.find(Author.self, id: 1) // George R.R MartinI
+identityMap.find(AuthorBooks.self, id: 1) // George R.R MartinI + [A Clash of Kings, A Dance with Dragons]
+
+ +
+

You might think about storing books on Author directly (author.books). In this case Author needs to implement Aggregate and declare books as nested entity.

+ +

However I strongly advise you to not nest Identifiable objects into other Identifiable objects. Read Handling relationships article if you want to know more about this subject.

+
+

Storing vs Updating

+ +

For now we only focused on identityMap.store but CohesionKit comes with another method to store data: identityMap.update.

+ +

Sometimes both can be used but they each have a different purpose:

+ +
    +
  1. store is suited for storing full data retrieved from webservices, like GET /user for instance
  2. +
  3. update is usually used for partial data. It’s also the preferred method when receiving events from websockets.
  4. +
+

Advanced topics

+

Enum support

+ +

Starting with 0.13 library has support for enum types. Note that you’ll need to conform to EntityEnumWrapper and provide computed getter/setter for each entity you’d like to store.

+
enum MediaType: EntityEnumWrapper {
+  case book(Book)
+  case game(Game)
+  case tvShow(TvShow)
+
+  func wrappedEntitiesKeyPaths<Root>(relativeTo parent: WritableKeyPath<Root, Self>) -> [PartialIdentifiableKeyPath<Root>] {
+    [.init(parent.appending(\.book)), .init(parent.appending(\.game)), .init(parent.appending(\.tvShow))]
+  }
+
+  var book: Book? {
+    get { ... }
+    set { ... }
+  }
+
+  var game: Game? {
+    get { ... }
+    set { ... }
+  }
+
+  var tvShow: TvShow? {
+    get { ... }
+    set { ... }
+  }
+}
+
+struct AuthorMedia: Aggregate {
+  var author: Author
+  var media: MediaType
+
+  var nestedEntitiesKeyPaths: [PartialIdentifiableKeyPath<Self>] {
+    [.init(\.author), .init(wrapper: \.media)]
+  }
+}
+
+

Aliases

+ +

Sometimes you need to retrieve data without knowing the object id. Common case is current user.

+ +

CohesionKit provides a suitable mechanism: aliases. Aliases allow you to register and find entities using a key.

+
extension AliasKey where T == User {
+  static let currentUser = AliasKey("user")
+}
+
+identityMap.store(currentUser, named: .currentUser)
+
+ +

Then request it somewhere else:

+
identityMap.find(named: .currentUser) // return the current user
+
+ +

Compared to regular entities, aliased objects are long-live objects: they will be kept in the storage even if no one observes them. This allow registered observers to be notified when alias value change:

+
identityMap.removeAlias(named: .currentUser) // observers will be notified currentUser is nil.
+
+identityMap.store(newCurrentUser, named: .currentUser) // observers will be notified that currentUser changed even if currentUser was nil before
+
+

Stale data

+ +

When storing data CohesionKit actually require you to set a modification stamp on it. Stamp is used as a marker to compare data freshness: the higher stamp is the more recent data is.

+ +

By default CohesionKit will use the current date as stamp.

+
identityMap.store(book) // use default stamp: current date
+identityMap.store(book, modifiedAt: Date().stamp) // explicitly use Date time stamp
+identityMap.store(book, modifiedAt: 9000) // any Double value is valid
+
+ +

If for some reason you try to store data with a stamp lower than the already stamped stored data then the update will be discarded.

+

Weak memory management

+ +

CohesionKit has a weak memory policy: objects are kept in IdentityMap as long as someone use them.

+ +

To that end you need to retain observers as long as you’re interested in the data:

+
let book = Book(id: "ACK", title: "A Clash of Kings")
+let cancellable = identityMap.store(book) // observer is retained: data is retained
+
+identityMap.find(Book.self, id: "ACK") // return  "A Clash of Kings"
+
+ +

If you don’t create/retain observers then once entities have no more observers they will be automatically discarded from the storage.

+
let book = Book(id: "ACK", title: "A Clash of Kings")
+_ = identityMap.store(book) // observer is not retained and no one else observe this book: data is released
+
+identityMap.find(Book.self, id: "ACK") // return nil
+
+
let book = Book(id: "ACK", title: "A Clash of Kings")
+var cancellable = identityMap.store(book).asPublisher.sink { ... }
+let cancellable2 = identityMap.find(Book.self, id: "ACK") // return a publisher
+
+cancellable = nil
+
+identityMap.find(Book.self, id: "ACK") // return "A Clash of Kings" because cancellable2 still observe this book
+
+

License

+ +

This project is released under the MIT License. Please see the LICENSE file for details.

+ +
+
+ +
+
+ + diff --git a/docsets/.docset/Contents/Resources/Documents/js/jazzy.js b/docsets/.docset/Contents/Resources/Documents/js/jazzy.js new file mode 100755 index 0000000..1984416 --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/js/jazzy.js @@ -0,0 +1,74 @@ +// Jazzy - https://github.com/realm/jazzy +// Copyright Realm Inc. +// SPDX-License-Identifier: MIT + +window.jazzy = {'docset': false} +if (typeof window.dash != 'undefined') { + document.documentElement.className += ' dash' + window.jazzy.docset = true +} +if (navigator.userAgent.match(/xcode/i)) { + document.documentElement.className += ' xcode' + window.jazzy.docset = true +} + +function toggleItem($link, $content) { + var animationDuration = 300; + $link.toggleClass('token-open'); + $content.slideToggle(animationDuration); +} + +function itemLinkToContent($link) { + return $link.parent().parent().next(); +} + +// On doc load + hash-change, open any targetted item +function openCurrentItemIfClosed() { + if (window.jazzy.docset) { + return; + } + var $link = $(`a[name="${location.hash.substring(1)}"]`).nextAll('.token'); + $content = itemLinkToContent($link); + if ($content.is(':hidden')) { + toggleItem($link, $content); + } +} + +$(openCurrentItemIfClosed); +$(window).on('hashchange', openCurrentItemIfClosed); + +// On item link ('token') click, toggle its discussion +$('.token').on('click', function(event) { + if (window.jazzy.docset) { + return; + } + var $link = $(this); + toggleItem($link, itemLinkToContent($link)); + + // Keeps the document from jumping to the hash. + var href = $link.attr('href'); + if (history.pushState) { + history.pushState({}, '', href); + } else { + location.hash = href; + } + event.preventDefault(); +}); + +// Clicks on links to the current, closed, item need to open the item +$("a:not('.token')").on('click', function() { + if (location == this.href) { + openCurrentItemIfClosed(); + } +}); + +// KaTeX rendering +if ("katex" in window) { + $($('.math').each( (_, element) => { + katex.render(element.textContent, element, { + displayMode: $(element).hasClass('m-block'), + throwOnError: false, + trust: true + }); + })) +} diff --git a/docsets/.docset/Contents/Resources/Documents/js/jazzy.search.js b/docsets/.docset/Contents/Resources/Documents/js/jazzy.search.js new file mode 100644 index 0000000..359cdbb --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/js/jazzy.search.js @@ -0,0 +1,74 @@ +// Jazzy - https://github.com/realm/jazzy +// Copyright Realm Inc. +// SPDX-License-Identifier: MIT + +$(function(){ + var $typeahead = $('[data-typeahead]'); + var $form = $typeahead.parents('form'); + var searchURL = $form.attr('action'); + + function displayTemplate(result) { + return result.name; + } + + function suggestionTemplate(result) { + var t = '
'; + t += '' + result.name + ''; + if (result.parent_name) { + t += '' + result.parent_name + ''; + } + t += '
'; + return t; + } + + $typeahead.one('focus', function() { + $form.addClass('loading'); + + $.getJSON(searchURL).then(function(searchData) { + const searchIndex = lunr(function() { + this.ref('url'); + this.field('name'); + this.field('abstract'); + for (const [url, doc] of Object.entries(searchData)) { + this.add({url: url, name: doc.name, abstract: doc.abstract}); + } + }); + + $typeahead.typeahead( + { + highlight: true, + minLength: 3, + autoselect: true + }, + { + limit: 10, + display: displayTemplate, + templates: { suggestion: suggestionTemplate }, + source: function(query, sync) { + const lcSearch = query.toLowerCase(); + const results = searchIndex.query(function(q) { + q.term(lcSearch, { boost: 100 }); + q.term(lcSearch, { + boost: 10, + wildcard: lunr.Query.wildcard.TRAILING + }); + }).map(function(result) { + var doc = searchData[result.ref]; + doc.url = result.ref; + return doc; + }); + sync(results); + } + } + ); + $form.removeClass('loading'); + $typeahead.trigger('focus'); + }); + }); + + var baseURL = searchURL.slice(0, -"search.json".length); + + $typeahead.on('typeahead:select', function(e, result) { + window.location = baseURL + result.url; + }); +}); diff --git a/docsets/.docset/Contents/Resources/Documents/js/jquery.min.js b/docsets/.docset/Contents/Resources/Documents/js/jquery.min.js new file mode 100644 index 0000000..7f37b5d --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/js/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 00){var c=e.utils.clone(r)||{};c.position=[a,l],c.index=s.length,s.push(new e.Token(i.slice(a,o),c))}a=o+1}}return s},e.tokenizer.separator=/[\s\-]+/,e.Pipeline=function(){this._stack=[]},e.Pipeline.registeredFunctions=Object.create(null),e.Pipeline.registerFunction=function(t,r){r in this.registeredFunctions&&e.utils.warn("Overwriting existing registered function: "+r),t.label=r,e.Pipeline.registeredFunctions[t.label]=t},e.Pipeline.warnIfFunctionNotRegistered=function(t){var r=t.label&&t.label in this.registeredFunctions;r||e.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",t)},e.Pipeline.load=function(t){var r=new e.Pipeline;return t.forEach(function(t){var i=e.Pipeline.registeredFunctions[t];if(!i)throw new Error("Cannot load unregistered function: "+t);r.add(i)}),r},e.Pipeline.prototype.add=function(){var t=Array.prototype.slice.call(arguments);t.forEach(function(t){e.Pipeline.warnIfFunctionNotRegistered(t),this._stack.push(t)},this)},e.Pipeline.prototype.after=function(t,r){e.Pipeline.warnIfFunctionNotRegistered(r);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,r)},e.Pipeline.prototype.before=function(t,r){e.Pipeline.warnIfFunctionNotRegistered(r);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");this._stack.splice(i,0,r)},e.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);t!=-1&&this._stack.splice(t,1)},e.Pipeline.prototype.run=function(e){for(var t=this._stack.length,r=0;r1&&(se&&(r=n),s!=e);)i=r-t,n=t+Math.floor(i/2),s=this.elements[2*n];return s==e?2*n:s>e?2*n:sa?l+=2:o==a&&(t+=r[u+1]*i[l+1],u+=2,l+=2);return t},e.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},e.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,r=0;t0){var o,a=s.str.charAt(0);a in s.node.edges?o=s.node.edges[a]:(o=new e.TokenSet,s.node.edges[a]=o),1==s.str.length&&(o["final"]=!0),n.push({node:o,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(0!=s.editsRemaining){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new e.TokenSet;s.node.edges["*"]=u}if(0==s.str.length&&(u["final"]=!0),n.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&n.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),1==s.str.length&&(s.node["final"]=!0),s.str.length>=1){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new e.TokenSet;s.node.edges["*"]=l}1==s.str.length&&(l["final"]=!0),n.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var c,h=s.str.charAt(0),d=s.str.charAt(1);d in s.node.edges?c=s.node.edges[d]:(c=new e.TokenSet,s.node.edges[d]=c),1==s.str.length&&(c["final"]=!0),n.push({node:c,editsRemaining:s.editsRemaining-1,str:h+s.str.slice(2)})}}}return i},e.TokenSet.fromString=function(t){for(var r=new e.TokenSet,i=r,n=0,s=t.length;n=e;t--){var r=this.uncheckedNodes[t],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r["char"]]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}},e.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},e.Index.prototype.search=function(t){return this.query(function(r){var i=new e.QueryParser(t,r);i.parse()})},e.Index.prototype.query=function(t){for(var r=new e.Query(this.fields),i=Object.create(null),n=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u1?this._b=1:this._b=e},e.Builder.prototype.k1=function(e){this._k1=e},e.Builder.prototype.add=function(t,r){var i=t[this._ref],n=Object.keys(this._fields);this._documents[i]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return e.QueryLexer.EOS;var t=this.str.charAt(this.pos);return this.pos+=1,t},e.QueryLexer.prototype.width=function(){return this.pos-this.start},e.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},e.QueryLexer.prototype.backup=function(){this.pos-=1},e.QueryLexer.prototype.acceptDigitRun=function(){var t,r;do t=this.next(),r=t.charCodeAt(0);while(r>47&&r<58);t!=e.QueryLexer.EOS&&this.backup()},e.QueryLexer.prototype.more=function(){return this.pos1&&(t.backup(),t.emit(e.QueryLexer.TERM)),t.ignore(),t.more())return e.QueryLexer.lexText},e.QueryLexer.lexEditDistance=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.EDIT_DISTANCE),e.QueryLexer.lexText},e.QueryLexer.lexBoost=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.BOOST),e.QueryLexer.lexText},e.QueryLexer.lexEOS=function(t){t.width()>0&&t.emit(e.QueryLexer.TERM)},e.QueryLexer.termSeparator=e.tokenizer.separator,e.QueryLexer.lexText=function(t){for(;;){var r=t.next();if(r==e.QueryLexer.EOS)return e.QueryLexer.lexEOS;if(92!=r.charCodeAt(0)){if(":"==r)return e.QueryLexer.lexField;if("~"==r)return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexEditDistance;if("^"==r)return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexBoost;if("+"==r&&1===t.width())return t.emit(e.QueryLexer.PRESENCE),e.QueryLexer.lexText;if("-"==r&&1===t.width())return t.emit(e.QueryLexer.PRESENCE),e.QueryLexer.lexText;if(r.match(e.QueryLexer.termSeparator))return e.QueryLexer.lexTerm}else t.escapeCharacter()}},e.QueryParser=function(t,r){this.lexer=new e.QueryLexer(t),this.query=r,this.currentClause={},this.lexemeIdx=0},e.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var t=e.QueryParser.parseClause;t;)t=t(this);return this.query},e.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},e.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},e.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},e.QueryParser.parseClause=function(t){var r=t.peekLexeme();if(void 0!=r)switch(r.type){case e.QueryLexer.PRESENCE:return e.QueryParser.parsePresence;case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(i+=" with value '"+r.str+"'"),new e.QueryParseError(i,r.start,r.end)}},e.QueryParser.parsePresence=function(t){var r=t.consumeLexeme();if(void 0!=r){switch(r.str){case"-":t.currentClause.presence=e.Query.presence.PROHIBITED;break;case"+":t.currentClause.presence=e.Query.presence.REQUIRED;break;default:var i="unrecognised presence operator'"+r.str+"'";throw new e.QueryParseError(i,r.start,r.end)}var n=t.peekLexeme();if(void 0==n){var i="expecting term or field, found nothing";throw new e.QueryParseError(i,r.start,r.end)}switch(n.type){case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expecting term or field, found '"+n.type+"'";throw new e.QueryParseError(i,n.start,n.end)}}},e.QueryParser.parseField=function(t){var r=t.consumeLexeme();if(void 0!=r){if(t.query.allFields.indexOf(r.str)==-1){var i=t.query.allFields.map(function(e){return"'"+e+"'"}).join(", "),n="unrecognised field '"+r.str+"', possible fields: "+i;throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.fields=[r.str];var s=t.peekLexeme();if(void 0==s){var n="expecting term, found nothing";throw new e.QueryParseError(n,r.start,r.end)}switch(s.type){case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var n="expecting term, found '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},e.QueryParser.parseTerm=function(t){var r=t.consumeLexeme();if(void 0!=r){t.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(t.currentClause.usePipeline=!1);var i=t.peekLexeme();if(void 0==i)return void t.nextClause();switch(i.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+i.type+"'";throw new e.QueryParseError(n,i.start,i.end)}}},e.QueryParser.parseEditDistance=function(t){var r=t.consumeLexeme();if(void 0!=r){var i=parseInt(r.str,10);if(isNaN(i)){var n="edit distance must be numeric";throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.editDistance=i;var s=t.peekLexeme();if(void 0==s)return void t.nextClause();switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},e.QueryParser.parseBoost=function(t){var r=t.consumeLexeme();if(void 0!=r){var i=parseInt(r.str,10);if(isNaN(i)){var n="boost must be numeric";throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.boost=i;var s=t.peekLexeme();if(void 0==s)return void t.nextClause();switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():e.lunr=t()}(this,function(){return e})}(); diff --git a/docsets/.docset/Contents/Resources/Documents/js/typeahead.jquery.js b/docsets/.docset/Contents/Resources/Documents/js/typeahead.jquery.js new file mode 100644 index 0000000..3a2d2ab --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/js/typeahead.jquery.js @@ -0,0 +1,1694 @@ +/*! + * typeahead.js 1.3.1 + * https://github.com/corejavascript/typeahead.js + * Copyright 2013-2020 Twitter, Inc. and other contributors; Licensed MIT + */ + + +(function(root, factory) { + if (typeof define === "function" && define.amd) { + define([ "jquery" ], function(a0) { + return factory(a0); + }); + } else if (typeof module === "object" && module.exports) { + module.exports = factory(require("jquery")); + } else { + factory(root["jQuery"]); + } +})(this, function($) { + var _ = function() { + "use strict"; + return { + isMsie: function() { + return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false; + }, + isBlankString: function(str) { + return !str || /^\s*$/.test(str); + }, + escapeRegExChars: function(str) { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + }, + isString: function(obj) { + return typeof obj === "string"; + }, + isNumber: function(obj) { + return typeof obj === "number"; + }, + isArray: $.isArray, + isFunction: $.isFunction, + isObject: $.isPlainObject, + isUndefined: function(obj) { + return typeof obj === "undefined"; + }, + isElement: function(obj) { + return !!(obj && obj.nodeType === 1); + }, + isJQuery: function(obj) { + return obj instanceof $; + }, + toStr: function toStr(s) { + return _.isUndefined(s) || s === null ? "" : s + ""; + }, + bind: $.proxy, + each: function(collection, cb) { + $.each(collection, reverseArgs); + function reverseArgs(index, value) { + return cb(value, index); + } + }, + map: $.map, + filter: $.grep, + every: function(obj, test) { + var result = true; + if (!obj) { + return result; + } + $.each(obj, function(key, val) { + if (!(result = test.call(null, val, key, obj))) { + return false; + } + }); + return !!result; + }, + some: function(obj, test) { + var result = false; + if (!obj) { + return result; + } + $.each(obj, function(key, val) { + if (result = test.call(null, val, key, obj)) { + return false; + } + }); + return !!result; + }, + mixin: $.extend, + identity: function(x) { + return x; + }, + clone: function(obj) { + return $.extend(true, {}, obj); + }, + getIdGenerator: function() { + var counter = 0; + return function() { + return counter++; + }; + }, + templatify: function templatify(obj) { + return $.isFunction(obj) ? obj : template; + function template() { + return String(obj); + } + }, + defer: function(fn) { + setTimeout(fn, 0); + }, + debounce: function(func, wait, immediate) { + var timeout, result; + return function() { + var context = this, args = arguments, later, callNow; + later = function() { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + } + }; + callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + } + return result; + }; + }, + throttle: function(func, wait) { + var context, args, timeout, result, previous, later; + previous = 0; + later = function() { + previous = new Date(); + timeout = null; + result = func.apply(context, args); + }; + return function() { + var now = new Date(), remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + } else if (!timeout) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }, + stringify: function(val) { + return _.isString(val) ? val : JSON.stringify(val); + }, + guid: function() { + function _p8(s) { + var p = (Math.random().toString(16) + "000000000").substr(2, 8); + return s ? "-" + p.substr(0, 4) + "-" + p.substr(4, 4) : p; + } + return "tt-" + _p8() + _p8(true) + _p8(true) + _p8(); + }, + noop: function() {} + }; + }(); + var WWW = function() { + "use strict"; + var defaultClassNames = { + wrapper: "twitter-typeahead", + input: "tt-input", + hint: "tt-hint", + menu: "tt-menu", + dataset: "tt-dataset", + suggestion: "tt-suggestion", + selectable: "tt-selectable", + empty: "tt-empty", + open: "tt-open", + cursor: "tt-cursor", + highlight: "tt-highlight" + }; + return build; + function build(o) { + var www, classes; + classes = _.mixin({}, defaultClassNames, o); + www = { + css: buildCss(), + classes: classes, + html: buildHtml(classes), + selectors: buildSelectors(classes) + }; + return { + css: www.css, + html: www.html, + classes: www.classes, + selectors: www.selectors, + mixin: function(o) { + _.mixin(o, www); + } + }; + } + function buildHtml(c) { + return { + wrapper: '', + menu: '
' + }; + } + function buildSelectors(classes) { + var selectors = {}; + _.each(classes, function(v, k) { + selectors[k] = "." + v; + }); + return selectors; + } + function buildCss() { + var css = { + wrapper: { + position: "relative", + display: "inline-block" + }, + hint: { + position: "absolute", + top: "0", + left: "0", + borderColor: "transparent", + boxShadow: "none", + opacity: "1" + }, + input: { + position: "relative", + verticalAlign: "top", + backgroundColor: "transparent" + }, + inputWithNoHint: { + position: "relative", + verticalAlign: "top" + }, + menu: { + position: "absolute", + top: "100%", + left: "0", + zIndex: "100", + display: "none" + }, + ltr: { + left: "0", + right: "auto" + }, + rtl: { + left: "auto", + right: " 0" + } + }; + if (_.isMsie()) { + _.mixin(css.input, { + backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)" + }); + } + return css; + } + }(); + var EventBus = function() { + "use strict"; + var namespace, deprecationMap; + namespace = "typeahead:"; + deprecationMap = { + render: "rendered", + cursorchange: "cursorchanged", + select: "selected", + autocomplete: "autocompleted" + }; + function EventBus(o) { + if (!o || !o.el) { + $.error("EventBus initialized without el"); + } + this.$el = $(o.el); + } + _.mixin(EventBus.prototype, { + _trigger: function(type, args) { + var $e = $.Event(namespace + type); + this.$el.trigger.call(this.$el, $e, args || []); + return $e; + }, + before: function(type) { + var args, $e; + args = [].slice.call(arguments, 1); + $e = this._trigger("before" + type, args); + return $e.isDefaultPrevented(); + }, + trigger: function(type) { + var deprecatedType; + this._trigger(type, [].slice.call(arguments, 1)); + if (deprecatedType = deprecationMap[type]) { + this._trigger(deprecatedType, [].slice.call(arguments, 1)); + } + } + }); + return EventBus; + }(); + var EventEmitter = function() { + "use strict"; + var splitter = /\s+/, nextTick = getNextTick(); + return { + onSync: onSync, + onAsync: onAsync, + off: off, + trigger: trigger + }; + function on(method, types, cb, context) { + var type; + if (!cb) { + return this; + } + types = types.split(splitter); + cb = context ? bindContext(cb, context) : cb; + this._callbacks = this._callbacks || {}; + while (type = types.shift()) { + this._callbacks[type] = this._callbacks[type] || { + sync: [], + async: [] + }; + this._callbacks[type][method].push(cb); + } + return this; + } + function onAsync(types, cb, context) { + return on.call(this, "async", types, cb, context); + } + function onSync(types, cb, context) { + return on.call(this, "sync", types, cb, context); + } + function off(types) { + var type; + if (!this._callbacks) { + return this; + } + types = types.split(splitter); + while (type = types.shift()) { + delete this._callbacks[type]; + } + return this; + } + function trigger(types) { + var type, callbacks, args, syncFlush, asyncFlush; + if (!this._callbacks) { + return this; + } + types = types.split(splitter); + args = [].slice.call(arguments, 1); + while ((type = types.shift()) && (callbacks = this._callbacks[type])) { + syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args)); + asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args)); + syncFlush() && nextTick(asyncFlush); + } + return this; + } + function getFlush(callbacks, context, args) { + return flush; + function flush() { + var cancelled; + for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) { + cancelled = callbacks[i].apply(context, args) === false; + } + return !cancelled; + } + } + function getNextTick() { + var nextTickFn; + if (window.setImmediate) { + nextTickFn = function nextTickSetImmediate(fn) { + setImmediate(function() { + fn(); + }); + }; + } else { + nextTickFn = function nextTickSetTimeout(fn) { + setTimeout(function() { + fn(); + }, 0); + }; + } + return nextTickFn; + } + function bindContext(fn, context) { + return fn.bind ? fn.bind(context) : function() { + fn.apply(context, [].slice.call(arguments, 0)); + }; + } + }(); + var highlight = function(doc) { + "use strict"; + var defaults = { + node: null, + pattern: null, + tagName: "strong", + className: null, + wordsOnly: false, + caseSensitive: false, + diacriticInsensitive: false + }; + var accented = { + A: "[AaªÀ-Åà-åĀ-ąǍǎȀ-ȃȦȧᴬᵃḀḁẚẠ-ảₐ℀℁℻⒜Ⓐⓐ㍱-㍴㎀-㎄㎈㎉㎩-㎯㏂㏊㏟㏿Aa]", + B: "[BbᴮᵇḂ-ḇℬ⒝Ⓑⓑ㍴㎅-㎇㏃㏈㏔㏝Bb]", + C: "[CcÇçĆ-čᶜ℀ℂ℃℅℆ℭⅭⅽ⒞Ⓒⓒ㍶㎈㎉㎝㎠㎤㏄-㏇Cc]", + D: "[DdĎďDŽ-džDZ-dzᴰᵈḊ-ḓⅅⅆⅮⅾ⒟Ⓓⓓ㋏㍲㍷-㍹㎗㎭-㎯㏅㏈Dd]", + E: "[EeÈ-Ëè-ëĒ-ěȄ-ȇȨȩᴱᵉḘ-ḛẸ-ẽₑ℡ℯℰⅇ⒠Ⓔⓔ㉐㋍㋎Ee]", + F: "[FfᶠḞḟ℉ℱ℻⒡Ⓕⓕ㎊-㎌㎙ff-fflFf]", + G: "[GgĜ-ģǦǧǴǵᴳᵍḠḡℊ⒢Ⓖⓖ㋌㋍㎇㎍-㎏㎓㎬㏆㏉㏒㏿Gg]", + H: "[HhĤĥȞȟʰᴴḢ-ḫẖℋ-ℎ⒣Ⓗⓗ㋌㍱㎐-㎔㏊㏋㏗Hh]", + I: "[IiÌ-Ïì-ïĨ-İIJijǏǐȈ-ȋᴵᵢḬḭỈ-ịⁱℐℑℹⅈⅠ-ⅣⅥ-ⅨⅪⅫⅰ-ⅳⅵ-ⅸⅺⅻ⒤Ⓘⓘ㍺㏌㏕fiffiIi]", + J: "[JjIJ-ĵLJ-njǰʲᴶⅉ⒥ⒿⓙⱼJj]", + K: "[KkĶķǨǩᴷᵏḰ-ḵK⒦Ⓚⓚ㎄㎅㎉㎏㎑㎘㎞㎢㎦㎪㎸㎾㏀㏆㏍-㏏Kk]", + L: "[LlĹ-ŀLJ-ljˡᴸḶḷḺ-ḽℒℓ℡Ⅼⅼ⒧Ⓛⓛ㋏㎈㎉㏐-㏓㏕㏖㏿flfflLl]", + M: "[MmᴹᵐḾ-ṃ℠™ℳⅯⅿ⒨Ⓜⓜ㍷-㍹㎃㎆㎎㎒㎖㎙-㎨㎫㎳㎷㎹㎽㎿㏁㏂㏎㏐㏔-㏖㏘㏙㏞㏟Mm]", + N: "[NnÑñŃ-ʼnNJ-njǸǹᴺṄ-ṋⁿℕ№⒩Ⓝⓝ㎁㎋㎚㎱㎵㎻㏌㏑Nn]", + O: "[OoºÒ-Öò-öŌ-őƠơǑǒǪǫȌ-ȏȮȯᴼᵒỌ-ỏₒ℅№ℴ⒪Ⓞⓞ㍵㏇㏒㏖Oo]", + P: "[PpᴾᵖṔ-ṗℙ⒫Ⓟⓟ㉐㍱㍶㎀㎊㎩-㎬㎰㎴㎺㏋㏗-㏚Pp]", + Q: "[Qqℚ⒬Ⓠⓠ㏃Qq]", + R: "[RrŔ-řȐ-ȓʳᴿᵣṘ-ṛṞṟ₨ℛ-ℝ⒭Ⓡⓡ㋍㍴㎭-㎯㏚㏛Rr]", + S: "[SsŚ-šſȘșˢṠ-ṣ₨℁℠⒮Ⓢⓢ㎧㎨㎮-㎳㏛㏜stSs]", + T: "[TtŢ-ťȚțᵀᵗṪ-ṱẗ℡™⒯Ⓣⓣ㉐㋏㎔㏏ſtstTt]", + U: "[UuÙ-Üù-üŨ-ųƯưǓǔȔ-ȗᵁᵘᵤṲ-ṷỤ-ủ℆⒰Ⓤⓤ㍳㍺Uu]", + V: "[VvᵛᵥṼ-ṿⅣ-Ⅷⅳ-ⅷ⒱Ⓥⓥⱽ㋎㍵㎴-㎹㏜㏞Vv]", + W: "[WwŴŵʷᵂẀ-ẉẘ⒲Ⓦⓦ㎺-㎿㏝Ww]", + X: "[XxˣẊ-ẍₓ℻Ⅸ-Ⅻⅸ-ⅻ⒳Ⓧⓧ㏓Xx]", + Y: "[YyÝýÿŶ-ŸȲȳʸẎẏẙỲ-ỹ⒴Ⓨⓨ㏉Yy]", + Z: "[ZzŹ-žDZ-dzᶻẐ-ẕℤℨ⒵Ⓩⓩ㎐-㎔Zz]" + }; + return function hightlight(o) { + var regex; + o = _.mixin({}, defaults, o); + if (!o.node || !o.pattern) { + return; + } + o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ]; + regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly, o.diacriticInsensitive); + traverse(o.node, hightlightTextNode); + function hightlightTextNode(textNode) { + var match, patternNode, wrapperNode; + if (match = regex.exec(textNode.data)) { + wrapperNode = doc.createElement(o.tagName); + o.className && (wrapperNode.className = o.className); + patternNode = textNode.splitText(match.index); + patternNode.splitText(match[0].length); + wrapperNode.appendChild(patternNode.cloneNode(true)); + textNode.parentNode.replaceChild(wrapperNode, patternNode); + } + return !!match; + } + function traverse(el, hightlightTextNode) { + var childNode, TEXT_NODE_TYPE = 3; + for (var i = 0; i < el.childNodes.length; i++) { + childNode = el.childNodes[i]; + if (childNode.nodeType === TEXT_NODE_TYPE) { + i += hightlightTextNode(childNode) ? 1 : 0; + } else { + traverse(childNode, hightlightTextNode); + } + } + } + }; + function accent_replacer(chr) { + return accented[chr.toUpperCase()] || chr; + } + function getRegex(patterns, caseSensitive, wordsOnly, diacriticInsensitive) { + var escapedPatterns = [], regexStr; + for (var i = 0, len = patterns.length; i < len; i++) { + var escapedWord = _.escapeRegExChars(patterns[i]); + if (diacriticInsensitive) { + escapedWord = escapedWord.replace(/\S/g, accent_replacer); + } + escapedPatterns.push(escapedWord); + } + regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")"; + return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i"); + } + }(window.document); + var Input = function() { + "use strict"; + var specialKeyCodeMap; + specialKeyCodeMap = { + 9: "tab", + 27: "esc", + 37: "left", + 39: "right", + 13: "enter", + 38: "up", + 40: "down" + }; + function Input(o, www) { + var id; + o = o || {}; + if (!o.input) { + $.error("input is missing"); + } + www.mixin(this); + this.$hint = $(o.hint); + this.$input = $(o.input); + this.$menu = $(o.menu); + id = this.$input.attr("id") || _.guid(); + this.$menu.attr("id", id + "_listbox"); + this.$hint.attr({ + "aria-hidden": true + }); + this.$input.attr({ + "aria-owns": id + "_listbox", + role: "combobox", + "aria-autocomplete": "list", + "aria-expanded": false + }); + this.query = this.$input.val(); + this.queryWhenFocused = this.hasFocus() ? this.query : null; + this.$overflowHelper = buildOverflowHelper(this.$input); + this._checkLanguageDirection(); + if (this.$hint.length === 0) { + this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop; + } + this.onSync("cursorchange", this._updateDescendent); + } + Input.normalizeQuery = function(str) { + return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " "); + }; + _.mixin(Input.prototype, EventEmitter, { + _onBlur: function onBlur() { + this.resetInputValue(); + this.trigger("blurred"); + }, + _onFocus: function onFocus() { + this.queryWhenFocused = this.query; + this.trigger("focused"); + }, + _onKeydown: function onKeydown($e) { + var keyName = specialKeyCodeMap[$e.which || $e.keyCode]; + this._managePreventDefault(keyName, $e); + if (keyName && this._shouldTrigger(keyName, $e)) { + this.trigger(keyName + "Keyed", $e); + } + }, + _onInput: function onInput() { + this._setQuery(this.getInputValue()); + this.clearHintIfInvalid(); + this._checkLanguageDirection(); + }, + _managePreventDefault: function managePreventDefault(keyName, $e) { + var preventDefault; + switch (keyName) { + case "up": + case "down": + preventDefault = !withModifier($e); + break; + + default: + preventDefault = false; + } + preventDefault && $e.preventDefault(); + }, + _shouldTrigger: function shouldTrigger(keyName, $e) { + var trigger; + switch (keyName) { + case "tab": + trigger = !withModifier($e); + break; + + default: + trigger = true; + } + return trigger; + }, + _checkLanguageDirection: function checkLanguageDirection() { + var dir = (this.$input.css("direction") || "ltr").toLowerCase(); + if (this.dir !== dir) { + this.dir = dir; + this.$hint.attr("dir", dir); + this.trigger("langDirChanged", dir); + } + }, + _setQuery: function setQuery(val, silent) { + var areEquivalent, hasDifferentWhitespace; + areEquivalent = areQueriesEquivalent(val, this.query); + hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false; + this.query = val; + if (!silent && !areEquivalent) { + this.trigger("queryChanged", this.query); + } else if (!silent && hasDifferentWhitespace) { + this.trigger("whitespaceChanged", this.query); + } + }, + _updateDescendent: function updateDescendent(event, id) { + this.$input.attr("aria-activedescendant", id); + }, + bind: function() { + var that = this, onBlur, onFocus, onKeydown, onInput; + onBlur = _.bind(this._onBlur, this); + onFocus = _.bind(this._onFocus, this); + onKeydown = _.bind(this._onKeydown, this); + onInput = _.bind(this._onInput, this); + this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown); + if (!_.isMsie() || _.isMsie() > 9) { + this.$input.on("input.tt", onInput); + } else { + this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) { + if (specialKeyCodeMap[$e.which || $e.keyCode]) { + return; + } + _.defer(_.bind(that._onInput, that, $e)); + }); + } + return this; + }, + focus: function focus() { + this.$input.focus(); + }, + blur: function blur() { + this.$input.blur(); + }, + getLangDir: function getLangDir() { + return this.dir; + }, + getQuery: function getQuery() { + return this.query || ""; + }, + setQuery: function setQuery(val, silent) { + this.setInputValue(val); + this._setQuery(val, silent); + }, + hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() { + return this.query !== this.queryWhenFocused; + }, + getInputValue: function getInputValue() { + return this.$input.val(); + }, + setInputValue: function setInputValue(value) { + this.$input.val(value); + this.clearHintIfInvalid(); + this._checkLanguageDirection(); + }, + resetInputValue: function resetInputValue() { + this.setInputValue(this.query); + }, + getHint: function getHint() { + return this.$hint.val(); + }, + setHint: function setHint(value) { + this.$hint.val(value); + }, + clearHint: function clearHint() { + this.setHint(""); + }, + clearHintIfInvalid: function clearHintIfInvalid() { + var val, hint, valIsPrefixOfHint, isValid; + val = this.getInputValue(); + hint = this.getHint(); + valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0; + isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow(); + !isValid && this.clearHint(); + }, + hasFocus: function hasFocus() { + return this.$input.is(":focus"); + }, + hasOverflow: function hasOverflow() { + var constraint = this.$input.width() - 2; + this.$overflowHelper.text(this.getInputValue()); + return this.$overflowHelper.width() >= constraint; + }, + isCursorAtEnd: function() { + var valueLength, selectionStart, range; + valueLength = this.$input.val().length; + selectionStart = this.$input[0].selectionStart; + if (_.isNumber(selectionStart)) { + return selectionStart === valueLength; + } else if (document.selection) { + range = document.selection.createRange(); + range.moveStart("character", -valueLength); + return valueLength === range.text.length; + } + return true; + }, + destroy: function destroy() { + this.$hint.off(".tt"); + this.$input.off(".tt"); + this.$overflowHelper.remove(); + this.$hint = this.$input = this.$overflowHelper = $("
"); + }, + setAriaExpanded: function setAriaExpanded(value) { + this.$input.attr("aria-expanded", value); + } + }); + return Input; + function buildOverflowHelper($input) { + return $('').css({ + position: "absolute", + visibility: "hidden", + whiteSpace: "pre", + fontFamily: $input.css("font-family"), + fontSize: $input.css("font-size"), + fontStyle: $input.css("font-style"), + fontVariant: $input.css("font-variant"), + fontWeight: $input.css("font-weight"), + wordSpacing: $input.css("word-spacing"), + letterSpacing: $input.css("letter-spacing"), + textIndent: $input.css("text-indent"), + textRendering: $input.css("text-rendering"), + textTransform: $input.css("text-transform") + }).insertAfter($input); + } + function areQueriesEquivalent(a, b) { + return Input.normalizeQuery(a) === Input.normalizeQuery(b); + } + function withModifier($e) { + return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey; + } + }(); + var Dataset = function() { + "use strict"; + var keys, nameGenerator; + keys = { + dataset: "tt-selectable-dataset", + val: "tt-selectable-display", + obj: "tt-selectable-object" + }; + nameGenerator = _.getIdGenerator(); + function Dataset(o, www) { + o = o || {}; + o.templates = o.templates || {}; + o.templates.notFound = o.templates.notFound || o.templates.empty; + if (!o.source) { + $.error("missing source"); + } + if (!o.node) { + $.error("missing node"); + } + if (o.name && !isValidName(o.name)) { + $.error("invalid dataset name: " + o.name); + } + www.mixin(this); + this.highlight = !!o.highlight; + this.name = _.toStr(o.name || nameGenerator()); + this.limit = o.limit || 5; + this.displayFn = getDisplayFn(o.display || o.displayKey); + this.templates = getTemplates(o.templates, this.displayFn); + this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source; + this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async; + this._resetLastSuggestion(); + this.$el = $(o.node).attr("role", "presentation").addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name); + } + Dataset.extractData = function extractData(el) { + var $el = $(el); + if ($el.data(keys.obj)) { + return { + dataset: $el.data(keys.dataset) || "", + val: $el.data(keys.val) || "", + obj: $el.data(keys.obj) || null + }; + } + return null; + }; + _.mixin(Dataset.prototype, EventEmitter, { + _overwrite: function overwrite(query, suggestions) { + suggestions = suggestions || []; + if (suggestions.length) { + this._renderSuggestions(query, suggestions); + } else if (this.async && this.templates.pending) { + this._renderPending(query); + } else if (!this.async && this.templates.notFound) { + this._renderNotFound(query); + } else { + this._empty(); + } + this.trigger("rendered", suggestions, false, this.name); + }, + _append: function append(query, suggestions) { + suggestions = suggestions || []; + if (suggestions.length && this.$lastSuggestion.length) { + this._appendSuggestions(query, suggestions); + } else if (suggestions.length) { + this._renderSuggestions(query, suggestions); + } else if (!this.$lastSuggestion.length && this.templates.notFound) { + this._renderNotFound(query); + } + this.trigger("rendered", suggestions, true, this.name); + }, + _renderSuggestions: function renderSuggestions(query, suggestions) { + var $fragment; + $fragment = this._getSuggestionsFragment(query, suggestions); + this.$lastSuggestion = $fragment.children().last(); + this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions)); + }, + _appendSuggestions: function appendSuggestions(query, suggestions) { + var $fragment, $lastSuggestion; + $fragment = this._getSuggestionsFragment(query, suggestions); + $lastSuggestion = $fragment.children().last(); + this.$lastSuggestion.after($fragment); + this.$lastSuggestion = $lastSuggestion; + }, + _renderPending: function renderPending(query) { + var template = this.templates.pending; + this._resetLastSuggestion(); + template && this.$el.html(template({ + query: query, + dataset: this.name + })); + }, + _renderNotFound: function renderNotFound(query) { + var template = this.templates.notFound; + this._resetLastSuggestion(); + template && this.$el.html(template({ + query: query, + dataset: this.name + })); + }, + _empty: function empty() { + this.$el.empty(); + this._resetLastSuggestion(); + }, + _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) { + var that = this, fragment; + fragment = document.createDocumentFragment(); + _.each(suggestions, function getSuggestionNode(suggestion) { + var $el, context; + context = that._injectQuery(query, suggestion); + $el = $(that.templates.suggestion(context)).data(keys.dataset, that.name).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable); + fragment.appendChild($el[0]); + }); + this.highlight && highlight({ + className: this.classes.highlight, + node: fragment, + pattern: query + }); + return $(fragment); + }, + _getFooter: function getFooter(query, suggestions) { + return this.templates.footer ? this.templates.footer({ + query: query, + suggestions: suggestions, + dataset: this.name + }) : null; + }, + _getHeader: function getHeader(query, suggestions) { + return this.templates.header ? this.templates.header({ + query: query, + suggestions: suggestions, + dataset: this.name + }) : null; + }, + _resetLastSuggestion: function resetLastSuggestion() { + this.$lastSuggestion = $(); + }, + _injectQuery: function injectQuery(query, obj) { + return _.isObject(obj) ? _.mixin({ + _query: query + }, obj) : obj; + }, + update: function update(query) { + var that = this, canceled = false, syncCalled = false, rendered = 0; + this.cancel(); + this.cancel = function cancel() { + canceled = true; + that.cancel = $.noop; + that.async && that.trigger("asyncCanceled", query, that.name); + }; + this.source(query, sync, async); + !syncCalled && sync([]); + function sync(suggestions) { + if (syncCalled) { + return; + } + syncCalled = true; + suggestions = (suggestions || []).slice(0, that.limit); + rendered = suggestions.length; + that._overwrite(query, suggestions); + if (rendered < that.limit && that.async) { + that.trigger("asyncRequested", query, that.name); + } + } + function async(suggestions) { + suggestions = suggestions || []; + if (!canceled && rendered < that.limit) { + that.cancel = $.noop; + var idx = Math.abs(rendered - that.limit); + rendered += idx; + that._append(query, suggestions.slice(0, idx)); + that.async && that.trigger("asyncReceived", query, that.name); + } + } + }, + cancel: $.noop, + clear: function clear() { + this._empty(); + this.cancel(); + this.trigger("cleared"); + }, + isEmpty: function isEmpty() { + return this.$el.is(":empty"); + }, + destroy: function destroy() { + this.$el = $("
"); + } + }); + return Dataset; + function getDisplayFn(display) { + display = display || _.stringify; + return _.isFunction(display) ? display : displayFn; + function displayFn(obj) { + return obj[display]; + } + } + function getTemplates(templates, displayFn) { + return { + notFound: templates.notFound && _.templatify(templates.notFound), + pending: templates.pending && _.templatify(templates.pending), + header: templates.header && _.templatify(templates.header), + footer: templates.footer && _.templatify(templates.footer), + suggestion: templates.suggestion ? userSuggestionTemplate : suggestionTemplate + }; + function userSuggestionTemplate(context) { + var template = templates.suggestion; + return $(template(context)).attr("id", _.guid()); + } + function suggestionTemplate(context) { + return $('
').attr("id", _.guid()).text(displayFn(context)); + } + } + function isValidName(str) { + return /^[_a-zA-Z0-9-]+$/.test(str); + } + }(); + var Menu = function() { + "use strict"; + function Menu(o, www) { + var that = this; + o = o || {}; + if (!o.node) { + $.error("node is required"); + } + www.mixin(this); + this.$node = $(o.node); + this.query = null; + this.datasets = _.map(o.datasets, initializeDataset); + function initializeDataset(oDataset) { + var node = that.$node.find(oDataset.node).first(); + oDataset.node = node.length ? node : $("
").appendTo(that.$node); + return new Dataset(oDataset, www); + } + } + _.mixin(Menu.prototype, EventEmitter, { + _onSelectableClick: function onSelectableClick($e) { + this.trigger("selectableClicked", $($e.currentTarget)); + }, + _onRendered: function onRendered(type, dataset, suggestions, async) { + this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty()); + this.trigger("datasetRendered", dataset, suggestions, async); + }, + _onCleared: function onCleared() { + this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty()); + this.trigger("datasetCleared"); + }, + _propagate: function propagate() { + this.trigger.apply(this, arguments); + }, + _allDatasetsEmpty: function allDatasetsEmpty() { + return _.every(this.datasets, _.bind(function isDatasetEmpty(dataset) { + var isEmpty = dataset.isEmpty(); + this.$node.attr("aria-expanded", !isEmpty); + return isEmpty; + }, this)); + }, + _getSelectables: function getSelectables() { + return this.$node.find(this.selectors.selectable); + }, + _removeCursor: function _removeCursor() { + var $selectable = this.getActiveSelectable(); + $selectable && $selectable.removeClass(this.classes.cursor); + }, + _ensureVisible: function ensureVisible($el) { + var elTop, elBottom, nodeScrollTop, nodeHeight; + elTop = $el.position().top; + elBottom = elTop + $el.outerHeight(true); + nodeScrollTop = this.$node.scrollTop(); + nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10); + if (elTop < 0) { + this.$node.scrollTop(nodeScrollTop + elTop); + } else if (nodeHeight < elBottom) { + this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight)); + } + }, + bind: function() { + var that = this, onSelectableClick; + onSelectableClick = _.bind(this._onSelectableClick, this); + this.$node.on("click.tt", this.selectors.selectable, onSelectableClick); + this.$node.on("mouseover", this.selectors.selectable, function() { + that.setCursor($(this)); + }); + this.$node.on("mouseleave", function() { + that._removeCursor(); + }); + _.each(this.datasets, function(dataset) { + dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that); + }); + return this; + }, + isOpen: function isOpen() { + return this.$node.hasClass(this.classes.open); + }, + open: function open() { + this.$node.scrollTop(0); + this.$node.addClass(this.classes.open); + }, + close: function close() { + this.$node.attr("aria-expanded", false); + this.$node.removeClass(this.classes.open); + this._removeCursor(); + }, + setLanguageDirection: function setLanguageDirection(dir) { + this.$node.attr("dir", dir); + }, + selectableRelativeToCursor: function selectableRelativeToCursor(delta) { + var $selectables, $oldCursor, oldIndex, newIndex; + $oldCursor = this.getActiveSelectable(); + $selectables = this._getSelectables(); + oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1; + newIndex = oldIndex + delta; + newIndex = (newIndex + 1) % ($selectables.length + 1) - 1; + newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex; + return newIndex === -1 ? null : $selectables.eq(newIndex); + }, + setCursor: function setCursor($selectable) { + this._removeCursor(); + if ($selectable = $selectable && $selectable.first()) { + $selectable.addClass(this.classes.cursor); + this._ensureVisible($selectable); + } + }, + getSelectableData: function getSelectableData($el) { + return $el && $el.length ? Dataset.extractData($el) : null; + }, + getActiveSelectable: function getActiveSelectable() { + var $selectable = this._getSelectables().filter(this.selectors.cursor).first(); + return $selectable.length ? $selectable : null; + }, + getTopSelectable: function getTopSelectable() { + var $selectable = this._getSelectables().first(); + return $selectable.length ? $selectable : null; + }, + update: function update(query) { + var isValidUpdate = query !== this.query; + if (isValidUpdate) { + this.query = query; + _.each(this.datasets, updateDataset); + } + return isValidUpdate; + function updateDataset(dataset) { + dataset.update(query); + } + }, + empty: function empty() { + _.each(this.datasets, clearDataset); + this.query = null; + this.$node.addClass(this.classes.empty); + function clearDataset(dataset) { + dataset.clear(); + } + }, + destroy: function destroy() { + this.$node.off(".tt"); + this.$node = $("
"); + _.each(this.datasets, destroyDataset); + function destroyDataset(dataset) { + dataset.destroy(); + } + } + }); + return Menu; + }(); + var Status = function() { + "use strict"; + function Status(options) { + this.$el = $("", { + role: "status", + "aria-live": "polite" + }).css({ + position: "absolute", + padding: "0", + border: "0", + height: "1px", + width: "1px", + "margin-bottom": "-1px", + "margin-right": "-1px", + overflow: "hidden", + clip: "rect(0 0 0 0)", + "white-space": "nowrap" + }); + options.$input.after(this.$el); + _.each(options.menu.datasets, _.bind(function(dataset) { + if (dataset.onSync) { + dataset.onSync("rendered", _.bind(this.update, this)); + dataset.onSync("cleared", _.bind(this.cleared, this)); + } + }, this)); + } + _.mixin(Status.prototype, { + update: function update(event, suggestions) { + var length = suggestions.length; + var words; + if (length === 1) { + words = { + result: "result", + is: "is" + }; + } else { + words = { + result: "results", + is: "are" + }; + } + this.$el.text(length + " " + words.result + " " + words.is + " available, use up and down arrow keys to navigate."); + }, + cleared: function() { + this.$el.text(""); + } + }); + return Status; + }(); + var DefaultMenu = function() { + "use strict"; + var s = Menu.prototype; + function DefaultMenu() { + Menu.apply(this, [].slice.call(arguments, 0)); + } + _.mixin(DefaultMenu.prototype, Menu.prototype, { + open: function open() { + !this._allDatasetsEmpty() && this._show(); + return s.open.apply(this, [].slice.call(arguments, 0)); + }, + close: function close() { + this._hide(); + return s.close.apply(this, [].slice.call(arguments, 0)); + }, + _onRendered: function onRendered() { + if (this._allDatasetsEmpty()) { + this._hide(); + } else { + this.isOpen() && this._show(); + } + return s._onRendered.apply(this, [].slice.call(arguments, 0)); + }, + _onCleared: function onCleared() { + if (this._allDatasetsEmpty()) { + this._hide(); + } else { + this.isOpen() && this._show(); + } + return s._onCleared.apply(this, [].slice.call(arguments, 0)); + }, + setLanguageDirection: function setLanguageDirection(dir) { + this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl); + return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0)); + }, + _hide: function hide() { + this.$node.hide(); + }, + _show: function show() { + this.$node.css("display", "block"); + } + }); + return DefaultMenu; + }(); + var Typeahead = function() { + "use strict"; + function Typeahead(o, www) { + var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged; + o = o || {}; + if (!o.input) { + $.error("missing input"); + } + if (!o.menu) { + $.error("missing menu"); + } + if (!o.eventBus) { + $.error("missing event bus"); + } + www.mixin(this); + this.eventBus = o.eventBus; + this.minLength = _.isNumber(o.minLength) ? o.minLength : 1; + this.input = o.input; + this.menu = o.menu; + this.enabled = true; + this.autoselect = !!o.autoselect; + this.active = false; + this.input.hasFocus() && this.activate(); + this.dir = this.input.getLangDir(); + this._hacks(); + this.menu.bind().onSync("selectableClicked", this._onSelectableClicked, this).onSync("asyncRequested", this._onAsyncRequested, this).onSync("asyncCanceled", this._onAsyncCanceled, this).onSync("asyncReceived", this._onAsyncReceived, this).onSync("datasetRendered", this._onDatasetRendered, this).onSync("datasetCleared", this._onDatasetCleared, this); + onFocused = c(this, "activate", "open", "_onFocused"); + onBlurred = c(this, "deactivate", "_onBlurred"); + onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed"); + onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed"); + onEscKeyed = c(this, "isActive", "_onEscKeyed"); + onUpKeyed = c(this, "isActive", "open", "_onUpKeyed"); + onDownKeyed = c(this, "isActive", "open", "_onDownKeyed"); + onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed"); + onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed"); + onQueryChanged = c(this, "_openIfActive", "_onQueryChanged"); + onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged"); + this.input.bind().onSync("focused", onFocused, this).onSync("blurred", onBlurred, this).onSync("enterKeyed", onEnterKeyed, this).onSync("tabKeyed", onTabKeyed, this).onSync("escKeyed", onEscKeyed, this).onSync("upKeyed", onUpKeyed, this).onSync("downKeyed", onDownKeyed, this).onSync("leftKeyed", onLeftKeyed, this).onSync("rightKeyed", onRightKeyed, this).onSync("queryChanged", onQueryChanged, this).onSync("whitespaceChanged", onWhitespaceChanged, this).onSync("langDirChanged", this._onLangDirChanged, this); + } + _.mixin(Typeahead.prototype, { + _hacks: function hacks() { + var $input, $menu; + $input = this.input.$input || $("
"); + $menu = this.menu.$node || $("
"); + $input.on("blur.tt", function($e) { + var active, isActive, hasActive; + active = document.activeElement; + isActive = $menu.is(active); + hasActive = $menu.has(active).length > 0; + if (_.isMsie() && (isActive || hasActive)) { + $e.preventDefault(); + $e.stopImmediatePropagation(); + _.defer(function() { + $input.focus(); + }); + } + }); + $menu.on("mousedown.tt", function($e) { + $e.preventDefault(); + }); + }, + _onSelectableClicked: function onSelectableClicked(type, $el) { + this.select($el); + }, + _onDatasetCleared: function onDatasetCleared() { + this._updateHint(); + }, + _onDatasetRendered: function onDatasetRendered(type, suggestions, async, dataset) { + this._updateHint(); + if (this.autoselect) { + var cursorClass = this.selectors.cursor.substr(1); + this.menu.$node.find(this.selectors.suggestion).first().addClass(cursorClass); + } + this.eventBus.trigger("render", suggestions, async, dataset); + }, + _onAsyncRequested: function onAsyncRequested(type, dataset, query) { + this.eventBus.trigger("asyncrequest", query, dataset); + }, + _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) { + this.eventBus.trigger("asynccancel", query, dataset); + }, + _onAsyncReceived: function onAsyncReceived(type, dataset, query) { + this.eventBus.trigger("asyncreceive", query, dataset); + }, + _onFocused: function onFocused() { + this._minLengthMet() && this.menu.update(this.input.getQuery()); + }, + _onBlurred: function onBlurred() { + if (this.input.hasQueryChangedSinceLastFocus()) { + this.eventBus.trigger("change", this.input.getQuery()); + } + }, + _onEnterKeyed: function onEnterKeyed(type, $e) { + var $selectable; + if ($selectable = this.menu.getActiveSelectable()) { + if (this.select($selectable)) { + $e.preventDefault(); + $e.stopPropagation(); + } + } else if (this.autoselect) { + if (this.select(this.menu.getTopSelectable())) { + $e.preventDefault(); + $e.stopPropagation(); + } + } + }, + _onTabKeyed: function onTabKeyed(type, $e) { + var $selectable; + if ($selectable = this.menu.getActiveSelectable()) { + this.select($selectable) && $e.preventDefault(); + } else if (this.autoselect) { + if ($selectable = this.menu.getTopSelectable()) { + this.autocomplete($selectable) && $e.preventDefault(); + } + } + }, + _onEscKeyed: function onEscKeyed() { + this.close(); + }, + _onUpKeyed: function onUpKeyed() { + this.moveCursor(-1); + }, + _onDownKeyed: function onDownKeyed() { + this.moveCursor(+1); + }, + _onLeftKeyed: function onLeftKeyed() { + if (this.dir === "rtl" && this.input.isCursorAtEnd()) { + this.autocomplete(this.menu.getActiveSelectable() || this.menu.getTopSelectable()); + } + }, + _onRightKeyed: function onRightKeyed() { + if (this.dir === "ltr" && this.input.isCursorAtEnd()) { + this.autocomplete(this.menu.getActiveSelectable() || this.menu.getTopSelectable()); + } + }, + _onQueryChanged: function onQueryChanged(e, query) { + this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty(); + }, + _onWhitespaceChanged: function onWhitespaceChanged() { + this._updateHint(); + }, + _onLangDirChanged: function onLangDirChanged(e, dir) { + if (this.dir !== dir) { + this.dir = dir; + this.menu.setLanguageDirection(dir); + } + }, + _openIfActive: function openIfActive() { + this.isActive() && this.open(); + }, + _minLengthMet: function minLengthMet(query) { + query = _.isString(query) ? query : this.input.getQuery() || ""; + return query.length >= this.minLength; + }, + _updateHint: function updateHint() { + var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match; + $selectable = this.menu.getTopSelectable(); + data = this.menu.getSelectableData($selectable); + val = this.input.getInputValue(); + if (data && !_.isBlankString(val) && !this.input.hasOverflow()) { + query = Input.normalizeQuery(val); + escapedQuery = _.escapeRegExChars(query); + frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i"); + match = frontMatchRegEx.exec(data.val); + match && this.input.setHint(val + match[1]); + } else { + this.input.clearHint(); + } + }, + isEnabled: function isEnabled() { + return this.enabled; + }, + enable: function enable() { + this.enabled = true; + }, + disable: function disable() { + this.enabled = false; + }, + isActive: function isActive() { + return this.active; + }, + activate: function activate() { + if (this.isActive()) { + return true; + } else if (!this.isEnabled() || this.eventBus.before("active")) { + return false; + } else { + this.active = true; + this.eventBus.trigger("active"); + return true; + } + }, + deactivate: function deactivate() { + if (!this.isActive()) { + return true; + } else if (this.eventBus.before("idle")) { + return false; + } else { + this.active = false; + this.close(); + this.eventBus.trigger("idle"); + return true; + } + }, + isOpen: function isOpen() { + return this.menu.isOpen(); + }, + open: function open() { + if (!this.isOpen() && !this.eventBus.before("open")) { + this.input.setAriaExpanded(true); + this.menu.open(); + this._updateHint(); + this.eventBus.trigger("open"); + } + return this.isOpen(); + }, + close: function close() { + if (this.isOpen() && !this.eventBus.before("close")) { + this.input.setAriaExpanded(false); + this.menu.close(); + this.input.clearHint(); + this.input.resetInputValue(); + this.eventBus.trigger("close"); + } + return !this.isOpen(); + }, + setVal: function setVal(val) { + this.input.setQuery(_.toStr(val)); + }, + getVal: function getVal() { + return this.input.getQuery(); + }, + select: function select($selectable) { + var data = this.menu.getSelectableData($selectable); + if (data && !this.eventBus.before("select", data.obj, data.dataset)) { + this.input.setQuery(data.val, true); + this.eventBus.trigger("select", data.obj, data.dataset); + this.close(); + return true; + } + return false; + }, + autocomplete: function autocomplete($selectable) { + var query, data, isValid; + query = this.input.getQuery(); + data = this.menu.getSelectableData($selectable); + isValid = data && query !== data.val; + if (isValid && !this.eventBus.before("autocomplete", data.obj, data.dataset)) { + this.input.setQuery(data.val); + this.eventBus.trigger("autocomplete", data.obj, data.dataset); + return true; + } + return false; + }, + moveCursor: function moveCursor(delta) { + var query, $candidate, data, suggestion, datasetName, cancelMove, id; + query = this.input.getQuery(); + $candidate = this.menu.selectableRelativeToCursor(delta); + data = this.menu.getSelectableData($candidate); + suggestion = data ? data.obj : null; + datasetName = data ? data.dataset : null; + id = $candidate ? $candidate.attr("id") : null; + this.input.trigger("cursorchange", id); + cancelMove = this._minLengthMet() && this.menu.update(query); + if (!cancelMove && !this.eventBus.before("cursorchange", suggestion, datasetName)) { + this.menu.setCursor($candidate); + if (data) { + if (typeof data.val === "string") { + this.input.setInputValue(data.val); + } + } else { + this.input.resetInputValue(); + this._updateHint(); + } + this.eventBus.trigger("cursorchange", suggestion, datasetName); + return true; + } + return false; + }, + destroy: function destroy() { + this.input.destroy(); + this.menu.destroy(); + } + }); + return Typeahead; + function c(ctx) { + var methods = [].slice.call(arguments, 1); + return function() { + var args = [].slice.call(arguments); + _.each(methods, function(method) { + return ctx[method].apply(ctx, args); + }); + }; + } + }(); + (function() { + "use strict"; + var old, keys, methods; + old = $.fn.typeahead; + keys = { + www: "tt-www", + attrs: "tt-attrs", + typeahead: "tt-typeahead" + }; + methods = { + initialize: function initialize(o, datasets) { + var www; + datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1); + o = o || {}; + www = WWW(o.classNames); + return this.each(attach); + function attach() { + var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, status, typeahead, MenuConstructor; + _.each(datasets, function(d) { + d.highlight = !!o.highlight; + }); + $input = $(this); + $wrapper = $(www.html.wrapper); + $hint = $elOrNull(o.hint); + $menu = $elOrNull(o.menu); + defaultHint = o.hint !== false && !$hint; + defaultMenu = o.menu !== false && !$menu; + defaultHint && ($hint = buildHintFromInput($input, www)); + defaultMenu && ($menu = $(www.html.menu).css(www.css.menu)); + $hint && $hint.val(""); + $input = prepInput($input, www); + if (defaultHint || defaultMenu) { + $wrapper.css(www.css.wrapper); + $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint); + $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null); + } + MenuConstructor = defaultMenu ? DefaultMenu : Menu; + eventBus = new EventBus({ + el: $input + }); + input = new Input({ + hint: $hint, + input: $input, + menu: $menu + }, www); + menu = new MenuConstructor({ + node: $menu, + datasets: datasets + }, www); + status = new Status({ + $input: $input, + menu: menu + }); + typeahead = new Typeahead({ + input: input, + menu: menu, + eventBus: eventBus, + minLength: o.minLength, + autoselect: o.autoselect + }, www); + $input.data(keys.www, www); + $input.data(keys.typeahead, typeahead); + } + }, + isEnabled: function isEnabled() { + var enabled; + ttEach(this.first(), function(t) { + enabled = t.isEnabled(); + }); + return enabled; + }, + enable: function enable() { + ttEach(this, function(t) { + t.enable(); + }); + return this; + }, + disable: function disable() { + ttEach(this, function(t) { + t.disable(); + }); + return this; + }, + isActive: function isActive() { + var active; + ttEach(this.first(), function(t) { + active = t.isActive(); + }); + return active; + }, + activate: function activate() { + ttEach(this, function(t) { + t.activate(); + }); + return this; + }, + deactivate: function deactivate() { + ttEach(this, function(t) { + t.deactivate(); + }); + return this; + }, + isOpen: function isOpen() { + var open; + ttEach(this.first(), function(t) { + open = t.isOpen(); + }); + return open; + }, + open: function open() { + ttEach(this, function(t) { + t.open(); + }); + return this; + }, + close: function close() { + ttEach(this, function(t) { + t.close(); + }); + return this; + }, + select: function select(el) { + var success = false, $el = $(el); + ttEach(this.first(), function(t) { + success = t.select($el); + }); + return success; + }, + autocomplete: function autocomplete(el) { + var success = false, $el = $(el); + ttEach(this.first(), function(t) { + success = t.autocomplete($el); + }); + return success; + }, + moveCursor: function moveCursoe(delta) { + var success = false; + ttEach(this.first(), function(t) { + success = t.moveCursor(delta); + }); + return success; + }, + val: function val(newVal) { + var query; + if (!arguments.length) { + ttEach(this.first(), function(t) { + query = t.getVal(); + }); + return query; + } else { + ttEach(this, function(t) { + t.setVal(_.toStr(newVal)); + }); + return this; + } + }, + destroy: function destroy() { + ttEach(this, function(typeahead, $input) { + revert($input); + typeahead.destroy(); + }); + return this; + } + }; + $.fn.typeahead = function(method) { + if (methods[method]) { + return methods[method].apply(this, [].slice.call(arguments, 1)); + } else { + return methods.initialize.apply(this, arguments); + } + }; + $.fn.typeahead.noConflict = function noConflict() { + $.fn.typeahead = old; + return this; + }; + function ttEach($els, fn) { + $els.each(function() { + var $input = $(this), typeahead; + (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input); + }); + } + function buildHintFromInput($input, www) { + return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop({ + readonly: true, + required: false + }).removeAttr("id name placeholder").removeClass("required").attr({ + spellcheck: "false", + tabindex: -1 + }); + } + function prepInput($input, www) { + $input.data(keys.attrs, { + dir: $input.attr("dir"), + autocomplete: $input.attr("autocomplete"), + spellcheck: $input.attr("spellcheck"), + style: $input.attr("style") + }); + $input.addClass(www.classes.input).attr({ + spellcheck: false + }); + try { + !$input.attr("dir") && $input.attr("dir", "auto"); + } catch (e) {} + return $input; + } + function getBackgroundStyles($el) { + return { + backgroundAttachment: $el.css("background-attachment"), + backgroundClip: $el.css("background-clip"), + backgroundColor: $el.css("background-color"), + backgroundImage: $el.css("background-image"), + backgroundOrigin: $el.css("background-origin"), + backgroundPosition: $el.css("background-position"), + backgroundRepeat: $el.css("background-repeat"), + backgroundSize: $el.css("background-size") + }; + } + function revert($input) { + var www, $wrapper; + www = $input.data(keys.www); + $wrapper = $input.parent().filter(www.selectors.wrapper); + _.each($input.data(keys.attrs), function(val, key) { + _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val); + }); + $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input); + if ($wrapper.length) { + $input.detach().insertAfter($wrapper); + $wrapper.remove(); + } + } + function $elOrNull(obj) { + var isValid, $el; + isValid = _.isJQuery(obj) || _.isElement(obj); + $el = isValid ? $(obj).first() : []; + return $el.length ? $el : null; + } + })(); +}); \ No newline at end of file diff --git a/docsets/.docset/Contents/Resources/Documents/search.json b/docsets/.docset/Contents/Resources/Documents/search.json new file mode 100644 index 0000000..3e4681a --- /dev/null +++ b/docsets/.docset/Contents/Resources/Documents/search.json @@ -0,0 +1 @@ +{"Typealiases.html#/s:11CohesionKit5Stampa":{"name":"Stamp","abstract":"

A type used to annotate track object modifications through time."},"Structs/EntityObserver.html#/s:11CohesionKit14EntityObserverV8OnChangea":{"name":"OnChange","parent_name":"EntityObserver"},"Structs/EntityObserver.html#/s:11CohesionKit8ObserverP5value1TQzvp":{"name":"value","parent_name":"EntityObserver"},"Structs/EntityObserver.html#/s:11CohesionKit8ObserverP7observe8onChangeAA12SubscriptionCy1TQzc_tF":{"name":"observe(onChange:)","parent_name":"EntityObserver"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__Gcs0D0Rd__lufc":{"name":"init(_:)","abstract":"

Creates an instance referencing an Identifiable keyPath

","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__GcAA9AggregateRd__lufc":{"name":"init(_:)","abstract":"

Creates an instance referencing an Aggregate keyPath

","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__SgGcs0D0Rd__lufc":{"name":"init(_:)","abstract":"

Creates an instance referencing an optional Identifiable keyPath

","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__SgGcAA9AggregateRd__lufc":{"name":"init(_:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__GcSMRd__s0D07ElementRpd__SH5IndexRpd__lufc":{"name":"init(_:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__SgGcSMRd__s0D07ElementRpd__SH5IndexRpd__lufc":{"name":"init(_:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__GcSMRd__AA9Aggregate7ElementRpd__SH5IndexRpd__lufc":{"name":"init(_:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__SgGcSMRd__AA9Aggregate7ElementRpd__SH5IndexRpd__lufc":{"name":"init(_:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathV7wrapperACyxGs08WritableeF0Cyxqd__G_tcAA17EntityEnumWrapperRd__lufc":{"name":"init(wrapper:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathV7wrapperACyxGs08WritableeF0Cyxqd__SgG_tcAA17EntityEnumWrapperRd__lufc":{"name":"init(wrapper:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/AliasKey.html#/s:11CohesionKit8AliasKeyV5namedACyxGSS_tcfc":{"name":"init(named:)","parent_name":"AliasKey"},"Structs/AliasKey.html":{"name":"AliasKey","abstract":"

A value representing an Entity or set of Entity

"},"Structs/PartialIdentifiableKeyPath.html":{"name":"PartialIdentifiableKeyPath","abstract":"

A KeyPath wrapper allowing only Identifiable/Aggregate keypaths

"},"Structs/EntityObserver.html":{"name":"EntityObserver","abstract":"

A type registering observers on a given entity from identity storage

"},"Protocols/Logger.html#/s:11CohesionKit6LoggerP8didStore_2idyqd__m_2IDQyd__ts12IdentifiableRd__lF":{"name":"didStore(_:id:)","abstract":"

Notify when an entity was stored in the identity map

","parent_name":"Logger"},"Protocols/Logger.html#/s:11CohesionKit6LoggerP16didFailedToStore_2id5erroryqd__m_2IDQyd__s5Error_pts12IdentifiableRd__lF":{"name":"didFailedToStore(_:id:error:)","parent_name":"Logger"},"Protocols/Logger.html#/s:11CohesionKit6LoggerP16didRegisterAliasyyAA0F3KeyVyqd__GlF":{"name":"didRegisterAlias(_:)","abstract":"

Notify an alias is registered with new entities

","parent_name":"Logger"},"Protocols/Logger.html#/s:11CohesionKit6LoggerP18didUnregisterAliasyyAA0F3KeyVyqd__GlF":{"name":"didUnregisterAlias(_:)","abstract":"

Notify an alias is suppressed from the identity map

","parent_name":"Logger"},"Protocols/EntityEnumWrapper.html#/s:11CohesionKit17EntityEnumWrapperP23wrappedEntitiesKeyPaths10relativeToSayAA019PartialIdentifiableH4PathVyqd__GGs08WritablehN0Cyqd__xG_tlF":{"name":"wrappedEntitiesKeyPaths(relativeTo:)","abstract":"

Entities contained by all cases relative to the parent container

","parent_name":"EntityEnumWrapper"},"Protocols/Aggregate.html#/s:11CohesionKit9AggregateP22nestedEntitiesKeyPathsSayAA019PartialIdentifiableF4PathVyxGGvp":{"name":"nestedEntitiesKeyPaths","abstract":"

keypaths to nested models

","parent_name":"Aggregate"},"Protocols/Observer.html#/s:11CohesionKit8ObserverP1TQa":{"name":"T","parent_name":"Observer"},"Protocols/Observer.html#/s:11CohesionKit8ObserverP5value1TQzvp":{"name":"value","abstract":"

The value at the time the observer creation.","parent_name":"Observer"},"Protocols/Observer.html#/s:11CohesionKit8ObserverP7observe8onChangeAA12SubscriptionCy1TQzc_tF":{"name":"observe(onChange:)","abstract":"

Add an observer being notified when entity change.","parent_name":"Observer"},"Protocols/Observer.html#/s:11CohesionKit8ObserverPAAE11asPublisher7Combine03AnyE0Vy1TQzs5NeverOGvp":{"name":"asPublisher","abstract":"

A Publisher emitting the observer current value and subscribing to any subsequents new values

","parent_name":"Observer"},"Protocols/Observer.html":{"name":"Observer","abstract":"

A protocol allowing to observe a value returned from the IdentityMap

"},"Protocols/Aggregate.html":{"name":"Aggregate","abstract":"

An Identifiable model containing nested models

"},"Protocols/EntityEnumWrapper.html":{"name":"EntityEnumWrapper","abstract":"

a type wrapping one or more Identifiable types. As the name indicates you should use this type only on enums:"},"Protocols/Logger.html":{"name":"Logger","abstract":"

a protocol reporting IdentityMap internal information

"},"Extensions/Date.html#/s:10Foundation4DateV11CohesionKitE5stampSdvp":{"name":"stamp","abstract":"

Generate a stamp suitable to use in IdentityMap.","parent_name":"Date"},"Extensions/Publisher.html#/s:7Combine9PublisherP11CohesionKitE5store2in5named10modifiedAtAA03AnyB0Vy6OutputQz7FailureQzGAD11IdentityMapC_AD8AliasKeyVyALGSgSdts12IdentifiableALRQrlF":{"name":"store(in:named:modifiedAt:)","abstract":"

Stores the Identifiable upstream into an identityMap

","parent_name":"Publisher"},"Extensions/Publisher.html#/s:7Combine9PublisherP11CohesionKitE5store2in5named10modifiedAtAA03AnyB0Vy6OutputQz7FailureQzGAD11IdentityMapC_AD8AliasKeyVyALGSgSdtAD9AggregateALRQrlF":{"name":"store(in:named:modifiedAt:)","abstract":"

Stores the Aggregate upstream into an identityMap

","parent_name":"Publisher"},"Extensions/Publisher.html#/s:7Combine9PublisherP11CohesionKitE5store2in5named10modifiedAtAA03AnyB0VySay6Output_7ElementQZG7FailureQzGAD11IdentityMapC_AD8AliasKeyVyAKQzGSgSdtSlAVRQs12IdentifiableAMRQrlF":{"name":"store(in:named:modifiedAt:)","abstract":"

Stores the upstream collection into an identityMap

","parent_name":"Publisher"},"Extensions/Publisher.html#/s:7Combine9PublisherP11CohesionKitE5store2in5named10modifiedAtAA03AnyB0VySay6Output_7ElementQZG7FailureQzGAD11IdentityMapC_AD8AliasKeyVyAKQzGSgSdtSlAVRQAD9AggregateAMRQrlF":{"name":"store(in:named:modifiedAt:)","abstract":"

Stores the upstream collection into an identityMap

","parent_name":"Publisher"},"Extensions/Publisher.html":{"name":"Publisher"},"Extensions/Date.html":{"name":"Date"},"Extensions.html#/s:11CohesionKit10EntityNodeC":{"name":"EntityNode"},"Enums/StampError.html#/s:11CohesionKit10StampErrorO6tooOldyACSd_SdtcACmF":{"name":"tooOld(current:received:)","abstract":"

received stamp is smaller than current stamp

","parent_name":"StampError"},"Enums/StampError.html":{"name":"StampError"},"Classes/Subscription.html#/s:11CohesionKit12SubscriptionC11unsubscribeyycvp":{"name":"unsubscribe","parent_name":"Subscription"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6Updatea":{"name":"Update","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC5queue6loggerACSo012OS_dispatch_E0CSg_AA6Logger_pSgtcfc":{"name":"init(queue:logger:)","abstract":"

Create a new IdentityMap instance optionally with a queue and a logger

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC5store6entity5named10modifiedAt9ifPresentAA14EntityObserverVyxGx_AA8AliasKeyVyxGSgSdSgyxzcSgts12IdentifiableRzlF":{"name":"store(entity:named:modifiedAt:ifPresent:)","abstract":"

Store an entity in the storage. Entity will be stored only if stamp (modifiedAt) is higher than in previous","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC5store6entity5named10modifiedAt9ifPresentAA14EntityObserverVyxGx_AA8AliasKeyVyxGSgSdSgyxzcSgtAA9AggregateRzlF":{"name":"store(entity:named:modifiedAt:ifPresent:)","abstract":"

Store an aggregate in the storage. Each aggregate entities will be stored only if stamp (modifiedAt) is higher than in previous","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC5store8entities5named10modifiedAtAA14EntityObserverVySay7ElementQzGGx_AA8AliasKeyVyxGSgSdSgtSlRzs12IdentifiableAKRQlF":{"name":"store(entities:named:modifiedAt:)","abstract":"

Store multiple entities at once

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC5store8entities5named10modifiedAtAA14EntityObserverVySay7ElementQzGGx_AA8AliasKeyVyxGSgSdSgtSlRzAA9AggregateAKRQlF":{"name":"store(entities:named:modifiedAt:)","abstract":"

store multiple aggregates at once

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC4find_2idAA14EntityObserverVyxGSgxm_2IDQzts12IdentifiableRzlF":{"name":"find(_:id:)","abstract":"

Try to find an entity/aggregate in the storage.

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC4find5namedAA14EntityObserverVyxSgGAA8AliasKeyVyxG_ts12IdentifiableRzlF":{"name":"find(named:)","abstract":"

Try to find an entity/aggregate registered under named alias

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC4find5namedAA14EntityObserverVyxSgGAA8AliasKeyVyxG_tSlRzlF":{"name":"find(named:)","abstract":"

Try to find a collected registered under named alias

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6update_2id10modifiedAtADSbxm_2IDQzSdSgyxzXEts12IdentifiableRzlF":{"name":"update(_:id:modifiedAt:update:)","abstract":"

Updates an already stored entity using a closure. Useful to update a few properties or when you assume the entity","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6update_2id10modifiedAt_Sbxm_2IDQzSdSgyxzXEtAA9AggregateRzlF":{"name":"update(_:id:modifiedAt:_:)","abstract":"

Updates an already stored alias using a closure. This is useful if you don’t have a full entity for update","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6update5named10modifiedAtADSbAA8AliasKeyVyxG_SdSgyxzXEts12IdentifiableRzlF":{"name":"update(named:modifiedAt:update:)","abstract":"

Updates an already stored alias using a closure.","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6update5named10modifiedAtADSbAA8AliasKeyVyxG_SdSgyxzXEtAA9AggregateRzlF":{"name":"update(named:modifiedAt:update:)","abstract":"

Updates an already stored alias using a closure.","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6update5named10modifiedAtADSbAA8AliasKeyVyxG_SdSgyxzXEtSlRzs12Identifiable7ElementRpzlF":{"name":"update(named:modifiedAt:update:)","abstract":"

Updates an already existing collection alias content","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6update5named10modifiedAtADSbAA8AliasKeyVyxG_SdSgyxzXEtSlRzAA9Aggregate7ElementRpzlF":{"name":"update(named:modifiedAt:update:)","abstract":"

Updates an already existing collection alias content","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC11removeAlias5namedyAA0F3KeyVyxG_tlF":{"name":"removeAlias(named:)","abstract":"

Removes an alias from the storage

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC11removeAlias5namedyAA0F3KeyVyxG_tSlRzlF":{"name":"removeAlias(named:)","abstract":"

Removes an alias from the storage

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC14removeAllAliasyyF":{"name":"removeAllAlias()","abstract":"

Removes all alias from identity map

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC9removeAllyyF":{"name":"removeAll()","abstract":"

Removes all alias AND all objects stored weakly. You should not need this method and rather use removeAlias.","parent_name":"IdentityMap"},"Classes/IdentityMap.html":{"name":"IdentityMap","abstract":"

Manages entities lifecycle and synchronisation

"},"Classes/Subscription.html":{"name":"Subscription"},"Classes.html":{"name":"Classes","abstract":"

The following classes are available globally.

"},"Enums.html":{"name":"Enumerations","abstract":"

The following enumerations are available globally.

"},"Extensions.html":{"name":"Extensions","abstract":"

The following extensions are available globally.

"},"Protocols.html":{"name":"Protocols","abstract":"

The following protocols are available globally.

"},"Structs.html":{"name":"Structures","abstract":"

The following structures are available globally.

"},"Typealiases.html":{"name":"Type Aliases","abstract":"

The following type aliases are available globally.

"}} \ No newline at end of file diff --git a/docsets/.docset/Contents/Resources/docSet.dsidx b/docsets/.docset/Contents/Resources/docSet.dsidx new file mode 100644 index 0000000000000000000000000000000000000000..61a2e6e7f167da726a43d9c67eb517c4472ad774 GIT binary patch literal 36864 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 literal 0 HcmV?d00001 diff --git a/docsets/.tgz b/docsets/.tgz new file mode 100644 index 0000000000000000000000000000000000000000..385accdfd86fd332e46f083b5e069c3bbb18be57 GIT binary patch literal 87317 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 ARsaA1 literal 0 HcmV?d00001 diff --git a/img/carat.png b/img/carat.png new file mode 100755 index 0000000000000000000000000000000000000000..29d2f7fd4955fca6bc6fb740e0373a2c358c398e GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRo!3HEV4DF?Wlw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6JlqAi{-jv*Ddl5#RKJQ5NTUZgiPI4RUKGIKU?u8L&ndhX1t za+0CMVUnT(Gnb}ei=c~x==tMH^F1_tBocXwcoSWoO-SZY-o>!8%^=Bms)(~h;m_U( zXNixk28L}0LS5-jKyq@#2gyS|J&f#pGCLkTc<@2s1dqeyqJ*Rc0tSIETAgmODY;(s z2y|Mcp&2}7rpBprBBB~1qM1`N+}4SoxYVPqsXi&l`rxZp{(w0iSy$Nv5*Vy!RapG^ S^0y4=eg;ohKbLh*2~7a!Pg}VF literal 0 HcmV?d00001 diff --git a/img/dash.png b/img/dash.png new file mode 100755 index 0000000000000000000000000000000000000000..6f694c7a012b417908da3687a0a39aa182e91c74 GIT binary patch literal 1338 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 literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 0000000..d27177b --- /dev/null +++ b/index.html @@ -0,0 +1,403 @@ + + + + Reference + + + + + + + + + + + + +
+
+

Docs (100% documented)

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+ +

CohesionKit - Single Source of Truth

+ +

+ swift + platforms + test + + twitter + +

+ +

Keep your models synchronized in your app and never have any inconsistency anymore. Designed using latest Swift features.

+

Why using CohesionKit?

+ +
    +
  • 🔁 You need realtime synchronisation (websockets)
  • +
  • 🌐 You have multiple data sources (REST, CoreData, websocket, phone Contacts, Google Maps, etc…)
  • +
  • 🪶 You look for a full Swift lightweight tool
  • +
  • 🗃️ You want to use structs
  • +
+

Features

+ +
    +
  • [x] 🦺 Thread safe
  • +
  • [x] 🪶 Lighweight (< 600 lines of code)
  • +
  • [x] 🪪 Working with plain Swift struct and Identifiable objects
  • +
  • [x] 🔀 Support for Combine
  • +
  • [x] 🧠 In-memory storage
  • +
  • [x] 🐾 Low memory footprint
  • +
  • [x] 🐪 Strongly typed
  • +
+

Where to put CohesionKit in my stack?

+ +

CohesionKit being a Single Source of Truth solution it handles your objects lifecycle and synchronization from any source.

+ +

You should put CohesionKit in front of your data sources (REST API, GraphQL, …) before returning data to your app.

+
sequenceDiagram
+    autonumber
+
+        YourApp ->>DataSource: findBooks
+        DataSource ->>GraphQL: query findBooks
+        GraphQL -->>DataSource: FindBooksQueryResult
+        DataSource ->>CohesionKit: store books [A,B,C]
+        CohesionKit -->> YourApp: Publisher<[A,B,C]>
+
+        WebSocket ->> WebSocketListener: book A updated
+        WebSocketListener ->> CohesionKit: update book A
+        CohesionKit -->> YourApp: Publisher<[A,B,C]>
+
+

Installation

+ +
    +
  • Swift Package Manager
  • +
+
dependencies: [
+    .package(url: "https://github.com/pjechris/CohesionKit.git", .upToNextMajor(from: "0.7.0"))
+]
+
+

Examples

+ +

Library comes with an example project so you can see a real case usage. It mostly shows:

+ +
    +
  • How to store data in the library
  • +
  • How to retrieve and update that data for realtime
  • +
  • How data is synchronised throughout multiple screens
  • +
+

Getting started

+

Storing an object

+ +

First create an instance of IdentityMap:

+
let identityMap = IdentityMap()
+
+ +

IdentityMap let you store Identifiable objects:

+
struct Book: Identifiable {
+  let id: String
+  let title: String
+}
+
+let book = Book(id: "ABCD", name: "My Book")
+
+identityMap.store(book)
+
+ +

Then You can retrieve the object from anywhere in your code:

+
// somewhere else in the code
+identityMap.find(Book.self, id: "ABCD") // return Book(id: "ABCD", name: "My Book")
+
+

Observing changes

+ +

Every time data is updated in IdentityMap triggers a notification to any registered observer. To register yourself as an observer just use result from store or find methods:

+
func findBooks() -> some Publisher<[Book], Error> {
+  // 1. load data using URLSession
+  URLSession(...)
+  // 2. store data inside our identityMap
+    .store(in: identityMap)
+    .sink { ... }
+    .store(in: &cancellables)
+}
+
+
identityMap.find(Book.self, id: 1)?
+  .asPublisher
+  .sink { ... }
+  .store(in: &cancellables)
+
+ +
+

CohesionKit has a weak memory policy you should read about. As such, returned value from identityMap.store must be strongly retained to not lose value.

+ +

For brievety, next examples will omit .sink { ... }.store(in:&cancellables).

+
+

Relational objects

+ +

To store objects containing nested identity objects you need to make them conform to one protocol: Aggregate.

+
struct AuthorBooks: Aggregate {
+  var id: Author.ID { author.id }
+
+  var author: Author
+  var books: [Book]
+
+  // `nestedEntitiesKeyPaths` must list all Identifiable/Aggregate this object contain
+  var nestedEntitiesKeyPaths: [PartialIdentifiableKeyPath<Self>] {
+    [.init(\.author), .init(\.books)]
+  }
+}
+
+ +

CohesionKit then handles synchronisation for the three entities:

+ +
    +
  • AuthorBook
  • +
+

Author

+ Author + +
    +
  • Book
  • +
+ +

This gives you the ability to retrieve them independently from each other:

+
let authorBooks = AuthorBooks(
+    author: Author(id: 1, name: "George R.R Martin"),
+    books: [
+      Book(id: "ACK", title: "A Clash of Kings"),
+      Book(id: "ADD", title: "A Dance with Dragons")
+    ]
+)
+
+identityMap.store(authorBooks)
+
+identityMap.find(Author.self, id: 1) // George R.R Martin
+identityMap.find(Book.self, id: "ACK") // A Clash of Kings
+identityMap.find(Book.self, id: "ADD") // A Dance with Dragons
+
+ +

You can also modify any of them however you want. Notice the change is visible from the object itself AND from aggregate objects:

+
let newAuthor = Author(id: 1, name: "George R.R MartinI")
+
+identityMap.store(newAuthor)
+
+identityMap.find(Author.self, id: 1) // George R.R MartinI
+identityMap.find(AuthorBooks.self, id: 1) // George R.R MartinI + [A Clash of Kings, A Dance with Dragons]
+
+ +
+

You might think about storing books on Author directly (author.books). In this case Author needs to implement Aggregate and declare books as nested entity.

+ +

However I strongly advise you to not nest Identifiable objects into other Identifiable objects. Read Handling relationships article if you want to know more about this subject.

+
+

Storing vs Updating

+ +

For now we only focused on identityMap.store but CohesionKit comes with another method to store data: identityMap.update.

+ +

Sometimes both can be used but they each have a different purpose:

+ +
    +
  1. store is suited for storing full data retrieved from webservices, like GET /user for instance
  2. +
  3. update is usually used for partial data. It’s also the preferred method when receiving events from websockets.
  4. +
+

Advanced topics

+

Enum support

+ +

Starting with 0.13 library has support for enum types. Note that you’ll need to conform to EntityEnumWrapper and provide computed getter/setter for each entity you’d like to store.

+
enum MediaType: EntityEnumWrapper {
+  case book(Book)
+  case game(Game)
+  case tvShow(TvShow)
+
+  func wrappedEntitiesKeyPaths<Root>(relativeTo parent: WritableKeyPath<Root, Self>) -> [PartialIdentifiableKeyPath<Root>] {
+    [.init(parent.appending(\.book)), .init(parent.appending(\.game)), .init(parent.appending(\.tvShow))]
+  }
+
+  var book: Book? {
+    get { ... }
+    set { ... }
+  }
+
+  var game: Game? {
+    get { ... }
+    set { ... }
+  }
+
+  var tvShow: TvShow? {
+    get { ... }
+    set { ... }
+  }
+}
+
+struct AuthorMedia: Aggregate {
+  var author: Author
+  var media: MediaType
+
+  var nestedEntitiesKeyPaths: [PartialIdentifiableKeyPath<Self>] {
+    [.init(\.author), .init(wrapper: \.media)]
+  }
+}
+
+

Aliases

+ +

Sometimes you need to retrieve data without knowing the object id. Common case is current user.

+ +

CohesionKit provides a suitable mechanism: aliases. Aliases allow you to register and find entities using a key.

+
extension AliasKey where T == User {
+  static let currentUser = AliasKey("user")
+}
+
+identityMap.store(currentUser, named: .currentUser)
+
+ +

Then request it somewhere else:

+
identityMap.find(named: .currentUser) // return the current user
+
+ +

Compared to regular entities, aliased objects are long-live objects: they will be kept in the storage even if no one observes them. This allow registered observers to be notified when alias value change:

+
identityMap.removeAlias(named: .currentUser) // observers will be notified currentUser is nil.
+
+identityMap.store(newCurrentUser, named: .currentUser) // observers will be notified that currentUser changed even if currentUser was nil before
+
+

Stale data

+ +

When storing data CohesionKit actually require you to set a modification stamp on it. Stamp is used as a marker to compare data freshness: the higher stamp is the more recent data is.

+ +

By default CohesionKit will use the current date as stamp.

+
identityMap.store(book) // use default stamp: current date
+identityMap.store(book, modifiedAt: Date().stamp) // explicitly use Date time stamp
+identityMap.store(book, modifiedAt: 9000) // any Double value is valid
+
+ +

If for some reason you try to store data with a stamp lower than the already stamped stored data then the update will be discarded.

+

Weak memory management

+ +

CohesionKit has a weak memory policy: objects are kept in IdentityMap as long as someone use them.

+ +

To that end you need to retain observers as long as you’re interested in the data:

+
let book = Book(id: "ACK", title: "A Clash of Kings")
+let cancellable = identityMap.store(book) // observer is retained: data is retained
+
+identityMap.find(Book.self, id: "ACK") // return  "A Clash of Kings"
+
+ +

If you don’t create/retain observers then once entities have no more observers they will be automatically discarded from the storage.

+
let book = Book(id: "ACK", title: "A Clash of Kings")
+_ = identityMap.store(book) // observer is not retained and no one else observe this book: data is released
+
+identityMap.find(Book.self, id: "ACK") // return nil
+
+
let book = Book(id: "ACK", title: "A Clash of Kings")
+var cancellable = identityMap.store(book).asPublisher.sink { ... }
+let cancellable2 = identityMap.find(Book.self, id: "ACK") // return a publisher
+
+cancellable = nil
+
+identityMap.find(Book.self, id: "ACK") // return "A Clash of Kings" because cancellable2 still observe this book
+
+

License

+ +

This project is released under the MIT License. Please see the LICENSE file for details.

+ +
+
+ +
+
+ + diff --git a/js/jazzy.js b/js/jazzy.js new file mode 100755 index 0000000..1984416 --- /dev/null +++ b/js/jazzy.js @@ -0,0 +1,74 @@ +// Jazzy - https://github.com/realm/jazzy +// Copyright Realm Inc. +// SPDX-License-Identifier: MIT + +window.jazzy = {'docset': false} +if (typeof window.dash != 'undefined') { + document.documentElement.className += ' dash' + window.jazzy.docset = true +} +if (navigator.userAgent.match(/xcode/i)) { + document.documentElement.className += ' xcode' + window.jazzy.docset = true +} + +function toggleItem($link, $content) { + var animationDuration = 300; + $link.toggleClass('token-open'); + $content.slideToggle(animationDuration); +} + +function itemLinkToContent($link) { + return $link.parent().parent().next(); +} + +// On doc load + hash-change, open any targetted item +function openCurrentItemIfClosed() { + if (window.jazzy.docset) { + return; + } + var $link = $(`a[name="${location.hash.substring(1)}"]`).nextAll('.token'); + $content = itemLinkToContent($link); + if ($content.is(':hidden')) { + toggleItem($link, $content); + } +} + +$(openCurrentItemIfClosed); +$(window).on('hashchange', openCurrentItemIfClosed); + +// On item link ('token') click, toggle its discussion +$('.token').on('click', function(event) { + if (window.jazzy.docset) { + return; + } + var $link = $(this); + toggleItem($link, itemLinkToContent($link)); + + // Keeps the document from jumping to the hash. + var href = $link.attr('href'); + if (history.pushState) { + history.pushState({}, '', href); + } else { + location.hash = href; + } + event.preventDefault(); +}); + +// Clicks on links to the current, closed, item need to open the item +$("a:not('.token')").on('click', function() { + if (location == this.href) { + openCurrentItemIfClosed(); + } +}); + +// KaTeX rendering +if ("katex" in window) { + $($('.math').each( (_, element) => { + katex.render(element.textContent, element, { + displayMode: $(element).hasClass('m-block'), + throwOnError: false, + trust: true + }); + })) +} diff --git a/js/jazzy.search.js b/js/jazzy.search.js new file mode 100644 index 0000000..359cdbb --- /dev/null +++ b/js/jazzy.search.js @@ -0,0 +1,74 @@ +// Jazzy - https://github.com/realm/jazzy +// Copyright Realm Inc. +// SPDX-License-Identifier: MIT + +$(function(){ + var $typeahead = $('[data-typeahead]'); + var $form = $typeahead.parents('form'); + var searchURL = $form.attr('action'); + + function displayTemplate(result) { + return result.name; + } + + function suggestionTemplate(result) { + var t = '
'; + t += '' + result.name + ''; + if (result.parent_name) { + t += '' + result.parent_name + ''; + } + t += '
'; + return t; + } + + $typeahead.one('focus', function() { + $form.addClass('loading'); + + $.getJSON(searchURL).then(function(searchData) { + const searchIndex = lunr(function() { + this.ref('url'); + this.field('name'); + this.field('abstract'); + for (const [url, doc] of Object.entries(searchData)) { + this.add({url: url, name: doc.name, abstract: doc.abstract}); + } + }); + + $typeahead.typeahead( + { + highlight: true, + minLength: 3, + autoselect: true + }, + { + limit: 10, + display: displayTemplate, + templates: { suggestion: suggestionTemplate }, + source: function(query, sync) { + const lcSearch = query.toLowerCase(); + const results = searchIndex.query(function(q) { + q.term(lcSearch, { boost: 100 }); + q.term(lcSearch, { + boost: 10, + wildcard: lunr.Query.wildcard.TRAILING + }); + }).map(function(result) { + var doc = searchData[result.ref]; + doc.url = result.ref; + return doc; + }); + sync(results); + } + } + ); + $form.removeClass('loading'); + $typeahead.trigger('focus'); + }); + }); + + var baseURL = searchURL.slice(0, -"search.json".length); + + $typeahead.on('typeahead:select', function(e, result) { + window.location = baseURL + result.url; + }); +}); diff --git a/js/jquery.min.js b/js/jquery.min.js new file mode 100644 index 0000000..7f37b5d --- /dev/null +++ b/js/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 00){var c=e.utils.clone(r)||{};c.position=[a,l],c.index=s.length,s.push(new e.Token(i.slice(a,o),c))}a=o+1}}return s},e.tokenizer.separator=/[\s\-]+/,e.Pipeline=function(){this._stack=[]},e.Pipeline.registeredFunctions=Object.create(null),e.Pipeline.registerFunction=function(t,r){r in this.registeredFunctions&&e.utils.warn("Overwriting existing registered function: "+r),t.label=r,e.Pipeline.registeredFunctions[t.label]=t},e.Pipeline.warnIfFunctionNotRegistered=function(t){var r=t.label&&t.label in this.registeredFunctions;r||e.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",t)},e.Pipeline.load=function(t){var r=new e.Pipeline;return t.forEach(function(t){var i=e.Pipeline.registeredFunctions[t];if(!i)throw new Error("Cannot load unregistered function: "+t);r.add(i)}),r},e.Pipeline.prototype.add=function(){var t=Array.prototype.slice.call(arguments);t.forEach(function(t){e.Pipeline.warnIfFunctionNotRegistered(t),this._stack.push(t)},this)},e.Pipeline.prototype.after=function(t,r){e.Pipeline.warnIfFunctionNotRegistered(r);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,r)},e.Pipeline.prototype.before=function(t,r){e.Pipeline.warnIfFunctionNotRegistered(r);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");this._stack.splice(i,0,r)},e.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);t!=-1&&this._stack.splice(t,1)},e.Pipeline.prototype.run=function(e){for(var t=this._stack.length,r=0;r1&&(se&&(r=n),s!=e);)i=r-t,n=t+Math.floor(i/2),s=this.elements[2*n];return s==e?2*n:s>e?2*n:sa?l+=2:o==a&&(t+=r[u+1]*i[l+1],u+=2,l+=2);return t},e.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},e.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,r=0;t0){var o,a=s.str.charAt(0);a in s.node.edges?o=s.node.edges[a]:(o=new e.TokenSet,s.node.edges[a]=o),1==s.str.length&&(o["final"]=!0),n.push({node:o,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(0!=s.editsRemaining){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new e.TokenSet;s.node.edges["*"]=u}if(0==s.str.length&&(u["final"]=!0),n.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&n.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),1==s.str.length&&(s.node["final"]=!0),s.str.length>=1){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new e.TokenSet;s.node.edges["*"]=l}1==s.str.length&&(l["final"]=!0),n.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var c,h=s.str.charAt(0),d=s.str.charAt(1);d in s.node.edges?c=s.node.edges[d]:(c=new e.TokenSet,s.node.edges[d]=c),1==s.str.length&&(c["final"]=!0),n.push({node:c,editsRemaining:s.editsRemaining-1,str:h+s.str.slice(2)})}}}return i},e.TokenSet.fromString=function(t){for(var r=new e.TokenSet,i=r,n=0,s=t.length;n=e;t--){var r=this.uncheckedNodes[t],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r["char"]]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}},e.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},e.Index.prototype.search=function(t){return this.query(function(r){var i=new e.QueryParser(t,r);i.parse()})},e.Index.prototype.query=function(t){for(var r=new e.Query(this.fields),i=Object.create(null),n=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u1?this._b=1:this._b=e},e.Builder.prototype.k1=function(e){this._k1=e},e.Builder.prototype.add=function(t,r){var i=t[this._ref],n=Object.keys(this._fields);this._documents[i]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return e.QueryLexer.EOS;var t=this.str.charAt(this.pos);return this.pos+=1,t},e.QueryLexer.prototype.width=function(){return this.pos-this.start},e.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},e.QueryLexer.prototype.backup=function(){this.pos-=1},e.QueryLexer.prototype.acceptDigitRun=function(){var t,r;do t=this.next(),r=t.charCodeAt(0);while(r>47&&r<58);t!=e.QueryLexer.EOS&&this.backup()},e.QueryLexer.prototype.more=function(){return this.pos1&&(t.backup(),t.emit(e.QueryLexer.TERM)),t.ignore(),t.more())return e.QueryLexer.lexText},e.QueryLexer.lexEditDistance=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.EDIT_DISTANCE),e.QueryLexer.lexText},e.QueryLexer.lexBoost=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.BOOST),e.QueryLexer.lexText},e.QueryLexer.lexEOS=function(t){t.width()>0&&t.emit(e.QueryLexer.TERM)},e.QueryLexer.termSeparator=e.tokenizer.separator,e.QueryLexer.lexText=function(t){for(;;){var r=t.next();if(r==e.QueryLexer.EOS)return e.QueryLexer.lexEOS;if(92!=r.charCodeAt(0)){if(":"==r)return e.QueryLexer.lexField;if("~"==r)return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexEditDistance;if("^"==r)return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexBoost;if("+"==r&&1===t.width())return t.emit(e.QueryLexer.PRESENCE),e.QueryLexer.lexText;if("-"==r&&1===t.width())return t.emit(e.QueryLexer.PRESENCE),e.QueryLexer.lexText;if(r.match(e.QueryLexer.termSeparator))return e.QueryLexer.lexTerm}else t.escapeCharacter()}},e.QueryParser=function(t,r){this.lexer=new e.QueryLexer(t),this.query=r,this.currentClause={},this.lexemeIdx=0},e.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var t=e.QueryParser.parseClause;t;)t=t(this);return this.query},e.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},e.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},e.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},e.QueryParser.parseClause=function(t){var r=t.peekLexeme();if(void 0!=r)switch(r.type){case e.QueryLexer.PRESENCE:return e.QueryParser.parsePresence;case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(i+=" with value '"+r.str+"'"),new e.QueryParseError(i,r.start,r.end)}},e.QueryParser.parsePresence=function(t){var r=t.consumeLexeme();if(void 0!=r){switch(r.str){case"-":t.currentClause.presence=e.Query.presence.PROHIBITED;break;case"+":t.currentClause.presence=e.Query.presence.REQUIRED;break;default:var i="unrecognised presence operator'"+r.str+"'";throw new e.QueryParseError(i,r.start,r.end)}var n=t.peekLexeme();if(void 0==n){var i="expecting term or field, found nothing";throw new e.QueryParseError(i,r.start,r.end)}switch(n.type){case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expecting term or field, found '"+n.type+"'";throw new e.QueryParseError(i,n.start,n.end)}}},e.QueryParser.parseField=function(t){var r=t.consumeLexeme();if(void 0!=r){if(t.query.allFields.indexOf(r.str)==-1){var i=t.query.allFields.map(function(e){return"'"+e+"'"}).join(", "),n="unrecognised field '"+r.str+"', possible fields: "+i;throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.fields=[r.str];var s=t.peekLexeme();if(void 0==s){var n="expecting term, found nothing";throw new e.QueryParseError(n,r.start,r.end)}switch(s.type){case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var n="expecting term, found '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},e.QueryParser.parseTerm=function(t){var r=t.consumeLexeme();if(void 0!=r){t.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(t.currentClause.usePipeline=!1);var i=t.peekLexeme();if(void 0==i)return void t.nextClause();switch(i.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+i.type+"'";throw new e.QueryParseError(n,i.start,i.end)}}},e.QueryParser.parseEditDistance=function(t){var r=t.consumeLexeme();if(void 0!=r){var i=parseInt(r.str,10);if(isNaN(i)){var n="edit distance must be numeric";throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.editDistance=i;var s=t.peekLexeme();if(void 0==s)return void t.nextClause();switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},e.QueryParser.parseBoost=function(t){var r=t.consumeLexeme();if(void 0!=r){var i=parseInt(r.str,10);if(isNaN(i)){var n="boost must be numeric";throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.boost=i;var s=t.peekLexeme();if(void 0==s)return void t.nextClause();switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():e.lunr=t()}(this,function(){return e})}(); diff --git a/js/typeahead.jquery.js b/js/typeahead.jquery.js new file mode 100644 index 0000000..3a2d2ab --- /dev/null +++ b/js/typeahead.jquery.js @@ -0,0 +1,1694 @@ +/*! + * typeahead.js 1.3.1 + * https://github.com/corejavascript/typeahead.js + * Copyright 2013-2020 Twitter, Inc. and other contributors; Licensed MIT + */ + + +(function(root, factory) { + if (typeof define === "function" && define.amd) { + define([ "jquery" ], function(a0) { + return factory(a0); + }); + } else if (typeof module === "object" && module.exports) { + module.exports = factory(require("jquery")); + } else { + factory(root["jQuery"]); + } +})(this, function($) { + var _ = function() { + "use strict"; + return { + isMsie: function() { + return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false; + }, + isBlankString: function(str) { + return !str || /^\s*$/.test(str); + }, + escapeRegExChars: function(str) { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + }, + isString: function(obj) { + return typeof obj === "string"; + }, + isNumber: function(obj) { + return typeof obj === "number"; + }, + isArray: $.isArray, + isFunction: $.isFunction, + isObject: $.isPlainObject, + isUndefined: function(obj) { + return typeof obj === "undefined"; + }, + isElement: function(obj) { + return !!(obj && obj.nodeType === 1); + }, + isJQuery: function(obj) { + return obj instanceof $; + }, + toStr: function toStr(s) { + return _.isUndefined(s) || s === null ? "" : s + ""; + }, + bind: $.proxy, + each: function(collection, cb) { + $.each(collection, reverseArgs); + function reverseArgs(index, value) { + return cb(value, index); + } + }, + map: $.map, + filter: $.grep, + every: function(obj, test) { + var result = true; + if (!obj) { + return result; + } + $.each(obj, function(key, val) { + if (!(result = test.call(null, val, key, obj))) { + return false; + } + }); + return !!result; + }, + some: function(obj, test) { + var result = false; + if (!obj) { + return result; + } + $.each(obj, function(key, val) { + if (result = test.call(null, val, key, obj)) { + return false; + } + }); + return !!result; + }, + mixin: $.extend, + identity: function(x) { + return x; + }, + clone: function(obj) { + return $.extend(true, {}, obj); + }, + getIdGenerator: function() { + var counter = 0; + return function() { + return counter++; + }; + }, + templatify: function templatify(obj) { + return $.isFunction(obj) ? obj : template; + function template() { + return String(obj); + } + }, + defer: function(fn) { + setTimeout(fn, 0); + }, + debounce: function(func, wait, immediate) { + var timeout, result; + return function() { + var context = this, args = arguments, later, callNow; + later = function() { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + } + }; + callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + } + return result; + }; + }, + throttle: function(func, wait) { + var context, args, timeout, result, previous, later; + previous = 0; + later = function() { + previous = new Date(); + timeout = null; + result = func.apply(context, args); + }; + return function() { + var now = new Date(), remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + } else if (!timeout) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }, + stringify: function(val) { + return _.isString(val) ? val : JSON.stringify(val); + }, + guid: function() { + function _p8(s) { + var p = (Math.random().toString(16) + "000000000").substr(2, 8); + return s ? "-" + p.substr(0, 4) + "-" + p.substr(4, 4) : p; + } + return "tt-" + _p8() + _p8(true) + _p8(true) + _p8(); + }, + noop: function() {} + }; + }(); + var WWW = function() { + "use strict"; + var defaultClassNames = { + wrapper: "twitter-typeahead", + input: "tt-input", + hint: "tt-hint", + menu: "tt-menu", + dataset: "tt-dataset", + suggestion: "tt-suggestion", + selectable: "tt-selectable", + empty: "tt-empty", + open: "tt-open", + cursor: "tt-cursor", + highlight: "tt-highlight" + }; + return build; + function build(o) { + var www, classes; + classes = _.mixin({}, defaultClassNames, o); + www = { + css: buildCss(), + classes: classes, + html: buildHtml(classes), + selectors: buildSelectors(classes) + }; + return { + css: www.css, + html: www.html, + classes: www.classes, + selectors: www.selectors, + mixin: function(o) { + _.mixin(o, www); + } + }; + } + function buildHtml(c) { + return { + wrapper: '', + menu: '
' + }; + } + function buildSelectors(classes) { + var selectors = {}; + _.each(classes, function(v, k) { + selectors[k] = "." + v; + }); + return selectors; + } + function buildCss() { + var css = { + wrapper: { + position: "relative", + display: "inline-block" + }, + hint: { + position: "absolute", + top: "0", + left: "0", + borderColor: "transparent", + boxShadow: "none", + opacity: "1" + }, + input: { + position: "relative", + verticalAlign: "top", + backgroundColor: "transparent" + }, + inputWithNoHint: { + position: "relative", + verticalAlign: "top" + }, + menu: { + position: "absolute", + top: "100%", + left: "0", + zIndex: "100", + display: "none" + }, + ltr: { + left: "0", + right: "auto" + }, + rtl: { + left: "auto", + right: " 0" + } + }; + if (_.isMsie()) { + _.mixin(css.input, { + backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)" + }); + } + return css; + } + }(); + var EventBus = function() { + "use strict"; + var namespace, deprecationMap; + namespace = "typeahead:"; + deprecationMap = { + render: "rendered", + cursorchange: "cursorchanged", + select: "selected", + autocomplete: "autocompleted" + }; + function EventBus(o) { + if (!o || !o.el) { + $.error("EventBus initialized without el"); + } + this.$el = $(o.el); + } + _.mixin(EventBus.prototype, { + _trigger: function(type, args) { + var $e = $.Event(namespace + type); + this.$el.trigger.call(this.$el, $e, args || []); + return $e; + }, + before: function(type) { + var args, $e; + args = [].slice.call(arguments, 1); + $e = this._trigger("before" + type, args); + return $e.isDefaultPrevented(); + }, + trigger: function(type) { + var deprecatedType; + this._trigger(type, [].slice.call(arguments, 1)); + if (deprecatedType = deprecationMap[type]) { + this._trigger(deprecatedType, [].slice.call(arguments, 1)); + } + } + }); + return EventBus; + }(); + var EventEmitter = function() { + "use strict"; + var splitter = /\s+/, nextTick = getNextTick(); + return { + onSync: onSync, + onAsync: onAsync, + off: off, + trigger: trigger + }; + function on(method, types, cb, context) { + var type; + if (!cb) { + return this; + } + types = types.split(splitter); + cb = context ? bindContext(cb, context) : cb; + this._callbacks = this._callbacks || {}; + while (type = types.shift()) { + this._callbacks[type] = this._callbacks[type] || { + sync: [], + async: [] + }; + this._callbacks[type][method].push(cb); + } + return this; + } + function onAsync(types, cb, context) { + return on.call(this, "async", types, cb, context); + } + function onSync(types, cb, context) { + return on.call(this, "sync", types, cb, context); + } + function off(types) { + var type; + if (!this._callbacks) { + return this; + } + types = types.split(splitter); + while (type = types.shift()) { + delete this._callbacks[type]; + } + return this; + } + function trigger(types) { + var type, callbacks, args, syncFlush, asyncFlush; + if (!this._callbacks) { + return this; + } + types = types.split(splitter); + args = [].slice.call(arguments, 1); + while ((type = types.shift()) && (callbacks = this._callbacks[type])) { + syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args)); + asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args)); + syncFlush() && nextTick(asyncFlush); + } + return this; + } + function getFlush(callbacks, context, args) { + return flush; + function flush() { + var cancelled; + for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) { + cancelled = callbacks[i].apply(context, args) === false; + } + return !cancelled; + } + } + function getNextTick() { + var nextTickFn; + if (window.setImmediate) { + nextTickFn = function nextTickSetImmediate(fn) { + setImmediate(function() { + fn(); + }); + }; + } else { + nextTickFn = function nextTickSetTimeout(fn) { + setTimeout(function() { + fn(); + }, 0); + }; + } + return nextTickFn; + } + function bindContext(fn, context) { + return fn.bind ? fn.bind(context) : function() { + fn.apply(context, [].slice.call(arguments, 0)); + }; + } + }(); + var highlight = function(doc) { + "use strict"; + var defaults = { + node: null, + pattern: null, + tagName: "strong", + className: null, + wordsOnly: false, + caseSensitive: false, + diacriticInsensitive: false + }; + var accented = { + A: "[AaªÀ-Åà-åĀ-ąǍǎȀ-ȃȦȧᴬᵃḀḁẚẠ-ảₐ℀℁℻⒜Ⓐⓐ㍱-㍴㎀-㎄㎈㎉㎩-㎯㏂㏊㏟㏿Aa]", + B: "[BbᴮᵇḂ-ḇℬ⒝Ⓑⓑ㍴㎅-㎇㏃㏈㏔㏝Bb]", + C: "[CcÇçĆ-čᶜ℀ℂ℃℅℆ℭⅭⅽ⒞Ⓒⓒ㍶㎈㎉㎝㎠㎤㏄-㏇Cc]", + D: "[DdĎďDŽ-džDZ-dzᴰᵈḊ-ḓⅅⅆⅮⅾ⒟Ⓓⓓ㋏㍲㍷-㍹㎗㎭-㎯㏅㏈Dd]", + E: "[EeÈ-Ëè-ëĒ-ěȄ-ȇȨȩᴱᵉḘ-ḛẸ-ẽₑ℡ℯℰⅇ⒠Ⓔⓔ㉐㋍㋎Ee]", + F: "[FfᶠḞḟ℉ℱ℻⒡Ⓕⓕ㎊-㎌㎙ff-fflFf]", + G: "[GgĜ-ģǦǧǴǵᴳᵍḠḡℊ⒢Ⓖⓖ㋌㋍㎇㎍-㎏㎓㎬㏆㏉㏒㏿Gg]", + H: "[HhĤĥȞȟʰᴴḢ-ḫẖℋ-ℎ⒣Ⓗⓗ㋌㍱㎐-㎔㏊㏋㏗Hh]", + I: "[IiÌ-Ïì-ïĨ-İIJijǏǐȈ-ȋᴵᵢḬḭỈ-ịⁱℐℑℹⅈⅠ-ⅣⅥ-ⅨⅪⅫⅰ-ⅳⅵ-ⅸⅺⅻ⒤Ⓘⓘ㍺㏌㏕fiffiIi]", + J: "[JjIJ-ĵLJ-njǰʲᴶⅉ⒥ⒿⓙⱼJj]", + K: "[KkĶķǨǩᴷᵏḰ-ḵK⒦Ⓚⓚ㎄㎅㎉㎏㎑㎘㎞㎢㎦㎪㎸㎾㏀㏆㏍-㏏Kk]", + L: "[LlĹ-ŀLJ-ljˡᴸḶḷḺ-ḽℒℓ℡Ⅼⅼ⒧Ⓛⓛ㋏㎈㎉㏐-㏓㏕㏖㏿flfflLl]", + M: "[MmᴹᵐḾ-ṃ℠™ℳⅯⅿ⒨Ⓜⓜ㍷-㍹㎃㎆㎎㎒㎖㎙-㎨㎫㎳㎷㎹㎽㎿㏁㏂㏎㏐㏔-㏖㏘㏙㏞㏟Mm]", + N: "[NnÑñŃ-ʼnNJ-njǸǹᴺṄ-ṋⁿℕ№⒩Ⓝⓝ㎁㎋㎚㎱㎵㎻㏌㏑Nn]", + O: "[OoºÒ-Öò-öŌ-őƠơǑǒǪǫȌ-ȏȮȯᴼᵒỌ-ỏₒ℅№ℴ⒪Ⓞⓞ㍵㏇㏒㏖Oo]", + P: "[PpᴾᵖṔ-ṗℙ⒫Ⓟⓟ㉐㍱㍶㎀㎊㎩-㎬㎰㎴㎺㏋㏗-㏚Pp]", + Q: "[Qqℚ⒬Ⓠⓠ㏃Qq]", + R: "[RrŔ-řȐ-ȓʳᴿᵣṘ-ṛṞṟ₨ℛ-ℝ⒭Ⓡⓡ㋍㍴㎭-㎯㏚㏛Rr]", + S: "[SsŚ-šſȘșˢṠ-ṣ₨℁℠⒮Ⓢⓢ㎧㎨㎮-㎳㏛㏜stSs]", + T: "[TtŢ-ťȚțᵀᵗṪ-ṱẗ℡™⒯Ⓣⓣ㉐㋏㎔㏏ſtstTt]", + U: "[UuÙ-Üù-üŨ-ųƯưǓǔȔ-ȗᵁᵘᵤṲ-ṷỤ-ủ℆⒰Ⓤⓤ㍳㍺Uu]", + V: "[VvᵛᵥṼ-ṿⅣ-Ⅷⅳ-ⅷ⒱Ⓥⓥⱽ㋎㍵㎴-㎹㏜㏞Vv]", + W: "[WwŴŵʷᵂẀ-ẉẘ⒲Ⓦⓦ㎺-㎿㏝Ww]", + X: "[XxˣẊ-ẍₓ℻Ⅸ-Ⅻⅸ-ⅻ⒳Ⓧⓧ㏓Xx]", + Y: "[YyÝýÿŶ-ŸȲȳʸẎẏẙỲ-ỹ⒴Ⓨⓨ㏉Yy]", + Z: "[ZzŹ-žDZ-dzᶻẐ-ẕℤℨ⒵Ⓩⓩ㎐-㎔Zz]" + }; + return function hightlight(o) { + var regex; + o = _.mixin({}, defaults, o); + if (!o.node || !o.pattern) { + return; + } + o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ]; + regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly, o.diacriticInsensitive); + traverse(o.node, hightlightTextNode); + function hightlightTextNode(textNode) { + var match, patternNode, wrapperNode; + if (match = regex.exec(textNode.data)) { + wrapperNode = doc.createElement(o.tagName); + o.className && (wrapperNode.className = o.className); + patternNode = textNode.splitText(match.index); + patternNode.splitText(match[0].length); + wrapperNode.appendChild(patternNode.cloneNode(true)); + textNode.parentNode.replaceChild(wrapperNode, patternNode); + } + return !!match; + } + function traverse(el, hightlightTextNode) { + var childNode, TEXT_NODE_TYPE = 3; + for (var i = 0; i < el.childNodes.length; i++) { + childNode = el.childNodes[i]; + if (childNode.nodeType === TEXT_NODE_TYPE) { + i += hightlightTextNode(childNode) ? 1 : 0; + } else { + traverse(childNode, hightlightTextNode); + } + } + } + }; + function accent_replacer(chr) { + return accented[chr.toUpperCase()] || chr; + } + function getRegex(patterns, caseSensitive, wordsOnly, diacriticInsensitive) { + var escapedPatterns = [], regexStr; + for (var i = 0, len = patterns.length; i < len; i++) { + var escapedWord = _.escapeRegExChars(patterns[i]); + if (diacriticInsensitive) { + escapedWord = escapedWord.replace(/\S/g, accent_replacer); + } + escapedPatterns.push(escapedWord); + } + regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")"; + return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i"); + } + }(window.document); + var Input = function() { + "use strict"; + var specialKeyCodeMap; + specialKeyCodeMap = { + 9: "tab", + 27: "esc", + 37: "left", + 39: "right", + 13: "enter", + 38: "up", + 40: "down" + }; + function Input(o, www) { + var id; + o = o || {}; + if (!o.input) { + $.error("input is missing"); + } + www.mixin(this); + this.$hint = $(o.hint); + this.$input = $(o.input); + this.$menu = $(o.menu); + id = this.$input.attr("id") || _.guid(); + this.$menu.attr("id", id + "_listbox"); + this.$hint.attr({ + "aria-hidden": true + }); + this.$input.attr({ + "aria-owns": id + "_listbox", + role: "combobox", + "aria-autocomplete": "list", + "aria-expanded": false + }); + this.query = this.$input.val(); + this.queryWhenFocused = this.hasFocus() ? this.query : null; + this.$overflowHelper = buildOverflowHelper(this.$input); + this._checkLanguageDirection(); + if (this.$hint.length === 0) { + this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop; + } + this.onSync("cursorchange", this._updateDescendent); + } + Input.normalizeQuery = function(str) { + return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " "); + }; + _.mixin(Input.prototype, EventEmitter, { + _onBlur: function onBlur() { + this.resetInputValue(); + this.trigger("blurred"); + }, + _onFocus: function onFocus() { + this.queryWhenFocused = this.query; + this.trigger("focused"); + }, + _onKeydown: function onKeydown($e) { + var keyName = specialKeyCodeMap[$e.which || $e.keyCode]; + this._managePreventDefault(keyName, $e); + if (keyName && this._shouldTrigger(keyName, $e)) { + this.trigger(keyName + "Keyed", $e); + } + }, + _onInput: function onInput() { + this._setQuery(this.getInputValue()); + this.clearHintIfInvalid(); + this._checkLanguageDirection(); + }, + _managePreventDefault: function managePreventDefault(keyName, $e) { + var preventDefault; + switch (keyName) { + case "up": + case "down": + preventDefault = !withModifier($e); + break; + + default: + preventDefault = false; + } + preventDefault && $e.preventDefault(); + }, + _shouldTrigger: function shouldTrigger(keyName, $e) { + var trigger; + switch (keyName) { + case "tab": + trigger = !withModifier($e); + break; + + default: + trigger = true; + } + return trigger; + }, + _checkLanguageDirection: function checkLanguageDirection() { + var dir = (this.$input.css("direction") || "ltr").toLowerCase(); + if (this.dir !== dir) { + this.dir = dir; + this.$hint.attr("dir", dir); + this.trigger("langDirChanged", dir); + } + }, + _setQuery: function setQuery(val, silent) { + var areEquivalent, hasDifferentWhitespace; + areEquivalent = areQueriesEquivalent(val, this.query); + hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false; + this.query = val; + if (!silent && !areEquivalent) { + this.trigger("queryChanged", this.query); + } else if (!silent && hasDifferentWhitespace) { + this.trigger("whitespaceChanged", this.query); + } + }, + _updateDescendent: function updateDescendent(event, id) { + this.$input.attr("aria-activedescendant", id); + }, + bind: function() { + var that = this, onBlur, onFocus, onKeydown, onInput; + onBlur = _.bind(this._onBlur, this); + onFocus = _.bind(this._onFocus, this); + onKeydown = _.bind(this._onKeydown, this); + onInput = _.bind(this._onInput, this); + this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown); + if (!_.isMsie() || _.isMsie() > 9) { + this.$input.on("input.tt", onInput); + } else { + this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) { + if (specialKeyCodeMap[$e.which || $e.keyCode]) { + return; + } + _.defer(_.bind(that._onInput, that, $e)); + }); + } + return this; + }, + focus: function focus() { + this.$input.focus(); + }, + blur: function blur() { + this.$input.blur(); + }, + getLangDir: function getLangDir() { + return this.dir; + }, + getQuery: function getQuery() { + return this.query || ""; + }, + setQuery: function setQuery(val, silent) { + this.setInputValue(val); + this._setQuery(val, silent); + }, + hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() { + return this.query !== this.queryWhenFocused; + }, + getInputValue: function getInputValue() { + return this.$input.val(); + }, + setInputValue: function setInputValue(value) { + this.$input.val(value); + this.clearHintIfInvalid(); + this._checkLanguageDirection(); + }, + resetInputValue: function resetInputValue() { + this.setInputValue(this.query); + }, + getHint: function getHint() { + return this.$hint.val(); + }, + setHint: function setHint(value) { + this.$hint.val(value); + }, + clearHint: function clearHint() { + this.setHint(""); + }, + clearHintIfInvalid: function clearHintIfInvalid() { + var val, hint, valIsPrefixOfHint, isValid; + val = this.getInputValue(); + hint = this.getHint(); + valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0; + isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow(); + !isValid && this.clearHint(); + }, + hasFocus: function hasFocus() { + return this.$input.is(":focus"); + }, + hasOverflow: function hasOverflow() { + var constraint = this.$input.width() - 2; + this.$overflowHelper.text(this.getInputValue()); + return this.$overflowHelper.width() >= constraint; + }, + isCursorAtEnd: function() { + var valueLength, selectionStart, range; + valueLength = this.$input.val().length; + selectionStart = this.$input[0].selectionStart; + if (_.isNumber(selectionStart)) { + return selectionStart === valueLength; + } else if (document.selection) { + range = document.selection.createRange(); + range.moveStart("character", -valueLength); + return valueLength === range.text.length; + } + return true; + }, + destroy: function destroy() { + this.$hint.off(".tt"); + this.$input.off(".tt"); + this.$overflowHelper.remove(); + this.$hint = this.$input = this.$overflowHelper = $("
"); + }, + setAriaExpanded: function setAriaExpanded(value) { + this.$input.attr("aria-expanded", value); + } + }); + return Input; + function buildOverflowHelper($input) { + return $('').css({ + position: "absolute", + visibility: "hidden", + whiteSpace: "pre", + fontFamily: $input.css("font-family"), + fontSize: $input.css("font-size"), + fontStyle: $input.css("font-style"), + fontVariant: $input.css("font-variant"), + fontWeight: $input.css("font-weight"), + wordSpacing: $input.css("word-spacing"), + letterSpacing: $input.css("letter-spacing"), + textIndent: $input.css("text-indent"), + textRendering: $input.css("text-rendering"), + textTransform: $input.css("text-transform") + }).insertAfter($input); + } + function areQueriesEquivalent(a, b) { + return Input.normalizeQuery(a) === Input.normalizeQuery(b); + } + function withModifier($e) { + return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey; + } + }(); + var Dataset = function() { + "use strict"; + var keys, nameGenerator; + keys = { + dataset: "tt-selectable-dataset", + val: "tt-selectable-display", + obj: "tt-selectable-object" + }; + nameGenerator = _.getIdGenerator(); + function Dataset(o, www) { + o = o || {}; + o.templates = o.templates || {}; + o.templates.notFound = o.templates.notFound || o.templates.empty; + if (!o.source) { + $.error("missing source"); + } + if (!o.node) { + $.error("missing node"); + } + if (o.name && !isValidName(o.name)) { + $.error("invalid dataset name: " + o.name); + } + www.mixin(this); + this.highlight = !!o.highlight; + this.name = _.toStr(o.name || nameGenerator()); + this.limit = o.limit || 5; + this.displayFn = getDisplayFn(o.display || o.displayKey); + this.templates = getTemplates(o.templates, this.displayFn); + this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source; + this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async; + this._resetLastSuggestion(); + this.$el = $(o.node).attr("role", "presentation").addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name); + } + Dataset.extractData = function extractData(el) { + var $el = $(el); + if ($el.data(keys.obj)) { + return { + dataset: $el.data(keys.dataset) || "", + val: $el.data(keys.val) || "", + obj: $el.data(keys.obj) || null + }; + } + return null; + }; + _.mixin(Dataset.prototype, EventEmitter, { + _overwrite: function overwrite(query, suggestions) { + suggestions = suggestions || []; + if (suggestions.length) { + this._renderSuggestions(query, suggestions); + } else if (this.async && this.templates.pending) { + this._renderPending(query); + } else if (!this.async && this.templates.notFound) { + this._renderNotFound(query); + } else { + this._empty(); + } + this.trigger("rendered", suggestions, false, this.name); + }, + _append: function append(query, suggestions) { + suggestions = suggestions || []; + if (suggestions.length && this.$lastSuggestion.length) { + this._appendSuggestions(query, suggestions); + } else if (suggestions.length) { + this._renderSuggestions(query, suggestions); + } else if (!this.$lastSuggestion.length && this.templates.notFound) { + this._renderNotFound(query); + } + this.trigger("rendered", suggestions, true, this.name); + }, + _renderSuggestions: function renderSuggestions(query, suggestions) { + var $fragment; + $fragment = this._getSuggestionsFragment(query, suggestions); + this.$lastSuggestion = $fragment.children().last(); + this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions)); + }, + _appendSuggestions: function appendSuggestions(query, suggestions) { + var $fragment, $lastSuggestion; + $fragment = this._getSuggestionsFragment(query, suggestions); + $lastSuggestion = $fragment.children().last(); + this.$lastSuggestion.after($fragment); + this.$lastSuggestion = $lastSuggestion; + }, + _renderPending: function renderPending(query) { + var template = this.templates.pending; + this._resetLastSuggestion(); + template && this.$el.html(template({ + query: query, + dataset: this.name + })); + }, + _renderNotFound: function renderNotFound(query) { + var template = this.templates.notFound; + this._resetLastSuggestion(); + template && this.$el.html(template({ + query: query, + dataset: this.name + })); + }, + _empty: function empty() { + this.$el.empty(); + this._resetLastSuggestion(); + }, + _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) { + var that = this, fragment; + fragment = document.createDocumentFragment(); + _.each(suggestions, function getSuggestionNode(suggestion) { + var $el, context; + context = that._injectQuery(query, suggestion); + $el = $(that.templates.suggestion(context)).data(keys.dataset, that.name).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable); + fragment.appendChild($el[0]); + }); + this.highlight && highlight({ + className: this.classes.highlight, + node: fragment, + pattern: query + }); + return $(fragment); + }, + _getFooter: function getFooter(query, suggestions) { + return this.templates.footer ? this.templates.footer({ + query: query, + suggestions: suggestions, + dataset: this.name + }) : null; + }, + _getHeader: function getHeader(query, suggestions) { + return this.templates.header ? this.templates.header({ + query: query, + suggestions: suggestions, + dataset: this.name + }) : null; + }, + _resetLastSuggestion: function resetLastSuggestion() { + this.$lastSuggestion = $(); + }, + _injectQuery: function injectQuery(query, obj) { + return _.isObject(obj) ? _.mixin({ + _query: query + }, obj) : obj; + }, + update: function update(query) { + var that = this, canceled = false, syncCalled = false, rendered = 0; + this.cancel(); + this.cancel = function cancel() { + canceled = true; + that.cancel = $.noop; + that.async && that.trigger("asyncCanceled", query, that.name); + }; + this.source(query, sync, async); + !syncCalled && sync([]); + function sync(suggestions) { + if (syncCalled) { + return; + } + syncCalled = true; + suggestions = (suggestions || []).slice(0, that.limit); + rendered = suggestions.length; + that._overwrite(query, suggestions); + if (rendered < that.limit && that.async) { + that.trigger("asyncRequested", query, that.name); + } + } + function async(suggestions) { + suggestions = suggestions || []; + if (!canceled && rendered < that.limit) { + that.cancel = $.noop; + var idx = Math.abs(rendered - that.limit); + rendered += idx; + that._append(query, suggestions.slice(0, idx)); + that.async && that.trigger("asyncReceived", query, that.name); + } + } + }, + cancel: $.noop, + clear: function clear() { + this._empty(); + this.cancel(); + this.trigger("cleared"); + }, + isEmpty: function isEmpty() { + return this.$el.is(":empty"); + }, + destroy: function destroy() { + this.$el = $("
"); + } + }); + return Dataset; + function getDisplayFn(display) { + display = display || _.stringify; + return _.isFunction(display) ? display : displayFn; + function displayFn(obj) { + return obj[display]; + } + } + function getTemplates(templates, displayFn) { + return { + notFound: templates.notFound && _.templatify(templates.notFound), + pending: templates.pending && _.templatify(templates.pending), + header: templates.header && _.templatify(templates.header), + footer: templates.footer && _.templatify(templates.footer), + suggestion: templates.suggestion ? userSuggestionTemplate : suggestionTemplate + }; + function userSuggestionTemplate(context) { + var template = templates.suggestion; + return $(template(context)).attr("id", _.guid()); + } + function suggestionTemplate(context) { + return $('
').attr("id", _.guid()).text(displayFn(context)); + } + } + function isValidName(str) { + return /^[_a-zA-Z0-9-]+$/.test(str); + } + }(); + var Menu = function() { + "use strict"; + function Menu(o, www) { + var that = this; + o = o || {}; + if (!o.node) { + $.error("node is required"); + } + www.mixin(this); + this.$node = $(o.node); + this.query = null; + this.datasets = _.map(o.datasets, initializeDataset); + function initializeDataset(oDataset) { + var node = that.$node.find(oDataset.node).first(); + oDataset.node = node.length ? node : $("
").appendTo(that.$node); + return new Dataset(oDataset, www); + } + } + _.mixin(Menu.prototype, EventEmitter, { + _onSelectableClick: function onSelectableClick($e) { + this.trigger("selectableClicked", $($e.currentTarget)); + }, + _onRendered: function onRendered(type, dataset, suggestions, async) { + this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty()); + this.trigger("datasetRendered", dataset, suggestions, async); + }, + _onCleared: function onCleared() { + this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty()); + this.trigger("datasetCleared"); + }, + _propagate: function propagate() { + this.trigger.apply(this, arguments); + }, + _allDatasetsEmpty: function allDatasetsEmpty() { + return _.every(this.datasets, _.bind(function isDatasetEmpty(dataset) { + var isEmpty = dataset.isEmpty(); + this.$node.attr("aria-expanded", !isEmpty); + return isEmpty; + }, this)); + }, + _getSelectables: function getSelectables() { + return this.$node.find(this.selectors.selectable); + }, + _removeCursor: function _removeCursor() { + var $selectable = this.getActiveSelectable(); + $selectable && $selectable.removeClass(this.classes.cursor); + }, + _ensureVisible: function ensureVisible($el) { + var elTop, elBottom, nodeScrollTop, nodeHeight; + elTop = $el.position().top; + elBottom = elTop + $el.outerHeight(true); + nodeScrollTop = this.$node.scrollTop(); + nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10); + if (elTop < 0) { + this.$node.scrollTop(nodeScrollTop + elTop); + } else if (nodeHeight < elBottom) { + this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight)); + } + }, + bind: function() { + var that = this, onSelectableClick; + onSelectableClick = _.bind(this._onSelectableClick, this); + this.$node.on("click.tt", this.selectors.selectable, onSelectableClick); + this.$node.on("mouseover", this.selectors.selectable, function() { + that.setCursor($(this)); + }); + this.$node.on("mouseleave", function() { + that._removeCursor(); + }); + _.each(this.datasets, function(dataset) { + dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that); + }); + return this; + }, + isOpen: function isOpen() { + return this.$node.hasClass(this.classes.open); + }, + open: function open() { + this.$node.scrollTop(0); + this.$node.addClass(this.classes.open); + }, + close: function close() { + this.$node.attr("aria-expanded", false); + this.$node.removeClass(this.classes.open); + this._removeCursor(); + }, + setLanguageDirection: function setLanguageDirection(dir) { + this.$node.attr("dir", dir); + }, + selectableRelativeToCursor: function selectableRelativeToCursor(delta) { + var $selectables, $oldCursor, oldIndex, newIndex; + $oldCursor = this.getActiveSelectable(); + $selectables = this._getSelectables(); + oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1; + newIndex = oldIndex + delta; + newIndex = (newIndex + 1) % ($selectables.length + 1) - 1; + newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex; + return newIndex === -1 ? null : $selectables.eq(newIndex); + }, + setCursor: function setCursor($selectable) { + this._removeCursor(); + if ($selectable = $selectable && $selectable.first()) { + $selectable.addClass(this.classes.cursor); + this._ensureVisible($selectable); + } + }, + getSelectableData: function getSelectableData($el) { + return $el && $el.length ? Dataset.extractData($el) : null; + }, + getActiveSelectable: function getActiveSelectable() { + var $selectable = this._getSelectables().filter(this.selectors.cursor).first(); + return $selectable.length ? $selectable : null; + }, + getTopSelectable: function getTopSelectable() { + var $selectable = this._getSelectables().first(); + return $selectable.length ? $selectable : null; + }, + update: function update(query) { + var isValidUpdate = query !== this.query; + if (isValidUpdate) { + this.query = query; + _.each(this.datasets, updateDataset); + } + return isValidUpdate; + function updateDataset(dataset) { + dataset.update(query); + } + }, + empty: function empty() { + _.each(this.datasets, clearDataset); + this.query = null; + this.$node.addClass(this.classes.empty); + function clearDataset(dataset) { + dataset.clear(); + } + }, + destroy: function destroy() { + this.$node.off(".tt"); + this.$node = $("
"); + _.each(this.datasets, destroyDataset); + function destroyDataset(dataset) { + dataset.destroy(); + } + } + }); + return Menu; + }(); + var Status = function() { + "use strict"; + function Status(options) { + this.$el = $("", { + role: "status", + "aria-live": "polite" + }).css({ + position: "absolute", + padding: "0", + border: "0", + height: "1px", + width: "1px", + "margin-bottom": "-1px", + "margin-right": "-1px", + overflow: "hidden", + clip: "rect(0 0 0 0)", + "white-space": "nowrap" + }); + options.$input.after(this.$el); + _.each(options.menu.datasets, _.bind(function(dataset) { + if (dataset.onSync) { + dataset.onSync("rendered", _.bind(this.update, this)); + dataset.onSync("cleared", _.bind(this.cleared, this)); + } + }, this)); + } + _.mixin(Status.prototype, { + update: function update(event, suggestions) { + var length = suggestions.length; + var words; + if (length === 1) { + words = { + result: "result", + is: "is" + }; + } else { + words = { + result: "results", + is: "are" + }; + } + this.$el.text(length + " " + words.result + " " + words.is + " available, use up and down arrow keys to navigate."); + }, + cleared: function() { + this.$el.text(""); + } + }); + return Status; + }(); + var DefaultMenu = function() { + "use strict"; + var s = Menu.prototype; + function DefaultMenu() { + Menu.apply(this, [].slice.call(arguments, 0)); + } + _.mixin(DefaultMenu.prototype, Menu.prototype, { + open: function open() { + !this._allDatasetsEmpty() && this._show(); + return s.open.apply(this, [].slice.call(arguments, 0)); + }, + close: function close() { + this._hide(); + return s.close.apply(this, [].slice.call(arguments, 0)); + }, + _onRendered: function onRendered() { + if (this._allDatasetsEmpty()) { + this._hide(); + } else { + this.isOpen() && this._show(); + } + return s._onRendered.apply(this, [].slice.call(arguments, 0)); + }, + _onCleared: function onCleared() { + if (this._allDatasetsEmpty()) { + this._hide(); + } else { + this.isOpen() && this._show(); + } + return s._onCleared.apply(this, [].slice.call(arguments, 0)); + }, + setLanguageDirection: function setLanguageDirection(dir) { + this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl); + return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0)); + }, + _hide: function hide() { + this.$node.hide(); + }, + _show: function show() { + this.$node.css("display", "block"); + } + }); + return DefaultMenu; + }(); + var Typeahead = function() { + "use strict"; + function Typeahead(o, www) { + var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged; + o = o || {}; + if (!o.input) { + $.error("missing input"); + } + if (!o.menu) { + $.error("missing menu"); + } + if (!o.eventBus) { + $.error("missing event bus"); + } + www.mixin(this); + this.eventBus = o.eventBus; + this.minLength = _.isNumber(o.minLength) ? o.minLength : 1; + this.input = o.input; + this.menu = o.menu; + this.enabled = true; + this.autoselect = !!o.autoselect; + this.active = false; + this.input.hasFocus() && this.activate(); + this.dir = this.input.getLangDir(); + this._hacks(); + this.menu.bind().onSync("selectableClicked", this._onSelectableClicked, this).onSync("asyncRequested", this._onAsyncRequested, this).onSync("asyncCanceled", this._onAsyncCanceled, this).onSync("asyncReceived", this._onAsyncReceived, this).onSync("datasetRendered", this._onDatasetRendered, this).onSync("datasetCleared", this._onDatasetCleared, this); + onFocused = c(this, "activate", "open", "_onFocused"); + onBlurred = c(this, "deactivate", "_onBlurred"); + onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed"); + onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed"); + onEscKeyed = c(this, "isActive", "_onEscKeyed"); + onUpKeyed = c(this, "isActive", "open", "_onUpKeyed"); + onDownKeyed = c(this, "isActive", "open", "_onDownKeyed"); + onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed"); + onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed"); + onQueryChanged = c(this, "_openIfActive", "_onQueryChanged"); + onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged"); + this.input.bind().onSync("focused", onFocused, this).onSync("blurred", onBlurred, this).onSync("enterKeyed", onEnterKeyed, this).onSync("tabKeyed", onTabKeyed, this).onSync("escKeyed", onEscKeyed, this).onSync("upKeyed", onUpKeyed, this).onSync("downKeyed", onDownKeyed, this).onSync("leftKeyed", onLeftKeyed, this).onSync("rightKeyed", onRightKeyed, this).onSync("queryChanged", onQueryChanged, this).onSync("whitespaceChanged", onWhitespaceChanged, this).onSync("langDirChanged", this._onLangDirChanged, this); + } + _.mixin(Typeahead.prototype, { + _hacks: function hacks() { + var $input, $menu; + $input = this.input.$input || $("
"); + $menu = this.menu.$node || $("
"); + $input.on("blur.tt", function($e) { + var active, isActive, hasActive; + active = document.activeElement; + isActive = $menu.is(active); + hasActive = $menu.has(active).length > 0; + if (_.isMsie() && (isActive || hasActive)) { + $e.preventDefault(); + $e.stopImmediatePropagation(); + _.defer(function() { + $input.focus(); + }); + } + }); + $menu.on("mousedown.tt", function($e) { + $e.preventDefault(); + }); + }, + _onSelectableClicked: function onSelectableClicked(type, $el) { + this.select($el); + }, + _onDatasetCleared: function onDatasetCleared() { + this._updateHint(); + }, + _onDatasetRendered: function onDatasetRendered(type, suggestions, async, dataset) { + this._updateHint(); + if (this.autoselect) { + var cursorClass = this.selectors.cursor.substr(1); + this.menu.$node.find(this.selectors.suggestion).first().addClass(cursorClass); + } + this.eventBus.trigger("render", suggestions, async, dataset); + }, + _onAsyncRequested: function onAsyncRequested(type, dataset, query) { + this.eventBus.trigger("asyncrequest", query, dataset); + }, + _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) { + this.eventBus.trigger("asynccancel", query, dataset); + }, + _onAsyncReceived: function onAsyncReceived(type, dataset, query) { + this.eventBus.trigger("asyncreceive", query, dataset); + }, + _onFocused: function onFocused() { + this._minLengthMet() && this.menu.update(this.input.getQuery()); + }, + _onBlurred: function onBlurred() { + if (this.input.hasQueryChangedSinceLastFocus()) { + this.eventBus.trigger("change", this.input.getQuery()); + } + }, + _onEnterKeyed: function onEnterKeyed(type, $e) { + var $selectable; + if ($selectable = this.menu.getActiveSelectable()) { + if (this.select($selectable)) { + $e.preventDefault(); + $e.stopPropagation(); + } + } else if (this.autoselect) { + if (this.select(this.menu.getTopSelectable())) { + $e.preventDefault(); + $e.stopPropagation(); + } + } + }, + _onTabKeyed: function onTabKeyed(type, $e) { + var $selectable; + if ($selectable = this.menu.getActiveSelectable()) { + this.select($selectable) && $e.preventDefault(); + } else if (this.autoselect) { + if ($selectable = this.menu.getTopSelectable()) { + this.autocomplete($selectable) && $e.preventDefault(); + } + } + }, + _onEscKeyed: function onEscKeyed() { + this.close(); + }, + _onUpKeyed: function onUpKeyed() { + this.moveCursor(-1); + }, + _onDownKeyed: function onDownKeyed() { + this.moveCursor(+1); + }, + _onLeftKeyed: function onLeftKeyed() { + if (this.dir === "rtl" && this.input.isCursorAtEnd()) { + this.autocomplete(this.menu.getActiveSelectable() || this.menu.getTopSelectable()); + } + }, + _onRightKeyed: function onRightKeyed() { + if (this.dir === "ltr" && this.input.isCursorAtEnd()) { + this.autocomplete(this.menu.getActiveSelectable() || this.menu.getTopSelectable()); + } + }, + _onQueryChanged: function onQueryChanged(e, query) { + this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty(); + }, + _onWhitespaceChanged: function onWhitespaceChanged() { + this._updateHint(); + }, + _onLangDirChanged: function onLangDirChanged(e, dir) { + if (this.dir !== dir) { + this.dir = dir; + this.menu.setLanguageDirection(dir); + } + }, + _openIfActive: function openIfActive() { + this.isActive() && this.open(); + }, + _minLengthMet: function minLengthMet(query) { + query = _.isString(query) ? query : this.input.getQuery() || ""; + return query.length >= this.minLength; + }, + _updateHint: function updateHint() { + var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match; + $selectable = this.menu.getTopSelectable(); + data = this.menu.getSelectableData($selectable); + val = this.input.getInputValue(); + if (data && !_.isBlankString(val) && !this.input.hasOverflow()) { + query = Input.normalizeQuery(val); + escapedQuery = _.escapeRegExChars(query); + frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i"); + match = frontMatchRegEx.exec(data.val); + match && this.input.setHint(val + match[1]); + } else { + this.input.clearHint(); + } + }, + isEnabled: function isEnabled() { + return this.enabled; + }, + enable: function enable() { + this.enabled = true; + }, + disable: function disable() { + this.enabled = false; + }, + isActive: function isActive() { + return this.active; + }, + activate: function activate() { + if (this.isActive()) { + return true; + } else if (!this.isEnabled() || this.eventBus.before("active")) { + return false; + } else { + this.active = true; + this.eventBus.trigger("active"); + return true; + } + }, + deactivate: function deactivate() { + if (!this.isActive()) { + return true; + } else if (this.eventBus.before("idle")) { + return false; + } else { + this.active = false; + this.close(); + this.eventBus.trigger("idle"); + return true; + } + }, + isOpen: function isOpen() { + return this.menu.isOpen(); + }, + open: function open() { + if (!this.isOpen() && !this.eventBus.before("open")) { + this.input.setAriaExpanded(true); + this.menu.open(); + this._updateHint(); + this.eventBus.trigger("open"); + } + return this.isOpen(); + }, + close: function close() { + if (this.isOpen() && !this.eventBus.before("close")) { + this.input.setAriaExpanded(false); + this.menu.close(); + this.input.clearHint(); + this.input.resetInputValue(); + this.eventBus.trigger("close"); + } + return !this.isOpen(); + }, + setVal: function setVal(val) { + this.input.setQuery(_.toStr(val)); + }, + getVal: function getVal() { + return this.input.getQuery(); + }, + select: function select($selectable) { + var data = this.menu.getSelectableData($selectable); + if (data && !this.eventBus.before("select", data.obj, data.dataset)) { + this.input.setQuery(data.val, true); + this.eventBus.trigger("select", data.obj, data.dataset); + this.close(); + return true; + } + return false; + }, + autocomplete: function autocomplete($selectable) { + var query, data, isValid; + query = this.input.getQuery(); + data = this.menu.getSelectableData($selectable); + isValid = data && query !== data.val; + if (isValid && !this.eventBus.before("autocomplete", data.obj, data.dataset)) { + this.input.setQuery(data.val); + this.eventBus.trigger("autocomplete", data.obj, data.dataset); + return true; + } + return false; + }, + moveCursor: function moveCursor(delta) { + var query, $candidate, data, suggestion, datasetName, cancelMove, id; + query = this.input.getQuery(); + $candidate = this.menu.selectableRelativeToCursor(delta); + data = this.menu.getSelectableData($candidate); + suggestion = data ? data.obj : null; + datasetName = data ? data.dataset : null; + id = $candidate ? $candidate.attr("id") : null; + this.input.trigger("cursorchange", id); + cancelMove = this._minLengthMet() && this.menu.update(query); + if (!cancelMove && !this.eventBus.before("cursorchange", suggestion, datasetName)) { + this.menu.setCursor($candidate); + if (data) { + if (typeof data.val === "string") { + this.input.setInputValue(data.val); + } + } else { + this.input.resetInputValue(); + this._updateHint(); + } + this.eventBus.trigger("cursorchange", suggestion, datasetName); + return true; + } + return false; + }, + destroy: function destroy() { + this.input.destroy(); + this.menu.destroy(); + } + }); + return Typeahead; + function c(ctx) { + var methods = [].slice.call(arguments, 1); + return function() { + var args = [].slice.call(arguments); + _.each(methods, function(method) { + return ctx[method].apply(ctx, args); + }); + }; + } + }(); + (function() { + "use strict"; + var old, keys, methods; + old = $.fn.typeahead; + keys = { + www: "tt-www", + attrs: "tt-attrs", + typeahead: "tt-typeahead" + }; + methods = { + initialize: function initialize(o, datasets) { + var www; + datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1); + o = o || {}; + www = WWW(o.classNames); + return this.each(attach); + function attach() { + var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, status, typeahead, MenuConstructor; + _.each(datasets, function(d) { + d.highlight = !!o.highlight; + }); + $input = $(this); + $wrapper = $(www.html.wrapper); + $hint = $elOrNull(o.hint); + $menu = $elOrNull(o.menu); + defaultHint = o.hint !== false && !$hint; + defaultMenu = o.menu !== false && !$menu; + defaultHint && ($hint = buildHintFromInput($input, www)); + defaultMenu && ($menu = $(www.html.menu).css(www.css.menu)); + $hint && $hint.val(""); + $input = prepInput($input, www); + if (defaultHint || defaultMenu) { + $wrapper.css(www.css.wrapper); + $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint); + $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null); + } + MenuConstructor = defaultMenu ? DefaultMenu : Menu; + eventBus = new EventBus({ + el: $input + }); + input = new Input({ + hint: $hint, + input: $input, + menu: $menu + }, www); + menu = new MenuConstructor({ + node: $menu, + datasets: datasets + }, www); + status = new Status({ + $input: $input, + menu: menu + }); + typeahead = new Typeahead({ + input: input, + menu: menu, + eventBus: eventBus, + minLength: o.minLength, + autoselect: o.autoselect + }, www); + $input.data(keys.www, www); + $input.data(keys.typeahead, typeahead); + } + }, + isEnabled: function isEnabled() { + var enabled; + ttEach(this.first(), function(t) { + enabled = t.isEnabled(); + }); + return enabled; + }, + enable: function enable() { + ttEach(this, function(t) { + t.enable(); + }); + return this; + }, + disable: function disable() { + ttEach(this, function(t) { + t.disable(); + }); + return this; + }, + isActive: function isActive() { + var active; + ttEach(this.first(), function(t) { + active = t.isActive(); + }); + return active; + }, + activate: function activate() { + ttEach(this, function(t) { + t.activate(); + }); + return this; + }, + deactivate: function deactivate() { + ttEach(this, function(t) { + t.deactivate(); + }); + return this; + }, + isOpen: function isOpen() { + var open; + ttEach(this.first(), function(t) { + open = t.isOpen(); + }); + return open; + }, + open: function open() { + ttEach(this, function(t) { + t.open(); + }); + return this; + }, + close: function close() { + ttEach(this, function(t) { + t.close(); + }); + return this; + }, + select: function select(el) { + var success = false, $el = $(el); + ttEach(this.first(), function(t) { + success = t.select($el); + }); + return success; + }, + autocomplete: function autocomplete(el) { + var success = false, $el = $(el); + ttEach(this.first(), function(t) { + success = t.autocomplete($el); + }); + return success; + }, + moveCursor: function moveCursoe(delta) { + var success = false; + ttEach(this.first(), function(t) { + success = t.moveCursor(delta); + }); + return success; + }, + val: function val(newVal) { + var query; + if (!arguments.length) { + ttEach(this.first(), function(t) { + query = t.getVal(); + }); + return query; + } else { + ttEach(this, function(t) { + t.setVal(_.toStr(newVal)); + }); + return this; + } + }, + destroy: function destroy() { + ttEach(this, function(typeahead, $input) { + revert($input); + typeahead.destroy(); + }); + return this; + } + }; + $.fn.typeahead = function(method) { + if (methods[method]) { + return methods[method].apply(this, [].slice.call(arguments, 1)); + } else { + return methods.initialize.apply(this, arguments); + } + }; + $.fn.typeahead.noConflict = function noConflict() { + $.fn.typeahead = old; + return this; + }; + function ttEach($els, fn) { + $els.each(function() { + var $input = $(this), typeahead; + (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input); + }); + } + function buildHintFromInput($input, www) { + return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop({ + readonly: true, + required: false + }).removeAttr("id name placeholder").removeClass("required").attr({ + spellcheck: "false", + tabindex: -1 + }); + } + function prepInput($input, www) { + $input.data(keys.attrs, { + dir: $input.attr("dir"), + autocomplete: $input.attr("autocomplete"), + spellcheck: $input.attr("spellcheck"), + style: $input.attr("style") + }); + $input.addClass(www.classes.input).attr({ + spellcheck: false + }); + try { + !$input.attr("dir") && $input.attr("dir", "auto"); + } catch (e) {} + return $input; + } + function getBackgroundStyles($el) { + return { + backgroundAttachment: $el.css("background-attachment"), + backgroundClip: $el.css("background-clip"), + backgroundColor: $el.css("background-color"), + backgroundImage: $el.css("background-image"), + backgroundOrigin: $el.css("background-origin"), + backgroundPosition: $el.css("background-position"), + backgroundRepeat: $el.css("background-repeat"), + backgroundSize: $el.css("background-size") + }; + } + function revert($input) { + var www, $wrapper; + www = $input.data(keys.www); + $wrapper = $input.parent().filter(www.selectors.wrapper); + _.each($input.data(keys.attrs), function(val, key) { + _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val); + }); + $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input); + if ($wrapper.length) { + $input.detach().insertAfter($wrapper); + $wrapper.remove(); + } + } + function $elOrNull(obj) { + var isValid, $el; + isValid = _.isJQuery(obj) || _.isElement(obj); + $el = isValid ? $(obj).first() : []; + return $el.length ? $el : null; + } + })(); +}); \ No newline at end of file diff --git a/search.json b/search.json new file mode 100644 index 0000000..3e4681a --- /dev/null +++ b/search.json @@ -0,0 +1 @@ +{"Typealiases.html#/s:11CohesionKit5Stampa":{"name":"Stamp","abstract":"

A type used to annotate track object modifications through time."},"Structs/EntityObserver.html#/s:11CohesionKit14EntityObserverV8OnChangea":{"name":"OnChange","parent_name":"EntityObserver"},"Structs/EntityObserver.html#/s:11CohesionKit8ObserverP5value1TQzvp":{"name":"value","parent_name":"EntityObserver"},"Structs/EntityObserver.html#/s:11CohesionKit8ObserverP7observe8onChangeAA12SubscriptionCy1TQzc_tF":{"name":"observe(onChange:)","parent_name":"EntityObserver"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__Gcs0D0Rd__lufc":{"name":"init(_:)","abstract":"

Creates an instance referencing an Identifiable keyPath

","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__GcAA9AggregateRd__lufc":{"name":"init(_:)","abstract":"

Creates an instance referencing an Aggregate keyPath

","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__SgGcs0D0Rd__lufc":{"name":"init(_:)","abstract":"

Creates an instance referencing an optional Identifiable keyPath

","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__SgGcAA9AggregateRd__lufc":{"name":"init(_:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__GcSMRd__s0D07ElementRpd__SH5IndexRpd__lufc":{"name":"init(_:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__SgGcSMRd__s0D07ElementRpd__SH5IndexRpd__lufc":{"name":"init(_:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__GcSMRd__AA9Aggregate7ElementRpd__SH5IndexRpd__lufc":{"name":"init(_:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathVyACyxGs08WritableeF0Cyxqd__SgGcSMRd__AA9Aggregate7ElementRpd__SH5IndexRpd__lufc":{"name":"init(_:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathV7wrapperACyxGs08WritableeF0Cyxqd__G_tcAA17EntityEnumWrapperRd__lufc":{"name":"init(wrapper:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/PartialIdentifiableKeyPath.html#/s:11CohesionKit26PartialIdentifiableKeyPathV7wrapperACyxGs08WritableeF0Cyxqd__SgG_tcAA17EntityEnumWrapperRd__lufc":{"name":"init(wrapper:)","parent_name":"PartialIdentifiableKeyPath"},"Structs/AliasKey.html#/s:11CohesionKit8AliasKeyV5namedACyxGSS_tcfc":{"name":"init(named:)","parent_name":"AliasKey"},"Structs/AliasKey.html":{"name":"AliasKey","abstract":"

A value representing an Entity or set of Entity

"},"Structs/PartialIdentifiableKeyPath.html":{"name":"PartialIdentifiableKeyPath","abstract":"

A KeyPath wrapper allowing only Identifiable/Aggregate keypaths

"},"Structs/EntityObserver.html":{"name":"EntityObserver","abstract":"

A type registering observers on a given entity from identity storage

"},"Protocols/Logger.html#/s:11CohesionKit6LoggerP8didStore_2idyqd__m_2IDQyd__ts12IdentifiableRd__lF":{"name":"didStore(_:id:)","abstract":"

Notify when an entity was stored in the identity map

","parent_name":"Logger"},"Protocols/Logger.html#/s:11CohesionKit6LoggerP16didFailedToStore_2id5erroryqd__m_2IDQyd__s5Error_pts12IdentifiableRd__lF":{"name":"didFailedToStore(_:id:error:)","parent_name":"Logger"},"Protocols/Logger.html#/s:11CohesionKit6LoggerP16didRegisterAliasyyAA0F3KeyVyqd__GlF":{"name":"didRegisterAlias(_:)","abstract":"

Notify an alias is registered with new entities

","parent_name":"Logger"},"Protocols/Logger.html#/s:11CohesionKit6LoggerP18didUnregisterAliasyyAA0F3KeyVyqd__GlF":{"name":"didUnregisterAlias(_:)","abstract":"

Notify an alias is suppressed from the identity map

","parent_name":"Logger"},"Protocols/EntityEnumWrapper.html#/s:11CohesionKit17EntityEnumWrapperP23wrappedEntitiesKeyPaths10relativeToSayAA019PartialIdentifiableH4PathVyqd__GGs08WritablehN0Cyqd__xG_tlF":{"name":"wrappedEntitiesKeyPaths(relativeTo:)","abstract":"

Entities contained by all cases relative to the parent container

","parent_name":"EntityEnumWrapper"},"Protocols/Aggregate.html#/s:11CohesionKit9AggregateP22nestedEntitiesKeyPathsSayAA019PartialIdentifiableF4PathVyxGGvp":{"name":"nestedEntitiesKeyPaths","abstract":"

keypaths to nested models

","parent_name":"Aggregate"},"Protocols/Observer.html#/s:11CohesionKit8ObserverP1TQa":{"name":"T","parent_name":"Observer"},"Protocols/Observer.html#/s:11CohesionKit8ObserverP5value1TQzvp":{"name":"value","abstract":"

The value at the time the observer creation.","parent_name":"Observer"},"Protocols/Observer.html#/s:11CohesionKit8ObserverP7observe8onChangeAA12SubscriptionCy1TQzc_tF":{"name":"observe(onChange:)","abstract":"

Add an observer being notified when entity change.","parent_name":"Observer"},"Protocols/Observer.html#/s:11CohesionKit8ObserverPAAE11asPublisher7Combine03AnyE0Vy1TQzs5NeverOGvp":{"name":"asPublisher","abstract":"

A Publisher emitting the observer current value and subscribing to any subsequents new values

","parent_name":"Observer"},"Protocols/Observer.html":{"name":"Observer","abstract":"

A protocol allowing to observe a value returned from the IdentityMap

"},"Protocols/Aggregate.html":{"name":"Aggregate","abstract":"

An Identifiable model containing nested models

"},"Protocols/EntityEnumWrapper.html":{"name":"EntityEnumWrapper","abstract":"

a type wrapping one or more Identifiable types. As the name indicates you should use this type only on enums:"},"Protocols/Logger.html":{"name":"Logger","abstract":"

a protocol reporting IdentityMap internal information

"},"Extensions/Date.html#/s:10Foundation4DateV11CohesionKitE5stampSdvp":{"name":"stamp","abstract":"

Generate a stamp suitable to use in IdentityMap.","parent_name":"Date"},"Extensions/Publisher.html#/s:7Combine9PublisherP11CohesionKitE5store2in5named10modifiedAtAA03AnyB0Vy6OutputQz7FailureQzGAD11IdentityMapC_AD8AliasKeyVyALGSgSdts12IdentifiableALRQrlF":{"name":"store(in:named:modifiedAt:)","abstract":"

Stores the Identifiable upstream into an identityMap

","parent_name":"Publisher"},"Extensions/Publisher.html#/s:7Combine9PublisherP11CohesionKitE5store2in5named10modifiedAtAA03AnyB0Vy6OutputQz7FailureQzGAD11IdentityMapC_AD8AliasKeyVyALGSgSdtAD9AggregateALRQrlF":{"name":"store(in:named:modifiedAt:)","abstract":"

Stores the Aggregate upstream into an identityMap

","parent_name":"Publisher"},"Extensions/Publisher.html#/s:7Combine9PublisherP11CohesionKitE5store2in5named10modifiedAtAA03AnyB0VySay6Output_7ElementQZG7FailureQzGAD11IdentityMapC_AD8AliasKeyVyAKQzGSgSdtSlAVRQs12IdentifiableAMRQrlF":{"name":"store(in:named:modifiedAt:)","abstract":"

Stores the upstream collection into an identityMap

","parent_name":"Publisher"},"Extensions/Publisher.html#/s:7Combine9PublisherP11CohesionKitE5store2in5named10modifiedAtAA03AnyB0VySay6Output_7ElementQZG7FailureQzGAD11IdentityMapC_AD8AliasKeyVyAKQzGSgSdtSlAVRQAD9AggregateAMRQrlF":{"name":"store(in:named:modifiedAt:)","abstract":"

Stores the upstream collection into an identityMap

","parent_name":"Publisher"},"Extensions/Publisher.html":{"name":"Publisher"},"Extensions/Date.html":{"name":"Date"},"Extensions.html#/s:11CohesionKit10EntityNodeC":{"name":"EntityNode"},"Enums/StampError.html#/s:11CohesionKit10StampErrorO6tooOldyACSd_SdtcACmF":{"name":"tooOld(current:received:)","abstract":"

received stamp is smaller than current stamp

","parent_name":"StampError"},"Enums/StampError.html":{"name":"StampError"},"Classes/Subscription.html#/s:11CohesionKit12SubscriptionC11unsubscribeyycvp":{"name":"unsubscribe","parent_name":"Subscription"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6Updatea":{"name":"Update","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC5queue6loggerACSo012OS_dispatch_E0CSg_AA6Logger_pSgtcfc":{"name":"init(queue:logger:)","abstract":"

Create a new IdentityMap instance optionally with a queue and a logger

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC5store6entity5named10modifiedAt9ifPresentAA14EntityObserverVyxGx_AA8AliasKeyVyxGSgSdSgyxzcSgts12IdentifiableRzlF":{"name":"store(entity:named:modifiedAt:ifPresent:)","abstract":"

Store an entity in the storage. Entity will be stored only if stamp (modifiedAt) is higher than in previous","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC5store6entity5named10modifiedAt9ifPresentAA14EntityObserverVyxGx_AA8AliasKeyVyxGSgSdSgyxzcSgtAA9AggregateRzlF":{"name":"store(entity:named:modifiedAt:ifPresent:)","abstract":"

Store an aggregate in the storage. Each aggregate entities will be stored only if stamp (modifiedAt) is higher than in previous","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC5store8entities5named10modifiedAtAA14EntityObserverVySay7ElementQzGGx_AA8AliasKeyVyxGSgSdSgtSlRzs12IdentifiableAKRQlF":{"name":"store(entities:named:modifiedAt:)","abstract":"

Store multiple entities at once

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC5store8entities5named10modifiedAtAA14EntityObserverVySay7ElementQzGGx_AA8AliasKeyVyxGSgSdSgtSlRzAA9AggregateAKRQlF":{"name":"store(entities:named:modifiedAt:)","abstract":"

store multiple aggregates at once

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC4find_2idAA14EntityObserverVyxGSgxm_2IDQzts12IdentifiableRzlF":{"name":"find(_:id:)","abstract":"

Try to find an entity/aggregate in the storage.

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC4find5namedAA14EntityObserverVyxSgGAA8AliasKeyVyxG_ts12IdentifiableRzlF":{"name":"find(named:)","abstract":"

Try to find an entity/aggregate registered under named alias

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC4find5namedAA14EntityObserverVyxSgGAA8AliasKeyVyxG_tSlRzlF":{"name":"find(named:)","abstract":"

Try to find a collected registered under named alias

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6update_2id10modifiedAtADSbxm_2IDQzSdSgyxzXEts12IdentifiableRzlF":{"name":"update(_:id:modifiedAt:update:)","abstract":"

Updates an already stored entity using a closure. Useful to update a few properties or when you assume the entity","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6update_2id10modifiedAt_Sbxm_2IDQzSdSgyxzXEtAA9AggregateRzlF":{"name":"update(_:id:modifiedAt:_:)","abstract":"

Updates an already stored alias using a closure. This is useful if you don’t have a full entity for update","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6update5named10modifiedAtADSbAA8AliasKeyVyxG_SdSgyxzXEts12IdentifiableRzlF":{"name":"update(named:modifiedAt:update:)","abstract":"

Updates an already stored alias using a closure.","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6update5named10modifiedAtADSbAA8AliasKeyVyxG_SdSgyxzXEtAA9AggregateRzlF":{"name":"update(named:modifiedAt:update:)","abstract":"

Updates an already stored alias using a closure.","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6update5named10modifiedAtADSbAA8AliasKeyVyxG_SdSgyxzXEtSlRzs12Identifiable7ElementRpzlF":{"name":"update(named:modifiedAt:update:)","abstract":"

Updates an already existing collection alias content","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC6update5named10modifiedAtADSbAA8AliasKeyVyxG_SdSgyxzXEtSlRzAA9Aggregate7ElementRpzlF":{"name":"update(named:modifiedAt:update:)","abstract":"

Updates an already existing collection alias content","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC11removeAlias5namedyAA0F3KeyVyxG_tlF":{"name":"removeAlias(named:)","abstract":"

Removes an alias from the storage

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC11removeAlias5namedyAA0F3KeyVyxG_tSlRzlF":{"name":"removeAlias(named:)","abstract":"

Removes an alias from the storage

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC14removeAllAliasyyF":{"name":"removeAllAlias()","abstract":"

Removes all alias from identity map

","parent_name":"IdentityMap"},"Classes/IdentityMap.html#/s:11CohesionKit11IdentityMapC9removeAllyyF":{"name":"removeAll()","abstract":"

Removes all alias AND all objects stored weakly. You should not need this method and rather use removeAlias.","parent_name":"IdentityMap"},"Classes/IdentityMap.html":{"name":"IdentityMap","abstract":"

Manages entities lifecycle and synchronisation

"},"Classes/Subscription.html":{"name":"Subscription"},"Classes.html":{"name":"Classes","abstract":"

The following classes are available globally.

"},"Enums.html":{"name":"Enumerations","abstract":"

The following enumerations are available globally.

"},"Extensions.html":{"name":"Extensions","abstract":"

The following extensions are available globally.

"},"Protocols.html":{"name":"Protocols","abstract":"

The following protocols are available globally.

"},"Structs.html":{"name":"Structures","abstract":"

The following structures are available globally.

"},"Typealiases.html":{"name":"Type Aliases","abstract":"

The following type aliases are available globally.

"}} \ No newline at end of file diff --git a/undocumented.json b/undocumented.json new file mode 100644 index 0000000..a27d575 --- /dev/null +++ b/undocumented.json @@ -0,0 +1,6 @@ +{ + "warnings": [ + + ], + "source_directory": "/Users/runner/work/CohesionKit/CohesionKit" +} \ No newline at end of file