# Specification

This document describes the Seekia specification.

Some of the information here may not match what is in the code, and some of it might have to be changed.

As of version 0.1, whatever exists in the code is probably more up-to-date, and this file should be updated to reflect it.

We can still easily change things because the network has not been launched yet.

## Value Lengths

Name | Length In Bytes | String Encoding
--- | --- | ---
Payment Proof Provider Account Key | 32 | Hex
Device Identifier | 11 | Hex
Request Identifier | 16 | None
Identity Key | 32 | Hex
Identity Hash | 16 | Custom
Secret Inbox Seed | 22 | None
Message Inbox | 10 | Base32
Message Cipher Key Hash | 25 | None
Message Cipher Key | 32 | Hex
Message Hash | 26 | Hex
Attribute Hash | 27 | Hex
Profile Hash | 28 | Hex
Review Hash | 29 | Hex
Report Hash | 30 | Hex
Network Parameters Hash | 31 | Hex
Payment Proof Hash | 32 | Hex
Memo Hash | 32 | Hex

## Parameters

Parameters are how Network Parameters are referred to in the code.

Parameters are encoded in MessagePack.

### Parameters Hash

A parameters hash is a 30 bytes long Blake3 hash of the parameters bytes, with a 1 byte metadata suffix

*TODO: Use the metadata suffix to encode something useful*

### Parameters Encoding

A profile is a MessagePack encoded list of {[]Signature, Content}

The list of admin signatures are encoded in MessagePack.

* **Signature**:
    * 64 byte long Ed25519 signature of Blake3_256(Content), signed by the parameters admin signer identity public key
* **Content**:
    * MessagePack encoded map of `map[int][]byte`
        * Map structure: Field Identifier -> Field value bytes

### Parameters Fields

These are a work in progress. Most of these parameters have not been implemented in the code yet.

The Format section describes the parameters map entries for each parameters type.

The Value Bytes section describes the map entry values in bytes, which are used when encoding the values in MessagePack.

The Value String section describes the map entry values encoded as String, which are used when encoding the parameters map as a `map[string]string`

* **AdminPermissions**
    * Description:
        * Describes which admins can sign each parametersType, and how many admin signatures are needed.
    * Format:
        * **(ParametersType)_AuthorizedAdmins**
            * Description: List of admins (ed25519 public keys) who can sign the parameters
            * Value Bytes: `[][32]byte`
            * Value String: List of admin public keys encoded as hex, separated by "+"
        * **(ParametersType)_MinimumSigners**
            * Description: Minimum number of admins needed to sign the parameters file
            * Value Bytes: `int`
            * Value String: `int` encoded as String
        * **(ParametersType)_MinimumCreationTime**
            * Description:
                * The minimum creation time required for the parametersType.
                * This is useful if old parameters become the newest valid parameters again, after admins are changed.
                * This allows for any maliciously authored parameters to be rejected, by setting this time after they were authored.
            * Value Bytes: `int64`
            * Value String: `int64` encoded as String
* **GeneralParameters**
    * Description:
        * Miscellaneous parameters
    * Format:
        * **SeekiaMinimumSafeVersion**
            * Description:
                * Version float of the latest seekia client that is safe to run.
                * This is useful if a vulnerability is found in a version of Seekia.
                * It will require clients to update to at least the minimum safe version to operate (connect to the internet).
                * For example, imagine a bug is found in version 2.4 that allows remote code execution on a requestor's machine.
                * This value can be set to 2.5, and any <=2.4 clients will not be able to connect to any hosts after downloading the updated parameters.
            * Value Bytes: `float32`
            * Value String: `float32` encoded as String
        * **SeekiaNewestVersion**
            * Description:
                * Version float of the newest Seekia application, so the user knows when an update is available.
                * This information should be shown in the GUI as "Update Available".
            * Value Bytes: `float32`
            * Value String: `float32` encoded as String
        * **SeekiaClearnetWebsite**
            * Description: URL of the current Seekia clearnet website (shown in the GUI)
            * Value Bytes: Unicode bytes
            * Value String: Unicode string
            * Example: `https://seekia.net`
        * **SeekiaEthWebsite**
            * Description: .eth address of the current Seekia website Ethereum Name Service IPFS site (shown in the GUI)
                * Changing this is only needed if the seekia.eth site was seized by a nefarious entity.
            * Value Bytes: Unicode bytes
            * Value String: Unicode string
            * Example: `seekia.eth`
        * **MateInactivityExpirationTime**
            * Description:
                * Number of seconds until a Mate profile is dropped from the network
                * The profile's CreationTime must be younger than this time. 
            * Value Bytes: `int`
            * Value String: `int` encoded as String
        * **HostInactivityExpirationTime**
            * Description:
                * Number of seconds until a Host profile is dropped from the network
                * The profile's CreationTime must be younger than this time. 
            * Value Bytes: `int`
            * Value String: `int` encoded as String

* **MinimumIdentityDaysToFund**
    * Description:
        * A file describing the minimum number of days required to fund a mate/host identity
        * The historic rates are needed so that updates to the durations will have time to be downloaded by the users of the network before the new durations take effect
    * Format:
        * **(IdentityType)_(TimeUnix)**
            * Description: The minimum number of days required to fund for identities of the identityType
            * Value Bytes: TODO
            * Value String: TODO (big.Int as String?)
            * Examples:
                * `Mate_1690000000 -> 60`
                * `Host_1690000000 -> 80`

* **MaximumIdentityDaysToFund**
    * Description:
        * A file describing the maximum number of days required to fund a mate/host identity
        * The historic rates are needed so that updates to the durations will have time to be downloaded by the users of the network before the new durations take effect
    * Format:
        * **(IdentityType)_(TimeUnix)**
            * Description: The maximum number of days required to fund for identities of the identityType
            * Value Bytes: TODO
            * Value String: TODO (big.Int as String?)
            * Examples:
                * `Mate_1690000000 -> 300`
                * `Host_1690000000 -> 600`

* **SeekiaApplicationHashes**
    * Description:
        * A file describing the official application hashes
        * The GUI should have a tool to show this information, as well as verify application hashes
        * TODO: Create Verify Application page, which has button which brings up dialog to select file
    * Format:
        * **(Filename)**
            * Description:
                * Blake3 hash of the official application file
            * Value Bytes: `[32]byte`
            * Value String: `[32]byte` encoded in Hex
            * Example:
                * `Seekia-v0.1.AppImage -> 12a34e43b2c112f34e43a21a341958a4841ab12abbba192384ab3804ab (Not A Real Hash)` 
                * `Seekia-v1.2.dmg -> 12a34e43b2c112f34e43a21a341958a4841ab12abbba192384ab3804ab (Not A Real Hash)`
                * `Seekia-v1.2.exe -> 12a34e43b2c112f34e43a21a341958a4841ab12abbba192384ab3804ab (Not A Real Hash)`
* **MessageCosts**
    * Description:
        * These are the gold/kilobytes/day rates for messages to be hosted on the network
        * The historical cost rates must be kept for 1 month (the longest time a message can be funded *2)
    * Format:
        * **(TimeUnix)**
            * Description: Milligrams of gold per day rate to store 1 kilobyte of message data for 1 day (24 hours) at timeUnix
            * Value Bytes: TODO
            * Value String: TODO
            * Example:
                * `1690000000 -> 1000`
* **FundingIdentityCosts**
    * Description:
        * These are the milligrams of gold/day rates for Mate/Host identities to be funded and hosted on the network
        * The historical cost rates are needed so updates to the rates have time to be downloaded by users before the new rates go into effect
    * Format:
        * **(IdentityType)_(TimeUnix)**
            * Description: Milligrams of gold rate per day at TimeUnix to fund an IdentityType identity
            * Value Bytes: TODO
            * Value String: TODO
            * Examples:
                * `Mate_1690000000 -> 1000`
                * `Host_1690000000 -> 2000`
* **ReportCosts**
    * Description:
        * The cost to fund a report
        * Historical times are needed so that all users have time to download the parameters before a price change takes place
    * Format:
        * **(TimeUnix)**
            * Description: Cost in milligrams of gold to fund a report for the standard report duration at timeUnix
            * Value Bytes: TODO
            * Value String: TODO
            * Example:
                * `1690000000 -> 1000`
* **MateProfileCosts**
    * Description:
        * The cost to fund a mate profile
        * Historical times are needed so that all users have time to download the parameters before a price change takes place
    * Format:
        * **(TimeUnix)**
            * Description: Cost in milligrams of gold to fund a mate profile at timeUnix
            * Value Bytes: TODO
            * Value String: TODO
            * Example:
                * `1690000000 -> 1000`
* **ModerationParameters**
    * Description:
        * Various moderation parameters
    * Format:
        * **StickyStatusIntervalDuration**
            * Description: The amount of time in seconds to wait between recording each historical viewable status
            * Value Bytes: `int`
            * Value String: `int` encoded as String
        * **StickyStatusEstablishingTime**
            * Description: The minimum number of seconds required for a host to be online and downloading the relevant reviews before they start sharing the sticky status to requestors
            * Value Bytes: `int`
            * Value String: `int` encoded as String
        * **StickyStatusHistoricalExpirationTime_(IdentityType)Identity**
            * Description: The duration of time in seconds to keep historical identity sticky statuses. Any statuses older than this time will be discarded.
            * Value Bytes: `int`
            * Value String: `int` encoded as String
            * Examples:
                * `StickyStatusHistoricalExpirationTime_MateIdentity -> 50000`
                * `StickyStatusHistoricalExpirationTime_HostIdentity -> 50000`
                * `StickyStatusHistoricalExpirationTime_ModeratorIdentity -> 50000`
        * **StickyStatusHistoricalExpirationTime_(IdentityType)Profile**
            * Description: The duration of time in seconds to keep historical profile sticky statuses. Any statuses older than this time will be discarded.
            * Value Bytes: `int`
            * Value Bytes: `int`
            * Value String: `int` encoded as String
            * Examples:
                * `StickyStatusHistoricalExpirationTime_MateProfile -> 50000`
                * `StickyStatusHistoricalExpirationTime_HostProfile -> 50000`
                * `StickyStatusHistoricalExpirationTime_ModeratorProfile -> 50000`
        * **StickyStatusHistoricalExpirationTime_Message**
            * Description: The duration of time in seconds to keep historical message sticky statuses. Any statuses older than this time will be discarded.
            * Value Bytes: `int`
            * Value Bytes: `int`
            * Value String: `int` encoded as String
        * **StickyStatusMinimumViewablePercentage_(IdentityType)Identity**
            * Description: The minimum viewable verdict percentage required for an identity's sticky status to be viewable
            * Value Bytes: `int` between 0-100
            * Value String: `int` encoded as String
            * Examples:
                * `StickyStatusMinimumViewablePercentage_MateIdentity -> 70`
                * `StickyStatusMinimumViewablePercentage_HostIdentity -> 60`
                * `StickyStatusMinimumViewablePercentage_ModeratorIdentity -> 50`
        * **StickyStatusMinimumViewablePercentage_(IdentityType)Profile**
            * Description: The minimum viewable verdict percentage required for a profile's sticky status to be viewable
            * Value Bytes: `int` between 0-100
            * Value String: `int` encoded as String
            * Examples:
                * `StickyStatusMinimumViewablePercentage_MateProfile -> 70`
                * `StickyStatusMinimumViewablePercentage_HostProfile -> 60`
                * `StickyStatusMinimumViewablePercentage_ModeratorProfile -> 50`
        * **StickyStatusMinimumViewablePercentage_Message**
            * Description: The minimum viewable verdict percentage required for a message's sticky status to be viewable
            * Value Bytes: `int` between 0-100
            * Value String: `int` encoded as String
        * **ReportDuration**
            * Description: The number of seconds that a funded report should exist on the network before expiring
            * Value Bytes: `int`
            * Value String: `int` encoded as String

* **Supermoderators**
    * Description:
        * A list of supermoderators
        * They are ranked, so supermoderators can ban each other
        * Any banning/banned supermoderator should eventually be removed from the parameters list, either the banner or the banned
    * Format:
        * **(Supermoderator Rank)**
            * Description: Supermoderator identity hash
            * Value Bytes: `[16]byte`
            * Value String: `[16]byte` encoded as identity hash string
            * Examples:
                * `1 -> wgkxplfvju7yhpoadvxju4l2r`
                * `2 -> fbeqvukltaw73yzbrx34vg4wr`
* **ExchangeRates**
    * Description:
        * Exchange rates for different currencies.
        * These are approximate values, and are not used for anything network consensus-critical
        * They are used to convert the cryptocurrency storage costs to fiat so users know what they are paying
        * They are also used to convert each user's wealth to a user's preferred fiat currency
        * No historical data is needed.
    * Format:
        * **(CurrencyCode)**: 
            * Description: Amount of CurrencyCode units required to buy 1 kilogram of gold
            * Value Bytes: TODO
            * Value String: TODO (big.Int as String?)
            * Examples:
                * `ETH -> 10000000 (wei)`
                * `USD -> 5000`
                * `EUR -> 5100` 
* **GoldRates**
    * Description:
        * Exchange rates for gold to crypto
        * This is used to calculate a moderator's identity score, so all hosts and moderators must agree on the rates
        * The historical rates must be kept forever, because all deposits to an identity's address must be converted
    * Format:
        * **(TimeUnix)_(Crypto)**
            * Description: Number of crypto atomic units to buy 1 kilogram of gold at time unix
            * Value Bytes: `int64`
            * Value String: `int64` encoded as String
            * Examples:
                * `1690000000_Ethereum -> 12332123123123`
                * `1690000000_Cardano -> 123213123123123123123`
* **PaymentProofProvidersStatus**
    * Description:
        * Used to tell users if any payment proof providers were hacked/broken for any period of time
        * This is useful so we can give users an explanation for why they can't access a server or if their balance has changed
    * Format:
        * TODO: Historical information describing periods that the servers were hacked/broken
* **PaymentProofProvidersList**
    * Description:
        * A list of all of the payment proof server URLS
        * These may be clearnet or Tor
    * Format:
        * **(URL)**
            * Description: The URL of the payment proof provider server.
            * Value Bytes: `string`
            * Value String: A description about the server and who operates it.
            * Examples:
                * `https://paymentproofprovider.seekia.net/ -> The main payment provider operated by X.

*TODO: Add parameters to ban specific messages (they could be malformed and undecryptable with the cipherkeyhash, but still contain unruleful content within them)*

## Profiles

Profile creation is implemented in `/internal/profiles/createProfiles/createProfiles.go`

Profile reading is implemented in `/internal/profiles/readProfiles/readProfiles.go`

Profiles are encoded in MessagePack.

### Profile Hashes

A profile hash is a 28 bytes long Blake3 hash of the profile bytes, with a 1 byte metadata suffix

The metadata byte is described below:
* 1 = Mate profile, disabled
* 2 = Mate profile, not disabled
* 3 = Host profile, disabled
* 4 = Host profile, not disabled
* 5 = Moderator profile, disabled
* 6 = Moderator profile, not disabled

### Profile Encoding

A profile is a MessagePack encoded list of {Signature, Content}

* **Signature**:
    * 64 byte long Ed25519 signature of Blake3_256(Content), signed by the profile author's identity public key
* **Content**:
    * MessagePack encoded map of `map[int][]byte`
        * Map structure: Attribute Identifier -> Attribute value bytes

### Profile attributes:

Each attribute has a bytes and string encoding.

The Bytes encoding is used when encoding the attributes in MessagePack.

The String encoding is used when reading a profile's attributes.

Many of the more space-efficient Bytes encodings have not been implemented yet.

For example, we should encode values such as "Yes"/"No" as `bool` rather than `string` (1 byte rather than 3/2 bytes).

Whenever a string value is described for the bytes value, we are encoding the string as unicode bytes `[]byte("Example")`

* **NetworkType**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate/Host/Moderator
    * Description: Network Type (1 == Mainnet, 2 == Testnet1)
    * Value Bytes: 1 byte
    * Value String: 1 byte (Example: "1"/"2")
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **IdentityKey**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate/Host/Moderator
    * Description: Profile author Ed25519 Identity Public Key
    * Value Bytes: 32 bytes
    * Value String: 32 bytes encoded in Hex
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **CreationTime**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate/Host/Moderator
    * Description: Time that profile was created
    * Value Bytes: Integer number of seconds after unix origin time that profile was created
    * Value String: Int64 encoded as string
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **ProfileType**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate/Host/Moderator
    * Description: Identity type of profile author
    * Value Bytes: "Mate"/"Host"/"Moderator"
    * Value String: "Mate"/"Host"/"Moderator"
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **ChatKeysLatestUpdateTime**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate/Moderator
    * Description: Time that user last updated their chat keys
    * Value Bytes: Int64 (Unix time)
    * Value String: Int64 encoded as string
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **DeviceIdentifier**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate/Moderator
    * Description: User's device identifier
    * Value Bytes: 11 bytes
    * Value String: 11 bytes encoded in Hex
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **NaclKey**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate/Moderator
    * Description: Used to encrypt all messages sent to user
    * Value Bytes: 32 bytes
    * Value String: 32 bytes encoded in Base64
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **MlkemKey**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate/Moderator
    * Description: Used to encrypt all messages sent to user
    * Value Bytes: 1568 bytes
    * Value String: 1568 bytes encoded in Base64
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **CsidhKey**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate/Moderator
    * Description: Used to encrypt all messages sent to user
    * Value Bytes: 64 bytes
    * Value String: 64 bytes encoded in Base64
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **ProfileLanguage**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate/Host/Moderator
    * Description: Language that the profile is written in
    * Value Bytes: Integer (TODO in code)
    * Value String: A language identifier integer
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **Height**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: User's height in centimeters
    * Value Bytes: Float64 (TODO in code)
    * Value String: Float64 between 30 and 400 representing centimeters encoded as string 
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **Sex**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: User's biological sex
    * Value Bytes: "Male"/"Female"/"Intersex Male"/"Intersex Female"/"Intersex"
    * Value String: "Male"/"Female"/"Intersex Male"/"Intersex Female"/"Intersex"
    * Is Required: No
    * Mandatory Attributes: None 
    * Is Canonical: Always
* **Age**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: User's age in years
    * Value Bytes: Integer (TODO in code)
    * Value String: Int between 18 and 150 encoded as string
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **Description**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate/Host/Moderator
    * Description: A user's description
    * Value Bytes: Unicode UTF-8 Bytes
        * Must be <= 3000 bytes (Mate), <= 300 bytes (Host), <= 500 bytes (Moderator)
        * Cannot be the empty string ""
    * Value String: Unicode UTF-8 String
    * Is Required: No
    * Mandatory Attributes: None 
    * Is Canonical: Never
* **Username**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate/Host/Moderator
    * Description: A user's username
    * Value Bytes: Unicode UTF-8 Bytes that is <= 25 bytes, containing no tabs or newlines. Cannot be empty.
    * Value String: Unicode UTF-8 String
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Never
* **PrimaryLocationLatitude**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: Latitude of user's primary location (Number between -90 and 90)
    * Value Bytes: Float64 (TODO in code)
    * Value String: Float64 as String
    * Is Required: No
    * Mandatory Attributes: PrimaryLocationLongitude
    * Is Canonical: Always
* **PrimaryLocationLongitude**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: Longitude of user's primary location (Number between -180 and 180)
    * Value Bytes: Float64 (TODO in code)
    * Value String: Float64 as String
    * Is Required: No
    * Mandatory Attributes: PrimaryLocationLatitude
    * Is Canonical: Always
* **PrimaryLocationCountry**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: Country where user's primary location is located, represented as an integer from the worldLocations countries list.
    * Value Bytes: Integer (TODO in code)
    * Value String: Integer as String
    * Is Required: No
    * Mandatory Attributes: PrimaryLocationLatitude, PrimaryLocationLongitude
    * Is Canonical: Always
* **SecondaryLocationLatitude**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: Latitude of user's secondary location (Number between -90 and 90)
    * Value Bytes: Float64 (TODO in code)
    * Value String: Float64 as String
    * Is Required: No
    * Mandatory Attributes: SecondaryLocationLongitude
    * Is Canonical: Always
* **SecondaryLocationLongitude**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: Longitude of user's secondary location (Number between -180 and 180)
    * Value Bytes: Float64 (TODO in code)
    * Value String: Float64 as String
    * Is Required: No
    * Mandatory Attributes: SecondaryLocationLatitude
    * Is Canonical: Always
* **SecondaryLocationCountry**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: Country where the user's secondary location is located, represented as an integer from the worldLocations countries list.
    * Value Bytes: Integer (TODO in code)
    * Value String: Integer as String
    * Is Required: No
    * Mandatory Attributes: SecondaryLocationLatitude, SecondaryLocationLongitude
    * Is Canonical: Always
* **Tags**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: User's profile tags
    * Value Bytes: TODO (Encode as MessagePack list)
    * Value String: List of tags, separated by "+&".
        * Each tag cannot contain "+&"
        * Each tag cannot be longer than 40 bytes.
        * All tags cannot exceed 500 bytes.
        * Number of tags cannot exceed 30.
        * Tag cannot be the empty string ""
        * Each tag cannot contain tab or newline
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Never
* **Photos**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: User's profile photos.
    * Value Bytes: JPEG image bytes list `[][]byte`
    * Value String: List of base64 encoded jpeg images, separated by "+".
        * Maximum of 5 photos.
        * Each photo cannot surpass 20,000 bytes in size
        * The full Standard image requirements are described in imagery/imagery.go
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Never
* **Questionnaire**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: A questionnaire which users can fill out and send their responses to the user.
    * Value Bytes: TODO
    * Value String: A questionnaire, encoded in the proper format.
        * The format is described later in this document, and implemented in mateQuestionnaire.go
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Never
* **Avatar**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate/Host/Moderator
    * Description: An avatar, which is selected from 3630 available options in the application.
    * Value Bytes: Integer (TODO in code)
    * Value String: An integer between 1 and 3630, encoded as String
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **Sexuality**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The sex(es) that the user is interested in.
    * Value Bytes: "Male"/"Female"/"Male And Female"
    * Value String: "Male"/"Female"/"Male And Female"
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **23andMe_AncestryComposition**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's 23andMe ancestry composition.
    * Value Bytes: A 23andMe ancestry location composition, encoded as bytes
    * Value String: A 23andMe ancestry location composition.
        * Format is described in /genetics/companyAnalysis/23andMe.go
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **23andMe_NeanderthalVariants**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's neanderthal variants count, as reported by 23andMe. Is an integer between 0 and 7462.
    * Value Bytes: Integer (TODO in code)
    * Value String: Integer as String
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **23andMe_MaternalHaplogroup**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's maternal haplogroup, as reported by 23andMe.
    * Value Bytes: Unicode UTF-8 bytes
    * Value String: A string no greater than 25 bytes in length, containing no tabs or newlines. Cannot be an empty string.
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Sometimes
        * Canonical values are listed in `/genetics/companyAnalysis/23andMe.go`
* **23andMe_PaternalHaplogroup**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's paternal haplogroup, as reported by 23andMe.
    * Value Bytes: Unicode UTF-8 bytes
    * Value String: A string no greater than 25 bytes in length, containing no tabs or newlines. Cannot be an empty string.
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Sometimes
        * Canonical values are listed in `/genetics/companyAnalysis/23andMe.go`
* **BodyFat**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The amount of body fat a user has, on a scale of 1-4 (least-most)
    * Value Bytes: Integer (TODO in code)
    * Value String: An integer between 1 and 4
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **BodyMuscle**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The amount of body muscle a user has, on a scale of 1-4 (least-most)
    * Value Bytes: Integer (TODO in code)
    * Value String: An integer between 1 and 4
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **EyeColor**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's eye color.
    * Value Bytes: Unicode UTF-8 bytes
    * Value String: A "+" delimited string consisting of: "Blue", "Green", "Hazel", Brown"
        * Must contain at least 1 color, cannot contain more than 4 colors. Repeats are not allowed.
        * Example: "Blue+Green", "Blue"
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **HairColor**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's natural hair color.
    * Value Bytes: Unicode UTF-8 bytes
    * Value String: A "+" delimited string consisting of "Brown", "Black", "Blonde", "Orange"
        * Must contain at least 1 color, cannot contain more than 2 colors. Repeats are not allowed.
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **HairTexture**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's natural hair texture.
    * Value Bytes: Integer
    * Value String: An integer between 1-6
		* 1 == Straight, 2 == Slightly Wavy, 3 == Wavy, 4 == Big Curls, 5 == Small Curls, 6 == Very Tight Curls
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **SkinColor**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's natural skin color.
    * Value Bytes: Integer between 1-6 (1 = lightest skin, 6 = darkest skin)
    * Value String: Unicode String
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **HasHIV**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's HIV infection status.
    * Value Bytes: Bool (TODO in code)
    * Value String: "Yes"/"No"
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **HasGenitalHerpes**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's genital herpes infection status.
    * Value Bytes: Bool (TODO in code)
    * Value String: "Yes"/"No"
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **Wealth**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's wealth, described in WealthCurrency units.
    * Value Bytes: Integer (TODO in code)
    * Value String: An integer between 0 and 9223372036854775807
    * Is Required: No
    * Mandatory Attributes: WealthIsLowerBound, WealthCurrency
    * Is Canonical: Always
* **WealthIsLowerBound**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: Describes if the user's wealth is a lower bound or an exact value.
    * Value Bytes: Bool (TODO in code)
    * Value String: "Yes"/"No"
    * Is Required: No
    * Mandatory Attributes: Wealth, WealthCurrency
    * Is Canonical: Always
* **WealthCurrency**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The currency that the user's Wealth attribute is represented in.
    * Value Bytes: Unicode UTF-8 bytes
    * Value String: A valid currency code from `currencies.go`
    * Is Required: No
    * Mandatory Attributes: Wealth, WealthIsLowerBound
    * Is Canonical: Always
* **Hobbies**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's hobbies.
    * Value Bytes: Unicode UTF-8 bytes
    * Value String: A string that is no longer than 1000 bytes
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Never
* **FruitRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of Fruit, on a scale of 1-10 (least liked - most liked)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **VegetablesRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of Vegetables, on a scale of 1-10 (least liked - most liked)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **NutsRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of Nuts, on a scale of 1-10 (least liked - most liked)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **GrainsRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of Grains, on a scale of 1-10 (least liked - most liked)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **DairyRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of Dairy, on a scale of 1-10 (least liked - most liked)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **SeafoodRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of Seafood, on a scale of 1-10 (least liked - most liked)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **BeefRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of Beef, on a scale of 1-10 (least liked - most liked)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **PorkRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of Pork, on a scale of 1-10 (least liked - most liked)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **PoultryRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of Poultry, on a scale of 1-10 (least liked - most liked)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **EggsRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of Eggs, on a scale of 1-10 (least liked - most liked)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **BeansRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of Beans, on a scale of 1-10 (least liked - most liked)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **Fame**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's fame, on a scale of 1-10 (least famous - most famous)
    * Value Bytes: Integer (TODO in code)
    * Value String: An integer between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **AlcoholFrequency**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's Alcohol consumption frequency, on a scale of 1-10 (never - constantly)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **TobaccoFrequency**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's Tobacco consumption frequency, on a scale of 1-10 (never - constantly)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **CannabisFrequency**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's Cannabis consumption frequency, on a scale of 1-10 (never - constantly)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **Language**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The language(s) that the user can speak, along with each language's fluency
    * Value Bytes: Unicode UTF-8 bytes
    * Value String: List of language items, separated by "+&".
        * Each language item is LanguageName + "$" + Language Rating
        * Language rating is an int between 1 and 5
        * Each language name cannot contain a tab or newline
        * Each language name cannot contain "+&" or "$"
        * Each language cannot be longer than 30 bytes.
        * Number of languages cannot exceed 100.
        * Language cannot be the empty string ""
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Sometimes
* **Beliefs**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's beliefs. This may include worldview, religion, and philosophies.
    * Value Bytes: Unicode bytes that is no longer than 1000 bytes long
    * Value String: Unicode UTF-8 string
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Never
* **GenderIdentity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The gender that the user mentally identifies as.
    * Value Bytes: Unicode UTF-8 bytes
    * Value String: Either "Man", "Woman", or a string that is no longer than 50 bytes. Cannot contain tabs or newlines.
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Sometimes
        * Is Canonical for "Man"/"Woman"
* **PetsRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of pet ownership in general, on a scale of 1-10 (hate-love)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **CatsRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of cat ownership, on a scale of 1-10 (hate-love)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **DogsRating**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Mate
    * Description: The user's rating of dog ownership, on a scale of 1-10 (hate-love)
    * Value Bytes: Integer (TODO in code)
    * Value String: An int between 1 and 10
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **SeekiaVersion**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: The version of Seekia that the host is running (Examples: "0.1", "1.2")
    * Value Bytes: Float32 (TODO in code)
    * Value String: Float32
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **TorAddress**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: The host's Tor address
    * Value Bytes: Hidden service address bytes without the .onion suffix and decoded from base32.
    * Value String: Hidden service .onion address
    * Is Required: No
    * Mandatory Attributes: None
    * Is Canonical: Always
* **ClearnetAddress**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: The host's clearnet address
    * Value Bytes: Unicode UTF-8 bytes
    * Value String: Clearnet address (can be domain or IP address) (encoded in Unicode)
    * Is Required: No
    * Mandatory Attributes: ClearnetPort
    * Is Canonical: Never
* **ClearnetPort**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: The host's clearnet address port.
    * Value Bytes: Positive Integer
    * Value String: Positive integer as String
    * Is Required: No
    * Mandatory Attributes: ClearnetAddress
    * Is Canonical: Always
* **HostingParameters**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Describes if the host is hosting the network parameters.
    * Value Bytes: Bool
    * Value String: "Yes"/"No"
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **HostingHostContent**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Describes if the host is hosting Host profiles and reviews/reports of host identities, profiles, and attributes.
    * Value Bytes: Bool
    * Value String: "Yes"/"No"
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **HostIdentitiesQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: The number of hosted Host identities whom have a profile.
    * Value Bytes: Positive integer
    * Value String: Positive integer as String
    * Is Required: Only if HostingHostContent is true.
    * Mandatory Attributes: HostProfilesQuantity, HostReviewsQuantity, HostReportsQuantity
    * Is Canonical: Always
* **HostProfilesQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: The number of hosted Host profiles
    * Value Bytes: Positive integer
    * Value String: Positive integer as String
    * Is Required: Only if HostingHostContent is true.
    * Mandatory Attributes: HostIdentitiesQuantity, HostReviewsQuantity, HostReportsQuantity
    * Is Canonical: Always
* **HostReviewsQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: The number of hosted reviews of host identities/profiles/attributes.
    * Value Bytes: Positive integer
    * Value String: Positive integer as String
    * Is Required: Only if HostingHostContent is true.
    * Mandatory Attributes: HostIdentitiesQuantity, HostProfilesQuantity, HostReportsQuantity
    * Is Canonical: Always
* **HostReportsQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: The number of hosted reports of host identities/profiles/attributes
    * Value Bytes: Positive integer
    * Value String: Positive integer as String
    * Is Required: Only if HostingHostContent is true.
    * Mandatory Attributes: HostIdentitiesQuantity, HostProfilesQuantity, HostReviewsQuantity
    * Is Canonical: Always
* **HostingModeratorContent**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Describes if the host is hosting moderator profiles and reviews/reports of moderator identities, profiles, and attributes.
    * Value Bytes: Bool
    * Value String: "Yes"/"No"
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **ModeratorIdentitiesQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: The number of hosted moderator identities who have a profile.
    * Value Bytes: Positive integer
    * Value String: Positive integer as String
    * Is Required: Only if HostingModeratorContent is true.
    * Mandatory Attributes: ModeratorProfilesQuantity, ModeratorReviewsQuantity, ModeratorReportsQuantity
    * Is Canonical: Always
* **ModeratorProfilesQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: The number of hosted Moderator profiles
    * Value Bytes: Positive integer
    * Value String: Positive integer as String
    * Is Required: Only if HostingModeratorContent is true.
    * Mandatory Attributes: ModeratorIdentitiesQuantity, ModeratorReviewsQuantity, ModeratorReportsQuantity
    * Is Canonical: Always
* **ModeratorReviewsQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: The number of hosted reviews for Moderator identities/profiles/attributes
    * Value Bytes: Positive integer
    * Value String: Positive integer as String
    * Is Required: Only if HostingModeratorContent is true.
    * Mandatory Attributes: ModeratorIdentitiesQuantity, ModeratorProfilesQuantity, ModeratorReportsQuantity
    * Is Canonical: Always
* **ModeratorReportsQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Number of hosted reports for Moderator identities/profiles/attributes
    * Value Bytes: Positive integer
    * Value String: Positive integer as String
    * Is Required: Only if HostingModeratorContent is true.
    * Mandatory Attributes: ModeratorIdentitiesQuantity, ModeratorProfilesQuantity, ModeratorReviewsQuantity 
    * Is Canonical: Always
* **HostingMateContent**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Describes if the host is hosting Mate profiles/attributes, and reviews/reports of Mate identities, profiles and attributes
    * Value Bytes: Bool
    * Value String: "Yes"/"No"
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **MateIdentitiesRangeStart**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Identity hash range start for Mate identities that the host is hosting.
    * Value Bytes: `[16]byte`
    * Value String: `[16]byte` Encoded Hex, because identity ranges are usually not valid identity hashes.
    * Is Required: Only if HostingMateContent is true.
    * Mandatory Attributes: MateIdentitiesRangeEnd, MateIdentitiesQuantity, MateProfilesQuantity, MateReviewsQuantity, MateReportsQuantity
    * Is Canonical: Always
* **MateIdentitiesRangeEnd**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Identity hash range end for Mate identities that the host is hosting.
    * Value Bytes: `[16]byte`
    * Value String: `[16]byte` Encoded Hex, because identity ranges are usually not valid identity hashes.
    * Is Required: Only if HostingMateContent is true.
    * Mandatory Attributes: MateIdentitiesRangeStart, MateIdentitiesQuantity, MateProfilesQuantity, MateReviewsQuantity, MateReportsQuantity
    * Is Canonical: Always
* **MateIdentitiesQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Number of mate identities within hosted range who have a profile
    * Value Bytes: Positive integer
    * Value String: Positive Integer as String
    * Is Required: Only if HostingMateContent is true.
    * Mandatory Attributes: MateIdentitiesRangeStart, MateIdentitiesRangeEnd, MateProfilesQuantity, MateReviewsQuantity, MateReportsQuantity
    * Is Canonical: Always
* **MateProfilesQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Number of mate profiles within hosted range
    * Value Bytes: Positive integer
    * Value String: Positive integer as String
    * Is Required: Only if HostingMateContent is true.
    * Mandatory Attributes: MateIdentitiesRangeStart, MateIdentitiesRangeEnd, MateIdentitiesQuantity, MateReviewsQuantity, MateReportsQuantity
    * Is Canonical: Always
* **MateReviewsQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Number of reviews for mate identities/profiles/attributes within hosted range
    * Value Bytes: Positive integer
    * Value String: Positive integer as String
    * Is Required: Only if HostingMateContent is true.
    * Mandatory Attributes: MateIdentitiesRangeStart, MateIdentitiesRangeEnd, MateIdentitiesQuantity, MateProfilesQuantity, MateReportsQuantity
    * Is Canonical: Always
* **MateReportsQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Number of reports for mate identities/profiles/attributes within hosted range
    * Value Bytes: Positive integer
    * Value String: Positive integer as String
    * Is Required: Only if HostingMateContent is true.
    * Mandatory Attributes: MateIdentitiesRangeStart, MateIdentitiesRangeEnd, MateIdentitiesQuantity, MateProfilesQuantity, MateReviewsQuantity
    * Is Canonical: Always
* **HostingUnviewableProfiles**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Describes if the Host is hosting unviewable profiles (profiles that have been banned (or not approved (if Mate)))
    * Value Bytes: Bool
    * Value String: "Yes"/"No"
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **HostingMessages**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Describes if Host is hosting messages
    * Value Bytes: Bool
    * Value String: "Yes"/"No"
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **MessageInboxesRangeStart**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: The start of the message inbox range the host is hosting
    * Value Bytes: `[10]byte`
    * Value String: `[10]byte` encoded in Base32
    * Is Required: Only if HostingMessages is true.
    * Mandatory Attributes: MessageInboxesRangeEnd, InboxesQuantity, MessagesQuantity, MessageReviewsQuantity, MessageReportsQuantity
    * Is Canonical: Always
* **MessageInboxesRangeEnd**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: The end of the message inbox range the host is hosting
    * Value Bytes: `[10]byte`
    * Value String: `[10]byte` encoded in Base32
    * Is Required: Only if HostingMessages is true.
    * Mandatory Attributes: MessageInboxesRangeStart, InboxesQuantity, MessagesQuantity, MessageReviewsQuantity, MessageReportsQuantity
    * Is Canonical: Always
* **InboxesQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Number of inboxes within hosted range
    * Value Bytes: Positive integer
    * Value String: Positive integer encoded as string
    * Is Required: Only if HostingMessages is true.
    * Mandatory Attributes: MessageInboxesRangeStart, MessageInboxesRangeEnd, MessagesQuantity, MessageReviewsQuantity, MessageReportsQuantity
    * Is Canonical: Always
* **MessagesQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Number of hosted messages within range
    * Value Bytes: Positive integer
    * Value String: Positive integer encoded as string
    * Is Required: Only if HostingMessages is true.
    * Mandatory Attributes: MessageInboxesRangeStart, MessageInboxesRangeEnd, InboxesQuantity, MessageReviewsQuantity, MessageReportsQuantity
    * Is Canonical: Always
* **MessageReviewsQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Number of message reviews within hosted range
    * Value Bytes: Positive integer
    * Value String: Positive integer encoded as string
    * Is Required: Only if HostingMessages is true.
    * Mandatory Attributes: MessageInboxesRangeStart, MessageInboxesRangeEnd, InboxesQuantity, MessagesQuantity, MessageReportsQuantity
    * Is Canonical: Always
* **MessageReportsQuantity**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Number of message reports within hosted range
    * Value Bytes: Positive integer
    * Value String: Positive integer encoded as string
    * Is Required: Only if HostingMessages is true.
    * Mandatory Attributes: MessageInboxesRangeStart, MessageInboxesRangeEnd, InboxesQuantity, MessagesQuantity, MessageReviewsQuantity
    * Is Canonical: Always
* **HostingEthereumBlockchain**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Describes if the user is hosting the Ethereum blockchain and can be queried for Ethereum address deposits.
    * Value Bytes: Bool
    * Value String: "Yes"/"No"
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always
* **HostingCardanoBlockchain**
    * Attribute Identifier: TODO (see profileFormat.go)
    * Profile Types: Host
    * Description: Describes if the user is hosting the Cardano blockchain and can be queried for Cardano address deposits.
    * Value Bytes: Bool
    * Value String: "Yes"/"No"
    * Is Required: Yes
    * Mandatory Attributes: All other required attributes
    * Is Canonical: Always

## Messages

Message creation is implemented in `/internal/messaging/chatMessage/createMessages/createMessages.go`

Message reading is implemented in `/internal/messaging/chatMessage/readMessages/readMessages.go`

Messages are encoded in MessagePack.

*TODO: Describe the encoding in this document.*

## Reviews

Review creation is implemented in `/internal/moderation/createReviews/createReviews.go`

Reviews reading is implemented in `/internal/moderation/readReviews/readReviews.go`

Reviews are encoded in MessagePack.

### Review Hashes

A review hash is a 28 byte Blake3 hash of the review bytes, with a 1 byte metadata suffix

The Metadata byte is described below:
* 1 = Identity review
* 2 = Profile review
* 3 = Attribute review
* 4 = Message review

### Review Encoding

A review is a MessagePack encoded list of {Signature, Content}

* **Signature**:
    * 64 byte long Ed25519 signature of Blake3_256(Content), signed by the review author's identity public key
* **Content**:
    * MessagePack encoded map of `map[int][]byte`
        * Map structure: Field Identifier -> Field value (encoded MessagePack)

### Review Fields:

Each field value has a bytes and string representation.

The bytes representation is used to encode the values in MessagePack.

The string representation is used to read the review into a `map[string]string`.

* **ReviewVersion**
    * Field Identifier: TODO (see readReviews.go)
    * Description: The version of the review
        * New versions are created when the format/specification for encoding reviews is changed
    * Value Bytes: `int`
    * Value String: `int` encoded as String
    * Is Required: Yes
* **NetworkType**
    * Field Identifier: TODO (see readReviews.go)
    * Description: The network type of the review
        * 1 == Mainnet, 2 == Testnet1
    * Value Bytes: `byte`
    * Value String: `byte` encoded as String
    * Is Required: Yes
* **IdentityKey**
    * Field Identifier: TODO (see readReviews.go)
    * Description: Ed25519 Identity key of moderator review author
    * Value Bytes: `[32]byte`
    * Value string: `[32]byte` encoded in Hex
    * Is Required: Yes
* **CreationTime** 
    * Field Identifier: TODO (see readReviews.go)
    * Description: Unix Creation Time (Number of seconds after unix origin time that the review was created)
    * Value Bytes: `int64`
    * Value String: `int64` encoded as String
    * Is Required: Yes
* **ReviewedHash**
    * Field Identifier: TODO (see readReviews.go)
    * Description: Identity Hash/Message Hash/Profile Hash/Attribute Hash being reviewed
    * Value Bytes: `[]byte`
    * Value String: Reviewed hash encoded (Identity hashes use custom encoding, message/profile/attribute hashes are encoded in Hex)
    * Is Required: Yes
* **Verdict**
    * Field Identifier: TODO (see readReviews.go)
    * Description: The verdict of the review (Approve not allowed if ReviewType == "Identity")
    * Value Bytes: "Ban"/"Approve"/"None" (TODO: Encode as a single byte to save space)
    * Value String: "Ban"/"Approve"/"None"
    * Is Required: Yes
* **Reason**
    * Field Identifier: TODO (see readReviews.go)
    * Description: Reason for Approve/Ban
    * Value Bytes: Unicode UTF-8 bytes (TODO: Length limit)
    * Value String: Unicode UTF-8 String
    * Is Required: No
* **ErrantProfiles**
    * Field Identifier: TODO (see readReviews.go)
    * Description: List of profile hashes that serve as evidence for why the ban happened (if Verdict == Ban and ReviewedType == "Identity")
    * Value Bytes: `[][28]byte` (List of profile hashes)
    * Value String: TODO
    * Is Required: No
* **ErrantMessages**
    * Field Identifier: TODO (see readReviews.go)
    * Description: Same as ErrantProfiles but with message hashes
    * Value Bytes: `[][26]byte` (List of message hashes)
    * Value String: TODO
    * Is Required: No
* **ErrantReviews**
    * Field Identifier: TODO (see readReviews.go)
    * Description: Same as ErrantProfiles but with review hashes (if reviewed identity hash profileType == "Moderator")
    * Value Bytes: `[][29]byte` (List of review hashes)
    * Value String: TODO
    * Is Required: No
* **ErrantAttributes** 
    * Field Identifier: TODO (see readReviews.go)
    * Description: Same as ErrantProfiles but with attribute hashes
    * Value Bytes: `[][27]byte` (List of attribute hashes)
    * Value String: TODO
    * Is Required: No
* **MessageCipherKey**
    * Field Identifier: TODO (see readReviews.go)
    * Description: Cipher key used to decrypt reviewed message
    * Value Bytes: `[32]byte`
    * Value String: `[32]byte` encoded as Hex
    * Is Required: Yes (If reviewedType == "Message")

## Reports

Report creation is implemented in `/internal/moderation/createReports/createReports.go`

Report reading is implemented in `/internal/moderation/readReports/readReports.go`

Reports are encoded in MessagePack.

### Report Hashes

A report hash is a 29 byte Blake3 hash of the report bytes with 1 byte metadata suffix.

The Metadata byte is described below:
* 1 = Identity report
* 2 = Profile report
* 3 = Attribute report
* 4 = Message report

### Report Encoding

A report is a MessagePack encoded map of `map[int][]byte`
    * Map structure: Field Identifier -> Field value (encoded MessagePack)

### Report Fields:

Each field value has a bytes and string representation.

The bytes representation is used to encode the values in MessagePack.

The string representation is used to read the report into a `map[string]string`.

* **ReportVersion**
    * Field Identifier: TODO (see readReports.go)
    * Description: The version of the report.
        * New versions are created when the format/specification for encoding reports is changed
    * Value Bytes: `int`
    * Value String: `int` encoded as String
    * Is Required: Yes
* **NetworkType**
    * Field Identifier: TODO (see readReports.go)
    * Description: The network type of the report.
        * 1 == Mainnet, 2 == Testnet1
    * Value Bytes: `byte`
    * Value String: `byte` encoded as String
    * Is Required: Yes
* **CreationTime**
    * Field Identifier: TODO (see readReports.go)
    * Description: Unix creation time of report (number of seconds after unix origin time representing creation time of report)
    * Value Bytes: `int64` 
    * Value String: `int64` encoded as String
    * Is Required: Yes
* **ReportedHash**
    * Field Identifier: TODO (see readReports.go)
    * Description: Identity Hash or Profile Hash or Attribute Hash or Message Hash being reported
    * Value Bytes: `[]byte`
    * Value String: Reported hash encoded as String (Identity hashes use custom encoding, message/profile/attribute hashes are encoded in Hex)
    * Is Required: Yes
* **Reason**
    * Field Identifier: TODO (see readReports.go)
    * Description: Explanation of unruleful behavior
    * Value Bytes: Unicode UTF-8 bytes
    * Value String: Unicode UTF-8 String
    * Is Required: No
* **MessageCipherKey**
    * Field Identifier: TODO (see readReports.go)
    * Description: Cipher key of message that is being reported (If ReportedType == "Message")
    * Value Bytes: `[32]byte` Cipher key bytes
    * Value String: `[32]byte` encoded as Hex
    * Is Required: Yes (if reportedType == "Message")

## Global Settings

These are the settings that are stored within the `globalSettings` package.

Each setting is an entry in a `map[string]string`.

* **AppTheme**
    * Description: The color scheme to display the app in.
    * Value: "Light"/"Dark"/"Love"
* **MetricOrImperial** 
    * Description: The measurement system to display length values in
    * Value: "Metric"/"Imperial"
* **Currency**
    * Description: The currency to use when displaying monetary values to the user
    * Value: 3 letter ISO currency code to display all amounts in (Example: USD, EUR)
* **AppNetworkType**
    * Description: The network type byte the application should interface with.
    * Value: "1" or "2"
        * 1 == Mainnet, 2 == Testnet1

## User Settings

These are the settings that are stored with the `mySettings` package.

Each setting is an entry in a `map[string]string`.

*TODO: Some of these have an "OnOff" suffix, some don't. Some also have a "Status" suffix, some don't.*

*We should either remove these suffixes for all or add them for all, to standardize the names.*

*Some of the setting names could also be improved in other ways.*

* **MemoDecoration**
    * Description: The decoration to use when creating Seekia memos.
    * Value: "«« Seekia Memo »»"/"⁕ Seekia Memo ⁕"/"⁂ Seekia Memo ⁂"...
* **NavigationBarLocation**
    * Description: The location of the navigation bar within the GUI.
    * Value: "Top"/"Bottom"/"Left"/"Right"
* **ShowHostButtonNavigation**
    * Description: Describes if the Host button should be shown in the navigation bar.
    * Value: "Yes/"No"
* **ShowModerateButtonNavigation**
    * Description: Describes if the Moderate button should be shown in the navigation bar.
    * Value: "Yes"/"No"
* **AllowedStorageSpace**
    * Description: Describes the amount of allowed storage space for the database to use
    * Value: Float64 value that describes the gigabytes amount.
* **DeviceSeed**
    * Description: The entropy used to derive the device identifier for the user's Mate/Moderator identities
    * Value: 64 bytes, encoded in Hex
* **ChatPageIdentityType**
    * Description: The identity type the user is currently viewing on the Chat page.
    * Value: "Mate"/"Moderator"
* **MyMateContactsPageViewedCategory**
    * Description: The category the user is viewing on the Mate contacts page
    * Value: Category Name
* **MyHostContactsPageViewedCategory**
    * Description: The category the user is viewing on the Host contacts page
    * Value: Category name
* **MyModeratorContactsPageViewedCategory**
    * Description: The category the user is viewing on the Moderator contacts page
    * Value: Category name
* **HostModeOnOffStatus**
    * Description: The user's Host mode status.
    * Value: "On"/"Off"
* **HostingHostContent**
    * Description: The user's HostingHostContent status.
    * Value: "Yes"/"No"
* **HostingMateContent**
    * Description: The user's HostingMateContent status.
    * Value: "Yes"/"No"
* **HostingModeratorContent**
    * Description: The user's HostingModeratorContent status.
    * Value: "Yes"/"No"
* **HostedMateContentRangeStart**
    * Description: The start of the user's hosted Mate identities range.
    * Value: `[16]byte`, encoded in Hex
* **HostedMateContentRangeEnd**
    * Description: The end of the user's hosted Mate identities range
    * Value: `[16]byte`, encoded in Hex
* **HostMessagesOnOffStatus**
    * Description: The user's HostMessages status.
    * Value: "On"/"Off"
* **HostedInboxRangeStart**
    * Description: The start of the user's hosted message inboxes range.
    * Value: `[10]byte`, encoded in base32
* **HostedInboxRangeEnd**
    * Description: The end of the user's hosted message inboxes range.
    * Value: `[10]byte`, encoded in base32
* **HostOverClearnetOnOffStatus**
    * Description: The user's HostOverClearnet status
    * Value: "Yes"/"No"
* **HostOverTorOnOffStatus**
    * Description: The user's HostOverTor status
    * Value: "Yes"/"No"
* **HostUnviewableProfilesOnOffStatus**
    * Description: The user's HostUnviewableProfiles status
    * Value: "Yes"/"No"
* **HostUnviewableMessagesOnOffStatus**
    * Description: The user's HostUnviewableMessages status
    * Value: "Yes"/"No"
* **HostOverClearnetPort**
    * Description: The user's HostOverClearnet port.
    * Value: Positive integer value, encoded as String
* **ModeratorModeOnOffStatus**
    * Description: The user's moderator mode status
    * Value: "On"/"Off"
* **ModerateMessagesOnOffStatus**
    * Description: The user's ModerateMessages status
    * Value: "On"/"Off"
* **ModeratedInboxRangeStart**
    * Description: The user's moderated inbox range start
    * Value: `[10]byte`, encoded as base32
* **ModeratedInboxRangeEnd**
    * Description: The user's moderated inbox range end
    * Value: `[10]byte`, encoded as base32
* **ModerateMateContentOnOffStatus**
    * Description: The user's ModerateMateContent status
    * Value: "On"/"Off"
* **ModerateHostContentOnOffStatus**
    * Description: The user's ModerateHostContent status
    * Value: "On"/"Off"
* **ModerateModeratorContentOnOffStatus**
    * Description: The user's ModerateModeratorContent status
    * Value: "On"/"Off"
* **ModeratedMateContentRangeStart**
    * Description: The user's moderated Mate content identity range start
    * Value: `[16]byte`, encoded as Hex
* **ModeratedMateContentRangeEnd**
    * Description: The user's moderated Mate content identity range end
    * Value: `[16]byte`, encoded as Hex
* **ModeratedHostContentRangeStart**
    * Description: The user's moderated Host content identity range start
    * Value: `[16]byte`, encoded as Hex
* **ModeratedHostContentRangeEnd**
    * Description: The user's moderated Host content identity range end
    * Value: `[16]byte`, encoded as Hex
* **ModeratedModeratorContentRangeStart**
    * Description: The user's moderated Moderator content identity range start
    * Value: `[16]byte`, encoded as Hex
* **ModeratedModeratorContentRangeEnd**
    * Description: The user's moderated Moderator content identity range end
    * Value: `[16]byte`, encoded as Hex
* **MatchesNeedRefreshYesNo**
    * Description: The matchesNeedRefresh status
        * This is set to "Yes" when new mate profiles are downloaded
    * Value: "Yes"/"No"
* **MatchesGeneratedStatus**
    * Description: The user's MatchesGeneratedStatus
        * This is set to "No" whenever the user changes their desires
    * Value: "Yes"/"No"
* **MatchesSortedStatus**
    * Description: The user's MatchesSortedStatus
    * Value: "Yes"/"No"
* **MatchesSortDirection**
    * Description: The user's MatchesSortDirection
    * Value: "Ascending"/"Descending"
* **MatchesSortByAttribute**
    * Description: The user's MatchesSortByAttribute
    * Value: Sort by Attribute ( Examples: "Height", "Wealth", "MatchScore")
* **MatchesViewIndex**
    * Description: The user's MatchesViewIndex
        * This describes the match the user is currently viewing
    * Value: Integer between (0-2147483647)
* **MateChatMessagesUpdatedStatus**
    * Description: The user's Mate ChatMessagesUpdatedStatus
       * Is true if all of the user's Mate chat messages have been imported 
    * Value: "Yes"/"No"
* **ModeratorChatMessagesUpdatedStatus**
    * Description: The user's Moderator ChatMessagesUpdatedStatus
       * Is true if all of the user's Moderator chat messages have been imported 
    * Value: "Yes"/"No"
* **MateChatConversationsGeneratedStatus**
    * Description: The user's Mate chat conversations generated status
    * Value: "Yes"/"No"
* **ModeratorChatConversationsGeneratedStatus**
    * Description: The user's Moderator chat conversations generated status
    * Value: "Yes"/"No"
* **MateChatConversationsSortedStatus**
    * Description: The user's Mate chat conversations sorted status
    * Value: "Yes"/"No"
* **ModeratorChatConversationsSortedStatus**
    * Description: The user's Moderator chat conversations sorted status
    * Value: "Yes"/"No"
* **MateChatConversationsNeedRefreshYesNo**
    * Description: The user's Mate chat conversations need refresh status
        * It is set to "Yes" whenever a new message has been downloaded that belongs to one of the user's Mate inboxes
    * Value: "Yes"/"No"
* **ModeratorChatConversationsNeedRefreshYesNo**
    * Description: The user's Moderator chat conversations need refresh status
        * It is set to "Yes" whenever a new message has been downloaded that belongs to one of the user's Moderator inboxes
    * Value: "Yes"/"No"
* **MateChatConversations_SortByAttribute**
    * Description: The user's Mate chat conversations sort by attribute
    * Value: Sort by attribute (Example: "Height", "Age")
* **ModeratorChatConversations_SortByAttribute**
    * Description: The user's Moderator chat conversations sort by attribute
    * Value: Sort by attribute (Example: "IdentityScore")
* **MateChatConversations_SortDirection**
    * Description: The user's Mate chat conversations sort direction
    * Value: "Ascending"/"Descending"
* **ModeratorChatConversations_SortDirection**
    * Description: The user's Moderator chat conversations sort direction
    * Value: "Ascending"/"Descending"
* **MateChatConversations_ViewIndex**
    * Description: The user's Mate chat conversations view index.
        * This describes the page of chat conversations the user is viewing.
    * Value: Integer between (0-2147483647)
* **ModeratorChatConversations_ViewIndex**
    * Description: The user's Moderator chat conversations view index.
        * This describes the page of chat conversations the user is viewing.
    * Value: Integer between (0-2147483647)
* **ViewedContentGeneratedStatus**
    * Description: The user's ViewedContent generated status
    * Value: "Yes"/"No"
* **ViewedContentSortedStatus**
    * Description: The user's ViewedContent sorted status
    * Value: "Yes"/"No"
* **ViewedContentSortByAttribute**
    * Description: The user's ViewedContent sort by attribute
    * Value: Sort by attribute (Example: "Controversy")
* **ViewedContentSortDirection**
    * Description: The user's ViewedContent sort direction
    * Value: "Ascending"/"Descending"
* **ViewedContentNeedsRefreshYesNo**
    * Description: The user's ViewedContentNeedsRefresh status
    * Value: "Yes"/"No"
* **ViewedContentViewIndex**
    * Description: The user's ViewedContent view index
        * This represents the page of viewedContents they are viewing
    * Value: Integer between (0-2147483647)
* **ViewedModeratorsGeneratedStatus**
    * Description: The user's ViewedModeratorsGeneratedStatus
    * Value: "Yes"/"No"
* **ViewedModeratorsSortedStatus**
    * Description: The user's ViewedModeratorsSorted status
    * Value: "Yes"/"No"
* **ViewedModeratorsNeedsRefreshYesNo**
    * Description: The user's ViewedModeratorsNeedsRefresh status
    * Value: "Yes"/"No"
* **ViewedModeratorsSortByAttribute**
    * Description: The user's ViewedModerators sort by attribute
    * Value: Sort by attribute (Example: "IdentityScore", "Controversy")
* **ViewedModeratorsSortDirection**
    * Description: The user's ViewedModeratorsSortDirection
    * Value: "Ascending"/"Descending"
* **ViewedModeratorsViewIndex**
    * Description: The user's ViewedModeratorsViewIndex
    * Value: Integer between (0-2147483647)
* **ViewedHostsGeneratedStatus**
    * Description: The user's ViewedHostsGenerated status
    * Value: "Yes"/"No"
* **ViewedHostsSortedStatus**
    * Description: The user's ViewedHostsSorted status
    * Value: "Yes"/"No"
* **ViewedHostsNeedsRefreshYesNo**
    * Description: The user's ViewedHostsNeedsRefresh status
    * Value: "Yes"/"No"
* **ViewedHostsSortByAttribute**
    * Description: The user's ViewedHostsSortByAttribute
    * Value: Sort by attribute (Example: "BanAdvocates")
* **ViewedHostsSortDirection**
    * Description: The user's ViewedHostsSortDirection
    * Value: "Ascending"/"Descending"
* **ViewedHostsViewIndex**
    * Description: The user's ViewedHosts view index. This describes the page of viewedHosts they are viewing.
    * Value: Integer between (0-2147483647)

# Questionnaire

*TODO: Encode Questionnaire and responses using MessagePack rather than this current encoding*

Questionnaires and responses are implemented in `/internal/network/mateQuestionnaire/mateQuestionnaire.go`

A questionnaire can contain a maximum of 25 questions.

Each question has:

* Identifier
* Type
* Content
* Options

Each question is separated by "+&"

{Question1} + "+&" + {Question2} + "+&" + {Question3} + ...

Question information is separated by "%¢"

{Identifier} + "%¢" + {Type} + "%¢" + {Content} + "%¢" + {Options}

*TODO: Swap order of Content and Options*

*TODO: Change length of question identifiers to 12/13 to avoid collisions. 9 bytes is too short, 10 is already being used for inboxes, 11 is already being used for device identifiers.*

There are 2 questions types: **Choice** and **Entry**.

* **Choice**:
    * Identifier: 9 bytes encoded Hex
    * Type: "Choice"
    * Options:
        * {Maximum Answers Allowed} + "#" + {Choices delimited by "$¥"}
        * Each choice can be a maximum of 100 bytes in length
        * Each choice cannot contain "+&" or "%¢" or "$¥"
    * Content:
        * Value: The question text (Example: "Select the music genres you enjoy.")
        * Maximum of 500 bytes in length
        * Text cannot contain "+&" or "%¢"
        * Maximum Answers allowed: 1, 2, 3, 4, 5, or 6
* **Entry**:
    * Identifier: 10 bytes encoded Hex
    * Type: "Entry"
    * Options: "Numeric"/"Any"
    * Content:
        * Value: The question text (Example: "What is your favourite movie?")
        * Maximum of 500 bytes in length
        * Cannot contain "+&" or "%¢"

## Questionnaire Response

A questionnaire response is encoded as follows:

Each question response is delimited with "+&"

{Question1} + "+&" + {Question2} + "+&" + {Question3} + ...

Question: {Identifier} + "%" + {Response}

* **Entry**:
    * Identifier:
        * The question identifier 
    * Response:
        * Response (Maximum of 2000 bytes)
        * Response cannot contain "+&"
* **Choice**:
    * Identifier:
        * The question identifier
    * Response:
        * The number of each choice, separated by "$" (Choice 1 = "1", choice 2 = "2"...)

## Requests and Responses

Requests and responses are used to communicate with Seekia hosts.

Requests are implemented in `internal/network/serverRequest/serverRequest.go`

Responses are implemented in `internal/network/serverResponse/serverResponse.go`

All requests and responses are encoded in MessagePack.

The `RecipientHost`, `RequestType`, `RequestIdentifier`, and `NetworkType` fields exist for all requests but are not included here.

* **GetParametersInfo**
    * Description:
        * Used to retrieve info on the parameters a host has
    * Request:
        * *Nothing other than the standard fields.*
    * Response:
        * ParametersInfo: `map[string]int64`
            * {ParametersType -> Parameters creation time} for each stored parameters (Empty if none exist)
* **GetParameters**
    * Description:
        * Used to retrieve parameters from a host
    * Request:
        * ParametersTypesList: `[]string`
            * List of parameters types to retrieve
    * Response:
        * ParametersList: `[]RawMessagePack`
            * List of parameters (each encoded in MessagePack)

* **GetProfilesInfo**
    * Description:
        * Used to get information about profiles
        * Can be used by to get profiles authored by specified authors
    * Request:
        * AcceptableVersionsList: `[]int`
            *  Acceptable profile versions the requestor can accept
        * ProfileType: "Mate"/"Host"/"Moderator"
        * IdentityHashesList: `[][16]byte`
            * Limit request to profiles authored by specific identity hashes
        * RangeStart: `[16]byte`
            * Identity hash range start
        * RangeEnd: `[16]byte`
            * Identity hash range end
        * GetNewestOnly: `bool`
            * Only retrieve newest profiles (maximum 1 profile for each identity)
        * GetViewableOnly: `bool`
            * Only retrieve viewable profiles
        * Criteria: Criteria of the profiles to retrieve. Profiles must fulfill the criteria.
            * Encoded MessagePack, see `mateCriteria.go` and `myMateCriteria.go` to see how it is formatted
    * Response:
        * ProfilesInfo: `[]ProfileInfoStruct` (empty if none exist)
            * ProfileInfoStruct:
                * ProfileHash: Profile hash `[28]byte`
                * ProfileAuthor: Profile author identity hash `[16]byte`
                * ProfileCreationTime: Profile Creation Time `int64` 

* **GetProfiles**
    * Description:
        * Used to retrieve profiles
    * Request:
        * ProfileType: "Mate"/"Host"/"Moderator"
            * Profile type of profile hashes to retrieve
        * ProfileHashesList: `[][28]byte`
            * List of profile hashes of profiles to retrieve
    * Response:
        * ProfilesList: `[]RawMessagePack`
            * List of profiles (empty if none exist)

* **GetMessageHashesList**
    * Description:
        * Used to get message hashes of messages
    * Request:
        * AcceptableVersions: `[]int`
            * Message versions the requestor can accept 
        * RangeStart: `[10]byte`
            * Start of message inbox range to retrieve
        * RangeEnd: `[10]byte`
            * End of message inbox range to retrieve
        * InboxesList: `[][10]byte`
            * List of inboxes to retrieve (Empty if none provided)
            * All messages in response must be sent to the inboxes in the list (unless list is empty)
        * GetViewableOnly: `bool`
            * If true, only retrieve messages that are not banned
        * GetDecryptableOnly: `bool`
            * If true, only retrieve messages which have been reviewed or reported with a valid message cipher key
    * Response:
        * MessageHashesList: `[][26]byte`
            * List of message hashes (Empty if none exist)
* **GetMessages**
    * Description:
        * Get messages
    * Request:
        * MessageHashesList: `[][26]byte`
            * List of message hashes of messages to retrieve
    * Response:
        * MessagesList: `[]RawMessagePack`
            * List of messages (Empty if none exist)

* **GetIdentityReviewsInfo**
    * Description:
        * Used to retrieve info about identity, profile, and attribute reviews that a host has.
    * Request:
        * AcceptableVersions: `[]int`
            * Review versions the requestor can accept
        * IdentityType: "Mate"/"Host"/"Moderator"
            * Identity type of reviewed identity/profile author/attribute hashes to retrieve
        * ReviewedIdentitiesList: `[][16]byte`
            * Only retrieve reviews reviewing these identity hashes, or profiles/attributes authored by these identities
            * If list is empty, allow all identities/profiles/attributes within requested range.
        * ReviewersList: `[][16]byte`
            * List of reviewer identity hashes (to only retrieve reviews authored by these reviewers)
            * If list is empty, allow all reviewers
        * RangeStart: `[16]byte`
            * Start of reviewed identity hash range
        * RangeEnd: `[16]byte`
            * End of reviewed identity hash range
    * Response:
        * ReviewsInfo: `map[[29]byte][]byte`
            * Map Structure: Review Hash -> Reviewed Hash (Empty if none exist)
            * Reviewed hash is either an identity hash, profile hash, or attribute hash
* **GetMessageReviewsInfo**
    * Description:
        * Used to retrieve info about message reviews the host has.
    * Request:
        * AcceptableVersions: `[]int`
            * Review versions the requestor can accept
        * ReviewedMessagesList: `[][26]byte`
            * Only retrieve reviews reviewing these message hashes.
            * If list is empty, allow all reviewed message within requested range.
        * ReviewersList: `[][16]byte`
            * List of reviewer identity hashes (to only retrieve reviews authored by these reviewers)
            * If list is empty, allow all reviewers
        * RangeStart: `[10]byte`
            * Start of reviewed message inbox range
            * Reviewed messages must be sent to an inbox within this range
        * RangeEnd: `[10]byte`
            * End of reviewed message inbox range
    * Response:
        * ReviewsInfo: `map[[29]byte][26]byte`
            * Map Structure: Review Hash -> Reviewed Message Hash
            * Map is empty if no reviews exist

* **GetReviews**
    * Description:
        * Used to retrieve reviews
    * Request:
        * ReviewHashesList: `[][29]byte`
            * List of review hashes of reviews to retrieve
    * Response:
        * ReviewsList: `[]RawMessagePack`
            * List of reviews (Empty if none exist)

* **GetIdentityReportsInfo**
    * Description:
        * Used to retrieve info about identity, profile, and attribute reports that the host has.
    * Request:
        * AcceptableVersions `[]int`
            * Report versions the requestor can accept
        * IdentityType: "Mate"/"Host"/"Moderator"
            * Identity type of reported identity hashes to retrieve (or authors of reported profiles/attributes)
        * RangeStart: `[16]byte`
            * Start of reported identity hash range to retrieve
        * RangeEnd: `[16]byte`
            * End of reported identity hash range to retrieve
        * ReportedIdentitiesList: `[][16]byte`
            * List of reported identity hashes to retrieve reports for (reported identity hashes, or authors of reported profiles/attributes)
    * Response:
        * ReportsInfo: `map[[30]byte][]byte`
            * Map Structure: Report hash -> Reported Hash (Empty if none exist)
            * Reported hash is either an identity hash, profile hash, or attribute hash
* **GetMessageReportsInfo**
    * Description:
        * Used to retrieve info about message reports the host has.
    * Request:
        * AcceptableVersions `[]int`
            * Report versions the requestor can accept
        * RangeStart: `[10]byte`
            * Start of reported message inbox range
            * Reports must be reporting messages that were sent to an inbox within this range
        * RangeEnd: `[10]byte`
            * End of reported message inbox range
        * ReportedMessagesList: `[][26]byte`
            * List of reported message hashes to retrieve reports for
    * Response:
        * ReportsInfo: `map[[30]byte][26]byte`
            * Map Structure: Report hash -> Reported Message Hash
            * Map is empty if no reports exist.
* **GetReports**
    * Description:
        * Used to retrieve reports
    * Request:
        * ReportHashesList: `[][30]byte`
            * List of report hashes of reports to retrieve
    * Response:
        * ReportsList: `[]RawMessagePack`
            * List of reports (Empty if none exist)

* **GetAddressDeposits**
    * Description:
        * Used to retrieve info about deposits made to cryptocurrency addresses
    * Request:
        * Cryptocurrency: "Ethereum", "Cardano"
        * AddressesList: `[]string`
            * List of cryptocurrency addresses to retrieve deposit information about
    * Response:
        * AddressDepositsList: `[]DepositStruct`
            * DepositStruct: This object type is used to represent a deposit to an address
                * Address: `string`
                    * The cryptocurrency address where funds were deposited
                * DepositTime: `int64`
                    * The unix time of the block when deposit(s) were made
                * DepositAmount: `big.Int`
                    * The sum of all deposit amounts in the block to the specified address, in crypto atomic units (example: wei)

* **GetViewableStatuses**
    * Description:
        * Used to retrieve verified moderator viewable consensus statuses
    * Request:
        * IdentityHashesList: `[][16]byte`
            * Identity hashes to retrieve viewable statuses of
        * ProfileHashesList: `[][28]byte`
            * Profile hashes to retrieve viewable statuses of
    * Response:
        * IdentityHashStatuses: `map[[16]byte]bool`
            * Map Structure: Identity Hash -> true/false (Viewable/Unviewable)
        * ProfileHashStatuses: `map[[28]byte]bool`
            * Map Structure: Profile Hash -> true/false (Viewable/Unviewable)

* **BroadcastContent**
    * Description:
        * Used to broadcast profiles, messages, reviews, reports, and parameters
    * Request:
        * ContentType: "Profile", "Message", "Review", "Report", "Parameters"
        * ContentList: `[]RawMessagePack`
            * List of each piece of content to broadcast
    * Response:
        * ContentAcceptedInfo: `map[string]bool`
            * Map Structure: Content Hash -> true/false
            * Host uses this to verify that the content is within their hosted range, and they will host the content

