<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.39 (Ruby 2.6.10) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-jennings-moq-mocha-chat-00" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.34.0 -->
  <front>
    <title abbrev="mocha-chat">MOCHA Chat: Messaging over MoQ Transport</title>
    <seriesInfo name="Internet-Draft" value="draft-jennings-moq-mocha-chat-00"/>
    <author fullname="Cullen Jennings">
      <organization>Cisco</organization>
      <address>
        <email>fluffy@iii.ca</email>
      </address>
    </author>
    <author fullname="Suhas Nandakumar">
      <organization>Cisco</organization>
      <address>
        <email>snandaku@cisco.com</email>
      </address>
    </author>
    <date year="2026" month="July" day="06"/>
    <area>Applications and Real-Time</area>
    <workgroup>Media Over QUIC</workgroup>
    <keyword>MoQ</keyword>
    <keyword>MOQT</keyword>
    <keyword>MOCHA</keyword>
    <keyword>Chat</keyword>
    <keyword>Messaging</keyword>
    <abstract>
      <?line 56?>

<t>This document specifies the messaging functionality for MOCHA
(MoQ Open Communication &amp; Hosting Architecture). It defines how
participants send and receive messages in channels using
MoQ Transport (MOQT) publish/subscribe primitives. Each device
publishes messages on its own track within a channel namespace,
enabling decentralized message production with relay-based
fan-out. This specification covers message naming, format,
causal ordering, delivery, roster management, and channel
discovery for text-based chat.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-jennings-moq-mocha-chat/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        Media Over QUIC Working Group mailing list (<eref target="mailto:moq@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/moq/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/moq/"/>.
      </t>
    </note>
  </front>
  <middle>
    <?line 68?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>Messaging is the most fundamental operation in any
communication system. This document specifies how MOCHA enables
real-time message exchange between participants in channels using
MOQT's publish/subscribe model.</t>
      <t>MOCHA Chat assigns each publishing device its own MOQT track
within a channel namespace. Messages are grouped by NTP time
in minutes, enabling straightforward time-based history
retrieval and relay caching. Causal ordering is maintained
through a previous-message linkage that forms a DAG across
the per-device tracks in a channel.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>See BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/>.</t>
      <t>This document uses terminology and architecture defined in
<xref target="MOCHA-ARCH"/>, including Provider, Organization, Team, Channel,
Device, GroupID, and ObjectID. The MOQT transport
primitives (Track, Group, Object, Namespace, Relay) are defined
in <xref target="MoQTransport"/>. HClientID and HDevID are defined in
<xref target="MOCHA-IDENTITY"/>.</t>
      <t>The following additional terms are used:</t>
      <dl>
        <dt>Provider:</dt>
        <dd>
          <t>The service provider operating the MOCHA deployment. Identified
by a domain name or similar unique string.</t>
        </dd>
        <dt>OrgID:</dt>
        <dd>
          <t>The organization identifier within a provider's deployment.</t>
        </dd>
        <dt>TeamID:</dt>
        <dd>
          <t>An identifier for a team or workspace within an organization.</t>
        </dd>
        <dt>ChannelID:</dt>
        <dd>
          <t>An identifier for a specific channel within a team.</t>
        </dd>
        <dt>MsgID:</dt>
        <dd>
          <t>A globally unique identifier for a message. Implementations
SHOULD use a UUID (version 4) to generate MsgIDs.</t>
        </dd>
      </dl>
    </section>
    <section anchor="chat-naming">
      <name>MOCHA Chat Naming</name>
      <section anchor="id-derivation">
        <name>Identifier Derivation</name>
        <t>The HClientID and HDevID used in namespace tuples and
track names are derived per <xref target="MOCHA-IDENTITY"/>,
Section "Identifier Derivation".</t>
      </section>
      <section anchor="channel-namespace">
        <name>Channel Namespace</name>
        <t>The MOQT tracks that carry chat messages use a namespace
tuple with the following fields:</t>
        <artwork><![CDATA[
  ("mocha_v1", <Provider>, <OrgID>, "chat", <TeamID>,
   <ChannelID>, <HClientID>)
]]></artwork>
        <t>For example, messages in the "general" channel of team
"engineering" at organization "acme" hosted by provider
"example.com":</t>
        <artwork><![CDATA[
  ("mocha_v1", "example.com", "acme", "chat", "engineering",
   "general", <HClientID>)
]]></artwork>
      </section>
      <section anchor="track-names">
        <name>Track Names</name>
        <t>Each device publishes messages on its own track within the
channel namespace. The track name is a single byte sequence:</t>
        <artwork><![CDATA[
  msg_v1_<HDevID>
]]></artwork>
        <t>For example:</t>
        <artwork><![CDATA[
  Namespace: ("mocha_v1", "example.com", "acme", "chat",
              "engineering", "general", <HClientID>)
  Track Name: "msg_v1_<HDevID>"
]]></artwork>
        <t>This per-device track design allows each device to publish
independently without coordinating Group IDs with other
publishers.</t>
      </section>
      <section anchor="group-semantics">
        <name>Group Semantics</name>
        <t>Groups are NTP time in minutes. The Group ID corresponds
to the NTP timestamp (in minutes) at the time the message
is published:</t>
        <artwork><![CDATA[
  group_id = floor(ntp_timestamp_seconds / 60)
]]></artwork>
        <t>This provides:</t>
        <ul spacing="normal">
          <li>
            <t>Natural time-based partitioning of messages.</t>
          </li>
          <li>
            <t>Straightforward mapping from wall-clock time to Group ID
for history retrieval.</t>
          </li>
          <li>
            <t>One-minute granularity balances caching efficiency with
latency.</t>
          </li>
        </ul>
      </section>
      <section anchor="object-semantics">
        <name>Object Semantics</name>
        <t>Within each group, messages are assigned sequentially
increasing Object IDs starting at 0. Each message occupies
exactly one MOQT object.</t>
      </section>
      <section anchor="moqt-object-mapping">
        <name>MOQT Object Mapping</name>
        <artwork><![CDATA[
  Namespace: ("mocha_v1", "example.com", "acme", "chat",
              "engineering", "general")
    |
    +-- Track: msg_v1_alice-laptop-1
    |   +-- Group 29598720 (minute: 2024-05-15 16:00 UTC)
    |   |   +-- Object 0: "Hello everyone"
    |   |   +-- Object 1: "Ready for standup?"
    |   |
    |   +-- Group 29598721 (minute: 2024-05-15 16:01 UTC)
    |       +-- Object 0: "Let's start"
    |
    +-- Track: msg_v1_bob-desktop-1
    |   +-- Group 29598720
    |   |   +-- Object 0: "Hey Alice!"
    |   |
    |   +-- Group 29598721
    |       +-- Object 0: "Sounds good"
    |       +-- Object 1: "Sharing my screen now"
    |
    +-- Track: msg_v1_carol-phone-1
        +-- Group 29598721
            +-- Object 0: "On my way, 2 min"
]]></artwork>
      </section>
    </section>
    <section anchor="message-format">
      <name>Message Format</name>
      <section anchor="encoding">
        <name>Encoding</name>
        <t>Messages are encoded as JSON <xref target="JSON"/> and compressed before
being placed in the MOQT object payload. The compression
algorithm is signaled via the MOCHA_COMPRESSION track
property (see <xref target="compression-property"/>).</t>
      </section>
      <section anchor="compression-property">
        <name>Compression Track Property</name>
        <t>The MOCHA_COMPRESSION track property signals the compression
algorithm applied to ALL objects on a message track. Publishers
MUST include this property in the PUBLISH message
(publisher-initiated flow) or SUBSCRIBE_OK
(subscriber-initiated flow).</t>
        <t>Subscribers MUST check for this property before processing
track payloads. If the property is absent, the subscriber
MUST treat the payload as uncompressed. If the property is
present with a value the subscriber does not support, the
subscriber MUST NOT attempt to process the payload and SHOULD
unsubscribe from the track.</t>
        <t>The following compression algorithm values are defined:</t>
        <table>
          <thead>
            <tr>
              <th align="left">Value</th>
              <th align="left">Algorithm</th>
              <th align="left">Reference</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">0</td>
              <td align="left">None</td>
              <td align="left">This document</td>
            </tr>
            <tr>
              <td align="left">1</td>
              <td align="left">GZIP</td>
              <td align="left">
                <xref target="RFC1952"/></td>
            </tr>
            <tr>
              <td align="left">2</td>
              <td align="left">Brotli</td>
              <td align="left">
                <xref target="RFC7932"/></td>
            </tr>
          </tbody>
        </table>
        <t>Implementations MUST support GZIP (value 1) and MAY support
Brotli (value 2). A publisher that does not compress MUST
either set the property to 0 or omit it entirely.</t>
      </section>
      <section anchor="message-structure">
        <name>Message Structure</name>
        <t>The message structure follows the MIMI content format style
<xref target="MIMI-CONTENT"/>, adapted for MOCHA's channel-based messaging.
Fields use short keys for compact JSON encoding.</t>
        <sourcecode type="json"><![CDATA[
{
  "msgId": "<hex-encoded MsgID>",
  "type": 0,
  "ts": 1715788800000,
  "sender": {
    "userId": "<user identifier>",
    "displayName": "<human-readable name>",
    "devId": "<device identifier>"
  },
  "content": {
    "type": "text/plain",
    "body": "<message text>"
  },
  "prev": ["<hex-encoded MsgID>", ...],
  "threadId": "<hex-encoded MsgID>",
  "replaces": "<hex-encoded MsgID>",
  "expires": 0,
  "ext": {}
}
]]></sourcecode>
        <t>The message fields are defined as follows:</t>
        <section anchor="top-level-fields">
          <name>Top-Level Fields</name>
          <dl>
            <dt>msgId (REQUIRED):</dt>
            <dd>
              <t>The globally unique identifier for this message within the
channel. Implementations SHOULD use a UUID (version 4).</t>
            </dd>
            <dt>type (REQUIRED):</dt>
            <dd>
              <t>Integer message type. This specification defines type 0
(none/system) and type 1 (text). The type field is
extensible for future message categories.</t>
            </dd>
            <dt>ts (REQUIRED):</dt>
            <dd>
              <t>The time the message was created, in milliseconds since
the Unix epoch. Set by the publisher's local clock.</t>
            </dd>
            <dt>sender (REQUIRED):</dt>
            <dd>
              <t>The originator of the message. See <xref target="sender-info"/>.</t>
            </dd>
            <dt>content (REQUIRED):</dt>
            <dd>
              <t>The message payload. See <xref target="content-structure"/>.</t>
            </dd>
            <dt>prev (REQUIRED):</dt>
            <dd>
              <t>A list of hex-encoded MsgIDs of the immediately preceding
message(s) in the channel. This forms a causal ordering
DAG across all tracks in the channel. An empty array
indicates no known predecessors. See <xref target="causal-ordering"/>.</t>
            </dd>
            <dt>threadId (OPTIONAL):</dt>
            <dd>
              <t>The hex-encoded MsgID of the root message that started
the thread. Present when this message is a reply within
a thread. Threads are flat — nested threading is not
supported. If absent, the message is a top-level channel
message.</t>
            </dd>
            <dt>replaces (OPTIONAL):</dt>
            <dd>
              <t>The hex-encoded MsgID of a prior message that this message
edits or deletes. Present when type is 2 (edit) or
3 (delete). See <xref target="message-edit-delete"/>.</t>
            </dd>
            <dt>expires (OPTIONAL):</dt>
            <dd>
              <t>Expiration time in milliseconds since the Unix epoch. If
non-zero, clients SHOULD hide the message after this time.
A value of 0 indicates no expiration.</t>
            </dd>
            <dt>ext (OPTIONAL):</dt>
            <dd>
              <t>An object containing extension fields. Implementations
MUST ignore unknown extension keys. Extensions are
namespaced to avoid collisions (see <xref target="MOCHA"/>).</t>
            </dd>
          </dl>
        </section>
        <section anchor="sender-info">
          <name>Sender Info</name>
          <t>The sender object identifies the message author:</t>
          <dl>
            <dt>userId (REQUIRED):</dt>
            <dd>
              <t>A stable identifier for the user within the identity
system (e.g., "alice@acme.example.com").</t>
            </dd>
            <dt>displayName (REQUIRED):</dt>
            <dd>
              <t>A human-readable label for rendering in the UI.</t>
            </dd>
            <dt>devId (REQUIRED):</dt>
            <dd>
              <t>The identifier of the publishing device. MUST match
the HDevID in the track name from which the message
is published.</t>
            </dd>
          </dl>
        </section>
        <section anchor="content-structure">
          <name>Content Structure</name>
          <t>The content object carries the message payload, following
MIMI's content disposition pattern:</t>
          <dl>
            <dt>type (REQUIRED):</dt>
            <dd>
              <t>A MIME type string indicating the content format. This
specification defines "text/plain" for plain text messages.
Implementations MUST support "text/plain".</t>
            </dd>
            <dt>body (REQUIRED):</dt>
            <dd>
              <t>The content payload. For "text/plain", this is a UTF-8
string containing the message text.</t>
            </dd>
          </dl>
          <t>Future specifications MAY define additional content types
(e.g., "text/markdown"). Clients receiving an unknown content
type SHOULD render the body as plain text if it is a string,
or display a placeholder indicating an unsupported format.</t>
        </section>
        <section anchor="message-type-values">
          <name>Message Type Values</name>
          <table>
            <thead>
              <tr>
                <th align="left">Value</th>
                <th align="left">Name</th>
                <th align="left">Description</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">0</td>
                <td align="left">none</td>
                <td align="left">System or control message (no body)</td>
              </tr>
              <tr>
                <td align="left">1</td>
                <td align="left">text</td>
                <td align="left">Text message</td>
              </tr>
              <tr>
                <td align="left">2</td>
                <td align="left">edit</td>
                <td align="left">Replaces content of a prior message</td>
              </tr>
              <tr>
                <td align="left">3</td>
                <td align="left">delete</td>
                <td align="left">Removes a prior message from display</td>
              </tr>
            </tbody>
          </table>
          <t>The type enum is extensible. Future specifications define
additional values for media and other content.</t>
        </section>
      </section>
      <section anchor="example-message">
        <name>Example Message</name>
        <t>A text message as JSON (before compression):</t>
        <sourcecode type="json"><![CDATA[
{
  "msgId": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
  "type": 1,
  "ts": 1715788800000,
  "sender": {
    "userId": "alice@acme.example.com",
    "displayName": "Alice Smith",
    "devId": "<HashDevID>"
  },
  "content": {
    "type": "text/plain",
    "body": "Hello everyone, ready for the standup?"
  },
  "prev": ["e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6"]
}
]]></sourcecode>
      </section>
    </section>
    <section anchor="causal-ordering">
      <name>Causal Ordering</name>
      <section anchor="previous-message-list">
        <name>Previous Message List</name>
        <t>Each message contains a "previous" field listing the MsgID(s)
of the most recent message(s) the publisher has observed in
the channel at the time of publishing. This forms a directed
acyclic graph (DAG) across all per-device tracks in a channel.</t>
        <artwork><![CDATA[
  Causal DAG across devices:

  Alice's track:     A1 -----> A2 ---------> A3
                      \          \           /
  Bob's track:         --> B1 --> B2 ------>
                                   \
  Carol's track:                    --> C1
]]></artwork>
        <t>In this example:</t>
        <ul spacing="normal">
          <li>
            <t>A1 has no previous (first message in channel, or references
messages not shown).</t>
          </li>
          <li>
            <t>B1.previous = [A1] (Bob saw Alice's first message).</t>
          </li>
          <li>
            <t>A2.previous = [B1] (Alice saw Bob's reply).</t>
          </li>
          <li>
            <t>B2.previous = [A2] (Bob saw Alice's second message).</t>
          </li>
          <li>
            <t>C1.previous = [B2] (Carol saw Bob's second message).</t>
          </li>
          <li>
            <t>A3.previous = [B2, C1] (Alice saw both Bob and Carol's
latest messages).</t>
          </li>
        </ul>
      </section>
      <section anchor="ordering-semantics">
        <name>Ordering Semantics</name>
        <t>The previous message list provides causal ordering:</t>
        <ul spacing="normal">
          <li>
            <t>If message B lists message A in its previous list
(directly or transitively), then A causally precedes B.</t>
          </li>
          <li>
            <t>Messages with no causal relationship are concurrent and
may be displayed in any order (typically by timestamp).</t>
          </li>
          <li>
            <t>Clients reconstruct channel ordering by traversing the
DAG.</t>
          </li>
        </ul>
      </section>
      <section anchor="display-ordering">
        <name>Display Ordering</name>
        <t>Clients SHOULD use the causal DAG to determine display
order. When causal ordering does not fully determine order
(concurrent messages), clients SHOULD fall back to timestamp
ordering.</t>
        <t>A simple linearization algorithm:</t>
        <ol spacing="normal" type="1"><li>
            <t>Topologically sort messages using the DAG.</t>
          </li>
          <li>
            <t>For concurrent messages (no causal relationship), sort
by timestamp.</t>
          </li>
          <li>
            <t>For identical timestamps, sort by MsgID (lexicographic
on the hash bytes) for deterministic ordering.</t>
          </li>
        </ol>
      </section>
    </section>
    <section anchor="message-edit-delete">
      <name>Message Edit and Delete</name>
      <t>A sender can edit or delete a message it previously published
by publishing a new object on the same track with the
<tt>replaces</tt> field set to the MsgID of the original message.</t>
      <section anchor="edit-type-2">
        <name>Edit (type 2)</name>
        <t>An edit message replaces the content of a prior message.
The <tt>content</tt> field carries the new text. The original
message's position in the causal DAG is preserved; the edit
object itself also participates in the DAG via its own <tt>prev</tt>
field.</t>
        <sourcecode type="json"><![CDATA[
{
  "msgId": "b2c3d4...",
  "type": 2,
  "ts": 1715788900000,
  "sender": {
    "userId": "alice@acme.example.com",
    "displayName": "Alice Smith",
    "devId": "<HashDevID>"
  },
  "content": {
    "type": "text/plain",
    "body": "Hello everyone, ready for standup? (corrected)"
  },
  "prev": ["a1b2c3..."],
  "replaces": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
}
]]></sourcecode>
      </section>
      <section anchor="delete-type-3">
        <name>Delete (type 3)</name>
        <t>A delete message removes a prior message from display. No
<tt>content</tt> field is required; if present it is ignored.</t>
        <sourcecode type="json"><![CDATA[
{
  "msgId": "c3d4e5...",
  "type": 3,
  "ts": 1715789000000,
  "sender": {
    "userId": "alice@acme.example.com",
    "displayName": "Alice Smith",
    "devId": "<HashDevID>"
  },
  "prev": ["b2c3d4..."],
  "replaces": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
}
]]></sourcecode>
      </section>
      <section anchor="processing-rules">
        <name>Processing Rules</name>
        <ol spacing="normal" type="1"><li>
            <t>Only the original sender (matching userId) MAY edit or
delete a message. Receivers MUST ignore edit or delete
objects from a different userId than the original message.</t>
          </li>
          <li>
            <t>Multiple edits to the same message are permitted. The
edit with the latest causal ordering (per
<xref target="causal-ordering"/>) takes precedence.</t>
          </li>
          <li>
            <t>A delete after an edit takes precedence: the message is
removed from display regardless of prior edits.</t>
          </li>
          <li>
            <t>Receivers SHOULD display an indicator that a message has
been edited. Receivers MAY offer access to the edit
history.</t>
          </li>
          <li>
            <t>Relays forward edit and delete objects like any other
message object without interpreting their semantics.</t>
          </li>
        </ol>
      </section>
    </section>
    <section anchor="threading">
      <name>Threading</name>
      <t>MOCHA supports threaded conversations where replies are
grouped under a parent message. Threads are flat — nested
threading is not supported.</t>
      <section anchor="thread-replies">
        <name>Thread Replies</name>
        <t>To reply within a thread, a device publishes a message on
its regular <tt>msg_v1_&lt;HDevID&gt;</tt> track with the <tt>threadId</tt> field
set to the MsgID of the root message that started the
thread. The root message itself has no <tt>threadId</tt> field.</t>
      </section>
      <section anchor="thread-display">
        <name>Thread Display</name>
        <t>Clients SHOULD group messages with the same <tt>threadId</tt> and
display them as a thread under the root message. The root
message is identified by its MsgID matching the <tt>threadId</tt>
of the replies.</t>
      </section>
      <section anchor="thread-edits-and-deletes">
        <name>Thread Edits and Deletes</name>
        <t>Edit and delete messages (types 2 and 3) within a thread
MUST carry the same <tt>threadId</tt> as the message they replace.
This allows clients to correctly scope the edit or delete
to the thread view.</t>
      </section>
    </section>
    <section anchor="roster-naming">
      <name>MOCHA Roster Naming</name>
      <t>The roster provides a discovery mechanism for participants
to learn which devices are active in a channel. Each device
publishes its availability and user identity on a dedicated
roster track. Participants subscribe to the roster namespace
to build the set of message tracks they should follow.</t>
      <section anchor="roster-namespace">
        <name>Roster Namespace</name>
        <t>The roster tracks for a channel use the namespace tuple:</t>
        <artwork><![CDATA[
  ("mocha_v1", <Provider>, <OrgID>, "roster", <TeamID>,
   <ChannelID>, <HClientID>)
]]></artwork>
        <t>HClientID and HDevID are derived per <xref target="id-derivation"/>.</t>
        <t>For example:</t>
        <artwork><![CDATA[
  ("mocha_v1", "example.com", "acme", "roster", "engineering",
   "general", <HClientID>)
]]></artwork>
      </section>
      <section anchor="roster-track-names">
        <name>Roster Track Names</name>
        <t>Each device publishes its user information on a track:</t>
        <artwork><![CDATA[
  user_<HDevID>
]]></artwork>
        <t>For example:</t>
        <artwork><![CDATA[
  Namespace: ("mocha_v1", "example.com", "acme", "roster",
              "engineering", "general", <HClientID>)
  Track Name: "user_<HDevID>"
]]></artwork>
      </section>
      <section anchor="roster-object-format">
        <name>Roster Object Format</name>
        <t>Each object on a roster track contains a JSON document
providing information about the mapping of the device to
a user in the identity system. The display_name is obtained
from the user's PAB entry (see <xref target="MOCHA"/>) and the user_id
is obtained from the identity system (see <xref target="MOCHA-IDENTITY"/>).</t>
        <sourcecode type="json"><![CDATA[
{
  "user_id": "alice@acme.example.com",
  "display_name": "Alice Smith",
  "dev_id": "<HashDevID>",
  "joined_at": 1715788000000,
  "status": "active"
}
]]></sourcecode>
      </section>
      <section anchor="roster-usage">
        <name>Roster Usage</name>
        <t>Participants subscribe to the roster namespace to discover
which devices are active in a channel. The roster provides
the set of msg_v1_&lt;HDevID&gt; tracks that should be subscribed
for receiving channel messages.</t>
        <t>When a new device joins a channel, it publishes a roster
object. When a device leaves, it publishes an updated roster
object with status "departed" or the track simply becomes
inactive.</t>
      </section>
    </section>
    <section anchor="channel-discovery">
      <name>Channel Discovery</name>
      <t>Channel discovery allows participants to learn which channels
are available within a team. A designated device (or server)
publishes channel metadata on a channel info track. Participants
subscribe to this namespace to present users with a list of
channels they can join.</t>
      <section anchor="channel-info-namespace">
        <name>Channel Info Namespace</name>
        <t>Channel discovery tracks use the namespace tuple:</t>
        <artwork><![CDATA[
  ("mocha_v1", <Provider>, <OrgID>, "channel_info", <TeamID>)
]]></artwork>
        <t>For example:</t>
        <artwork><![CDATA[
  ("mocha_v1", "example.com", "acme", "channel_info", "engineering")
]]></artwork>
      </section>
      <section anchor="channel-info-track-names">
        <name>Channel Info Track Names</name>
        <t>Each device (or server) that creates or manages channels
publishes channel information on a track:</t>
        <artwork><![CDATA[
  channel_<HDevID>
]]></artwork>
        <t>For example:</t>
        <artwork><![CDATA[
  Namespace: ("mocha_v1", "example.com", "acme",
              "channel_info", "engineering")
  Track Name: "channel_admin-server-1"
]]></artwork>
      </section>
      <section anchor="channel-info-object-format">
        <name>Channel Info Object Format</name>
        <t>Objects on channel info tracks contain the names and metadata
of channels available in the team:</t>
        <sourcecode type="json"><![CDATA[
{
  "channels": [
    {
      "channel_id": "general",
      "name": "#general",
      "topic": "General discussion",
      "type": "public"
    },
    {
      "channel_id": "backend",
      "name": "#backend",
      "topic": "Backend engineering",
      "type": "public"
    },
    {
      "channel_id": "secret-project",
      "name": "#secret-project",
      "type": "private"
    }
  ]
}
]]></sourcecode>
      </section>
    </section>
    <section anchor="availability">
      <name>Availability</name>
      <t>MOCHA provides an availability system for communicating user
availability and status within a channel. Channel membership
implicitly grants availability visibility — all channel members
can see each other's availability without explicit subscription
consent.</t>
      <section anchor="availability-namespace">
        <name>Availability Namespace</name>
        <t>Availability tracks for a channel use the namespace tuple:</t>
        <artwork><![CDATA[
  ("mocha_v1", <Provider>, <OrgID>, "availability", <TeamID>,
   <ChannelID>, <HClientID>)
]]></artwork>
        <t>HClientID is derived per <xref target="id-derivation"/>.</t>
      </section>
      <section anchor="availability-track-names">
        <name>Availability Track Names</name>
        <t>Each device publishes its availability on a dedicated track:</t>
        <artwork><![CDATA[
  availability_v1_<HDevID>
]]></artwork>
        <t>HDevID is derived per <xref target="id-derivation"/>.</t>
      </section>
      <section anchor="availability-states">
        <name>Availability States</name>
        <table>
          <thead>
            <tr>
              <th align="left">State</th>
              <th align="left">Description</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">online</td>
              <td align="left">User is active and available</td>
            </tr>
            <tr>
              <td align="left">away</td>
              <td align="left">User is idle or stepped away</td>
            </tr>
            <tr>
              <td align="left">dnd</td>
              <td align="left">Do not disturb — suppress notifications</td>
            </tr>
            <tr>
              <td align="left">offline</td>
              <td align="left">User is disconnected</td>
            </tr>
          </tbody>
        </table>
      </section>
      <section anchor="availability-object-format">
        <name>Availability Object Format</name>
        <t>Each object on an availability track contains:</t>
        <sourcecode type="json"><![CDATA[
{
  "status": "online",
  "status_message": "In meetings until 3pm",
  "last_active": 1715790000000,
  "idle_seconds": 0
}
]]></sourcecode>
        <t>Fields:</t>
        <ul spacing="normal">
          <li>
            <t><strong>status</strong>: One of the availability states above.</t>
          </li>
          <li>
            <t><strong>status_message</strong>: Optional human-readable status text.</t>
          </li>
          <li>
            <t><strong>last_active</strong>: NTP timestamp (milliseconds) of last
user activity.</t>
          </li>
          <li>
            <t><strong>idle_seconds</strong>: Seconds since last user interaction on
this device. Set to 0 when active.</t>
          </li>
        </ul>
      </section>
      <section anchor="availability-updates">
        <name>Availability Updates</name>
        <t>A device publishes a new availability object whenever its state
changes (e.g., user becomes idle, changes status, or goes
offline). Each new object replaces the previous state.</t>
        <t>Devices SHOULD publish an availability object with status
"offline" when gracefully disconnecting. If a device
disconnects without publishing an offline status, subscribers
detect the absence via track inactivity.</t>
      </section>
      <section anchor="typing-indicators">
        <name>Typing Indicators</name>
        <t>Typing indicators are ephemeral availability signals scoped to
a channel. They use the same availability namespace with a
separate track:</t>
        <artwork><![CDATA[
  typing_v1_<HDevID>
]]></artwork>
        <section anchor="typing-object-format">
          <name>Typing Object Format</name>
          <sourcecode type="json"><![CDATA[
{
  "is_typing": true,
  "thread_id": null,
  "ts": 1715790000000
}
]]></sourcecode>
          <t>Typing indicators:</t>
          <ul spacing="normal">
            <li>
              <t>SHOULD be delivered via QUIC datagrams (unreliable) for
low latency.</t>
            </li>
            <li>
              <t>SHOULD timeout after 5 seconds without an update.</t>
            </li>
            <li>
              <t>MAY be disabled per-user or per-channel.</t>
            </li>
          </ul>
        </section>
      </section>
      <section anchor="subscribing-to-availability">
        <name>Subscribing to Availability</name>
        <t>Participants subscribe (SUBSCRIBE_NAMESPACE) to the availability
namespace to receive availability and typing updates from all
channel members. This follows the same pattern as roster
subscription — joining a channel implicitly subscribes
the device to availability.</t>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>TODO</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <section anchor="mochacompression-track-property">
        <name>MOCHA_COMPRESSION Track Property</name>
        <t>This document requests IANA registration of the
MOCHA_COMPRESSION track property in the "MoQ Track Properties"
registry (if established by <xref target="MoQTransport"/>).</t>
        <dl>
          <dt>Property Name:</dt>
          <dd>
            <t>MOCHA_COMPRESSION</t>
          </dd>
          <dt>Property Type:</dt>
          <dd>
            <t>Track Property</t>
          </dd>
          <dt>Value Type:</dt>
          <dd>
            <t>Varint</t>
          </dd>
          <dt>Description:</dt>
          <dd>
            <t>Signals the compression algorithm applied to all objects
on a MOCHA message track.</t>
          </dd>
          <dt>Reference:</dt>
          <dd>
            <t>This document, <xref target="compression-property"/></t>
          </dd>
        </dl>
      </section>
      <section anchor="mocha-compression-algorithms-registry">
        <name>MOCHA Compression Algorithms Registry</name>
        <t>This document establishes a new "MOCHA Compression Algorithms"
registry with the following initial entries:</t>
        <table>
          <thead>
            <tr>
              <th align="left">Value</th>
              <th align="left">Algorithm</th>
              <th align="left">Reference</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">0</td>
              <td align="left">None</td>
              <td align="left">This document</td>
            </tr>
            <tr>
              <td align="left">1</td>
              <td align="left">GZIP</td>
              <td align="left">
                <xref target="RFC1952"/></td>
            </tr>
            <tr>
              <td align="left">2</td>
              <td align="left">Brotli</td>
              <td align="left">
                <xref target="RFC7932"/></td>
            </tr>
          </tbody>
        </table>
        <t>New entries require Specification Required (per <xref target="RFC8126"/>).</t>
      </section>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="MoQTransport">
          <front>
            <title>Media over QUIC Transport</title>
            <author fullname="Suhas Nandakumar" initials="S." surname="Nandakumar">
              <organization>Cisco</organization>
            </author>
            <author fullname="Victor Vasiliev" initials="V." surname="Vasiliev">
              <organization>Google</organization>
            </author>
            <author fullname="Ian Swett" initials="I." surname="Swett">
              <organization>Google</organization>
            </author>
            <author fullname="Alan Frindell" initials="A." surname="Frindell">
              <organization>Meta</organization>
            </author>
            <date day="12" month="May" year="2026"/>
            <abstract>
              <t>   This document defines Media over QUIC Transport (MOQT), a publish/
   subscribe protocol that runs over QUIC and WebTransport.  MOQT
   leverages the features of these transports, such as streams,
   datagrams, priorities, and partial reliability.  MOQT operates both
   point-to-point and through intermediate relays, enabling scalable
   low-latency delivery.  Despite its name, MOQT is media agnostic and
   can be used for a wide range of use cases.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-moq-transport-18"/>
        </reference>
        <reference anchor="MOCHA">
          <front>
            <title>*** BROKEN REFERENCE ***</title>
            <author>
              <organization/>
            </author>
            <date/>
          </front>
        </reference>
        <reference anchor="MOCHA-ARCH">
          <front>
            <title>*** BROKEN REFERENCE ***</title>
            <author>
              <organization/>
            </author>
            <date/>
          </front>
        </reference>
        <reference anchor="MOCHA-IDENTITY">
          <front>
            <title>*** BROKEN REFERENCE ***</title>
            <author>
              <organization/>
            </author>
            <date/>
          </front>
        </reference>
        <reference anchor="JSON">
          <front>
            <title>The JavaScript Object Notation (JSON) Data Interchange Format</title>
            <author fullname="T. Bray" initials="T." role="editor" surname="Bray"/>
            <date month="December" year="2017"/>
            <abstract>
              <t>JavaScript Object Notation (JSON) is a lightweight, text-based, language-independent data interchange format. It was derived from the ECMAScript Programming Language Standard. JSON defines a small set of formatting rules for the portable representation of structured data.</t>
              <t>This document removes inconsistencies with other specifications of JSON, repairs specification errors, and offers experience-based interoperability guidance.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="90"/>
          <seriesInfo name="RFC" value="8259"/>
          <seriesInfo name="DOI" value="10.17487/RFC8259"/>
        </reference>
        <reference anchor="RFC1952">
          <front>
            <title>GZIP file format specification version 4.3</title>
            <author fullname="P. Deutsch" initials="P." surname="Deutsch"/>
            <date month="May" year="1996"/>
            <abstract>
              <t>This specification defines a lossless compressed data format that is compatible with the widely used GZIP utility. This memo provides information for the Internet community. This memo does not specify an Internet standard of any kind.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="1952"/>
          <seriesInfo name="DOI" value="10.17487/RFC1952"/>
        </reference>
        <reference anchor="RFC7932">
          <front>
            <title>Brotli Compressed Data Format</title>
            <author fullname="J. Alakuijala" initials="J." surname="Alakuijala"/>
            <author fullname="Z. Szabadka" initials="Z." surname="Szabadka"/>
            <date month="July" year="2016"/>
            <abstract>
              <t>This specification defines a lossless compressed data format that compresses data using a combination of the LZ77 algorithm and Huffman coding, with efficiency comparable to the best currently available general-purpose compression methods.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7932"/>
          <seriesInfo name="DOI" value="10.17487/RFC7932"/>
        </reference>
        <reference anchor="RFC8126">
          <front>
            <title>Guidelines for Writing an IANA Considerations Section in RFCs</title>
            <author fullname="M. Cotton" initials="M." surname="Cotton"/>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <author fullname="T. Narten" initials="T." surname="Narten"/>
            <date month="June" year="2017"/>
            <abstract>
              <t>Many protocols make use of points of extensibility that use constants to identify various protocol parameters. To ensure that the values in these fields do not have conflicting uses and to promote interoperability, their allocations are often coordinated by a central record keeper. For IETF protocols, that role is filled by the Internet Assigned Numbers Authority (IANA).</t>
              <t>To make assignments in a given registry prudently, guidance describing the conditions under which new values should be assigned, as well as when and how modifications to existing values can be made, is needed. This document defines a framework for the documentation of these guidelines by specification authors, in order to assure that the provided guidance for the IANA Considerations is clear and addresses the various issues that are likely in the operation of a registry.</t>
              <t>This is the third edition of this document; it obsoletes RFC 5226.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="26"/>
          <seriesInfo name="RFC" value="8126"/>
          <seriesInfo name="DOI" value="10.17487/RFC8126"/>
        </reference>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="MIMI-CONTENT" target="https://datatracker.ietf.org/doc/draft-ietf-mimi-content/">
          <front>
            <title>More Instant Messaging Interoperability (MIMI) Content Format</title>
            <author fullname="R. Mahy">
              <organization/>
            </author>
            <date year="2024"/>
          </front>
        </reference>
      </references>
    </references>
  </back>
  <!-- ##markdown-source:
H4sIAFw/TGoAA9086XLbSHr/+yk6VFWWnJC0KNljW5l1hjo81sa2PDp2a7M7
ZYNAU8QYBDhoUDLX1lYeIk+YJ8l3daMBkrI9u5tUhVUzpog+vv7uqzEYDFSV
Vpk50J1XZ0cvxvpoFlUH+pWxNrpO82td3JhSvyp+1JdllNtFUVYdFU0mpbmB
KfMinkUD+A9+jKPKXBfl6kDbKlEqKeI8msO6SRlNq8HPJs9hOTuYF78M6mmD
3V1ll5N5am1a5NVqARNOTy6fq3w5n5jyQCWw6oGKi9ya3C7tga7KpVGw976K
ShMBDOPFIkthc5hvdZQn+txE2eAynZuOui3K99dlsVzg8UySRvoMj/Pj1elR
R703K3ieHCg9wAPSP2c/XvK/gAr8gtigHxw+1I3JlwCR1lvX1ZrP0fkD7I4o
/AFH4u/zKM0Ia798n5pqOizKa/w5KuMZ/DyrqoU9ePAAR+FP6Y0ZumEP8IcH
k7K4teYBzH/QUSpaVrOiRFAG8J/W02WWMcqP4JvJ9e8E5/QUFony9C+EJxiR
2rig3w0DNc2W0+nq+zRNh3GkNqx5sZxFVr8GBEfvl/Oo/JJFbc7Dv4/xyTAu
5krlRTmH8TeEQ0C7Zysg/OB4yNyCxyZOqdxTHIxECUet85QbNRifH724f+gA
MerHnx6fvL48vfzjZ+akiclBXFYw73cXZ68P9Pnzoyd7j54iwuDr6OmjvQP+
+vjpvvv6ZLT37YFSaT5tHP301eng6Oz1JWx8QEjzcliURp/mtoryKhDE07wy
ZbEwZTRJM4BBd3GJnj4CuQGo9HNavUNLkdTovd29h/RnzSlA14Cm50P9Kpqt
ePeovDZABMeFsEQE2I/fm7LmQhDqByGF0nk6iHn/B0oNBgMdTSzOqpS6nKVW
w4TlHKGzCxOn09RYXc2MnvtTTZd5jNwT0ZEAQyJ7XVQ5Zwvg4qNiPl/mIuH6
n/WLwlY4c4wiUpm4WpamN9SnlU7MNM1hh1lxqxZRWaVxugAcWg26IyHVUJrY
AP5lfxia5hromucms3ppUb4bqg5wDBqhpxfLSZba2QNQVTYu04nRixLOjrS0
Q30SxTPY/CaNjZKRsLTfA6BOAYjiNteEUH2bVjPYOHJba6SGXUSx6SuTR7AA
HC8BUHMYn6V/MYlbDLYtkiUhjFaBA2XRajCJrEnUNMoHxbIaasK8IFzQFqMa
9zDhhrBHXzNH9kF3L22UgTgnpqQHicngbOWqr0tAN6i2eZTDRCRlnzApoKsE
JRtHEu0q86FiaHBANWSemKdJkhmldpCH/QGUqnk7FbaAvZAjkgg3QoCQ3ekA
iK98BYYgZAa7AtjmcuANrAaMwOykCa3GqhJtQwW2waPCfMCjwJeJqW4N8FuD
czbwBzDEb+wGjpgXgDQ4cW1GdQRW7RqskkEGkRlMW+QVzxW4JLOG2s4aQ1EF
cCwwfGx9AM2TlX59+UbjkUDDAKrzZWVsX3s+QnFMr2cVkOc2KhMaKSQCrFVg
sAEpVZmaG8A3ywiwlI4BZJg+1EdN1kBSgXIH6oCoJaqaARzXMwB4AR5BWixB
WwpiYff3+G+FmEBGA8D18fgHHcXAU1YhwYG8A0EGnZ8Q7g8PyASeAf12g1rX
mfdjlPKU/lbqwhh9ePRGjx7qjx//CZTt3mj09O5O/ngyevzw7m7Y1kVLi2rI
lICsIiuuV7RsFKgT0SQJQKM+fqwtyt1dH36Ks2WCmHhTFjdgEMq+PgvMYF9f
mmjeRwbAM/TVMZ2vz17A6TGLz9nkZ9jq9Bh513gGEFNX6xbdvUS0yOS+TOuD
GXYKA7wdIFePeEKgRj4AqAPTCjjQL46yFA5/ekz7vwCo8OvmszprKLgzQL4s
K27x0FGSpKyvCYPMjIBQcKOUQ8iBOqBjWVMSaRfyuxNnWKaiU6OgJGaRFSuk
C+hwMq8gugmYJODsCGiGzEZSACyoLSAGfCMNKuCXpUHeRh5VCghweuy2DZ0S
nboly1rtOnhAjIPd4aRAOF5m3JiImi2C40ZzhAF9SsK9XzBvbAkLCe23r+WU
sxdzDxvugkrEyoHG+jorJlGWrdyh1xYTgQP0zRcZqWh2hgGHFy/Orl4eI31g
3NUVULyLdgAR87Cnq0JfmxxJAsTADe0QBS5QYK/JTuiPO+Srs9W4gzE7NalK
EMgyvWFsf9xJk0Hi/75j7tnIesgzWkjL6KyWAD7JuGI7SY+ER2FJGA/8o9eZ
tA9qgG1iZyNYnSGBLFSphYehq7WvZV0VRyWYMzxxbcMZgx5WRbCyCa4a8gFb
Z4kFYfjrX/8KBOhyiPT2ZtTp6++cgDyD78Sy8KVD0RP8wNz3rI/e2Heeg3Co
x9+zHi2rwNUDuxUhufsNXwZh6TBNs45nrmJKbKU6Jgdra0iPdzQcryEpnSiG
kAlsJthUsitOTGAe74UOfGfz0RpD+rJWfbjGznRCD+Wm8wGxSO8xqZQKHCz9
FQ4WYENtsKNI9JrB0KCBQAJgQNDJqkK1BWKWx8afdG6v4ZRvv2POfbZGAz/Q
c9bB12CH3O/608TVVkTpAEUYUzZh7DCQZPfaRhYwiW6JjpBnxTlxzwuHXzAi
oBvBb4b9QPcgRsG3BD8SHIE0ZyVORkmD2mBBKADfpXeAS8tSx4MuICIEwYyB
mPQDi7XzXHTtuTB53MqwX1kCSos8AYehIP52kyA+mi90t57aQ5bGEbRkHWaA
Y+T9NbJTTCzyoN6mif4tBL9wrG5eLd76hd9aE+Ou+oH+drcXYpOlAkX8G0A+
uAtoCmunitxHFChKnkw9lw5h+EXLF5tHiwUpjbKY61ugxyDOCiAQH6DwaABo
UdWLv6a9v4ZrnuVmwAiAE0X5EswjRlJgMiLgYescOW2mYG+Ae2ImJiyZgd6H
P5lM7FmEdPoDCxGxxzW7H/PQA2XnFk7M8lKlaKSAbWLwsVGc3JLIH4DSklgG
KLQrAZPzE4s4Xi7AW1cgJDHyWpGLUi5oAYaPfpAVXzHa/lekrkfjPtH//wVi
GRK6A6cSIDqLzSCLFlWxGIx4qAxk2u09ffT0yeO9Xd1lGnFQPth9NBg90qNv
D3Z39dXlUc/PdLPlpLsg2S8MyKk2GGMBZjrbho5g6LmJEg7EMHmQLBf/Fgzf
Dt1oK3SjJnR6HbqXpvqN0LdzL6omxQS0kH3/OUzdj4qVHiPK/+nLznUf4BfF
EsX7uiiSzrZxiNOLWURxz3ylIdDDADEvbu8/KjgQRTZYzIBcclS9HTy9Gbyz
HHe8jSAC30MFJwp9x0WBku4Bj0vkaMCxPHtnJ3lcJCQijaDR4M8gsZGl9BW4
UvgPhEsU0RdziOEs6rCJgcWMmhg8+CID0UqcdxEIJqi6VVZECatsNx0j+yi7
LkALzeZoXFFLRBmscJNGtd//9ujs1Zvzk4uLU4CDY98FZbcwsWUhqvv4MVhx
4J7d3fXEmasfiiF846aDt7pppvP2Nm6u/eYMLucjNp8pwoQznAcU9PjlS0EG
eSHeF+dFh/qNN4bq1dXFpQSPaJzYkvCWgto3V4cvTy9eeKvV9aZ0QAFvhH4Z
mKrbHoYhF1eHF0fnp4cnb8/+XXV9GmJtLKDrwj+0msCIZwaOTAmbBiBMd/w7
xlMD/whymNBgnE+nBGoNusWMH2WF8PcaDD5vBbaAbbIsgay3zGtW27SiwmcY
p5NXEWkwdEvTWh4CQ+DpvKjgtwWGuLS/CgbQ/q/PLsHkVGa+qMi34YM1AQLW
5zBJLfM6m0MmuXKe4loYHHCGrjmDILVhVA1ewif9ezrAJ1BdbiDrm3MzNSV6
mqRLPh38Fj9a/nWf5t84Tu/K/NdoKf3nUysNhiNH8uSH/zh9E47k9Aimq0H4
ceCePDgsiypL2wMxmU0DVSvEZCwLCXiXLpNr1CPMvhr/0T1WsrYM2OsNIbj1
LM6hl6eqwy9toEyKriU4GlWTV4CkuygLxTytIATQ6IWUJhOXxmlK8LqWlNZh
IjoRte5nISuzBebUtaS0JT0KI1eZweRIkLLHVFCUgOFHOXNZa7CEEm+IM+jz
3EP1nAJDCiTtDLH13qwsTcWzgufDKtmI5h6Sd/OzBc3zEewE+venSQcMw3cz
82HgFDlF7c/Imelg0QkG7PIfFr6OHo8ePX7y5MkufuhnTISbEh59JNvTAWhK
WRa/BrmFZ+IhdZLUggVYoZPF2y/BQxyAXCeYUaUQqh4LsQev5jKcwXow5I6A
EOzWUAjkHcweP4DNwNrJgpMiWdF6Xq/CkGApTDrC8z9txooeDoc/MTpmCPBn
EFgaMnX23kHmwwJYzHpEAzx4kDt152KEmsM4F9BIskXWcdsB8ijEueAOvQTn
LtPMIEoRpXX3/OTHq9Pzk+OeS2t9Jg9EmtztHATA2mdT2/mh+7NDwIBIlxYg
WIS6xnKAowcM2VhwcLUYWgOdum4O2uoBZ+xZN9Aj8D2Rpj0Jy/EnQhvaAQ0B
NnCKTZHR8IzTJcmr21wqzikGVwos8DrO2pEgOFQgomiUTNLnqDMD/SOhHli8
GBGGE67y9IM2C4gmhhAUVZgPIdXj9BWIOoRqEPpRxAb7s2htgAEAvMaIGfXU
NAQGF0Y/h2cOsD5ICVenfdaX8lUg53hdiKNEEwZeo9EyKButNcYagK8QjDX2
tg64dD7HgnYFahRz+uD6oR+g3d5dCLPFX/F8ReR3Gf5WKQlm1jl/TDkEif7G
ImMINcFMr0BcyghLkmmeIDORQdDvc8zuADxYFrO2KK0/PO03cPvR0Z246+7Z
m0vw8cYvPQrXDu7OXRZFVbP1jNQ+BDWUiiY/gNYEl845JzOTN4WOEkmoRFYi
f1ja9/Mu6V/WBlMIvfV//+d/aZAQNCA8RqorYP5gohhN8ZBCH6uxHUZTGakP
V5DzlAI8OI32pXjA1HhalE00hGdEkUwo11ZiidBQwqaJEZRgmLCnuzgSXVWY
tK+7PLznyOaiFhw04GdEOtGvLYhP8FdWLHW+qC25a3J7OoWtQe0M/mLKog+S
iskzr/ZmadLUDdG0MqJHcZMhTB6L8wm42W0ypPEQEdBVC2DgZgmSUDjBolEK
hrUZHIItw6aMPYcJ1zn64cuc2b6ehz7DELAhfxM34RldBoSCkuimSDGcQ/zQ
IImnyEVxAdQO0IEU1imoHQiZQiXEVkwUmhzDWxvbxJl0Fij2JNb0DcgQKu81
W0U1ozKwUzporWAjAQw0vB5i3gYj/u8xezMMMzp4jsA5Wdu65ahk0QSkBHcv
6WAkbbz11Skuhb7LBp0bgC6aYq2QO2SqgatIHSU4RoocskGQbeZU3yyNZ40M
pdZhjlIo5Do7vANLoW1b1zO1nNFwXAdatE0rsRr9OoxR6NGi0yqTEZ2Fpewl
jIa4qcwPNroBY/STT1jYuQjnpMMV95ouNNsIJO1GJyH0/IhE9JWcvSB/qtcc
mEb0ES4CCETXcQM5HVzehGIev+F5sgYg7Xp1+XzwBKHmIwaiHOIVJ8OGz9k5
aZzQUgDExwxLpw4KRKBVjtEJinlUvk9A6oG/9ZFoLG5bofxp7rWCrMHkEZ3G
rE3Q0fnB2wlQmU4xSOJ6B52or1CPswyh8kdjMSsyXCIgJ+3p7ZGjKLOoi7Eu
EQiKc20Y8ZJgYhx5bDCuXhDVt37WY+B2MLzl04iKc46KP+kLViMUYWHfSeYp
Br4o4aenG1EyIYkC6YDx7oPWh81oxSSkF4vr5XHdqtLMfZnJpo9mzgus+LdH
k8JwNPrEwk4kN/mS8mu1jwzMvJEHmf9UwH+SqJjSPti+iP441W8c4BxCn7C+
dWRWatwQSp9I7ErmKEiL9A62RbDRaLIX7ycPzaPpt9HjyZP4abJrRtO9aH/y
MH6UfGseT59ETye78SjZM/vTh9Gjybfx4+SJeTrdxbmNcHf068LdLTZlc8xL
KWd9MQdjtR7pvojszNXc/oYIt5nl7+vSp/Ip8RWk81uR76/FoqNA5ycXuu64
Xp8z1+sD5qblXRNXvJFWHy/9LyGqkCqtj81YVyI/d1xrUEdCOwxCfBMI+p4Q
VCgXG2ELWEm9b2HI0Yi9NHaiFhNsL+G+lSCQaNQAYc3aWLfilATczBjd+yhe
gWcYY/VsMdNdiFZ6Ybjy2RYlLkIJ6oJYhydhnK+5aAGGtuI6AX7GIz3AzzM9
3uNv8td+qzLlPn/e+FU/gOGHxaS5OH5wscMR/+N2eLZl7eZGdBzQl+trBh9c
92jEnHMqkVBdD/8Gz4dkygvfGaa707S0tfKoe+v6mtwyyYbaOoaRFO8M7F0P
i52Ho6Ff7bf6T+PRT7oLh9c2uvU4bmxCs8Z7jVmHOItlGucx8ihu4z2ao8d7
G/bguKOxyVETtEOcRlgMNtkwbbzfmtaHlRrwTUAv43zS0UIXqd7W57RSFvGi
GxRyLyllKnvU3Xkw2dWy20E7EfDU1671IQ2vJ4+RdhgG+mXxOSZ5WKqwiFty
Qxv1sQFmKXbNYSZv5ZMLsPkh4sHXqSjpD1wjIGE3IlmxWbqg2BkwGC/LEvUD
dgphUz0WLpyJ5EpVlK/4MLoLqhcMIW6IKRxX3meS1e4VbEAOdd0z4xCJs8qI
8mKssjijweg+Frvs0K7UUTPIxNwaaadaPUCElhjuPvRQK9puqP+AOGoRo06K
Y+P2KphMI1Q3wIjnhrVod4q6bIJhCLZRODQot8kQTbtNydhnsHZUurYgX90A
phgNMV+JPZOCUouOd9Ak5bQ6IWiPnesN4JEDtoHAALblXv8GsYZqn5fiWCyW
hgt6ZnkKjuc0RjczH9K4IG2exrhUwUEYaKMZNfiAOZlS/oLxiMYo1gEiaq/2
BN067jklL60utoZpC0IdO94x+MrkC/r8SFATTCsvL8j+LthTk1UYUkY6N7cu
jBPQLbrRdWsTceE7l9x5J1aVqiNFbVRduCr5xyzIC6Fnh1B2yZHc68EJBG4H
q88chbHcui87JOXyTgY4SMLgEw9DAVKYC82UzMdGahdwuoRgLSlUmjRs5v+V
HiKMymUkKmsygCizRd2zXdV9cLgClpxda9g7RP47RSBura6wXzQcDhtO5t6a
k/n0/5mT6RxM3aWOK3SMehucTXYcET0/rZVM/ma33vuhO07emD/3kT+dONUM
+vlwaahfF6rNnCnq+1+WYKeApyAidsVmjow587adP/iAbf7Yb/MHs8f/LX94
otU8/Y8l2hvfNqDPl3jZAu3FWZ6tmmrIFUooXYaDGSE9SpWI8sTztfXnEEJk
ur3juhgkS9rUt6TwpSODeAE9/Sl5lpXshGntfJtqBKP1aplVKRpCTnWLTiUd
7OPeku4uADEoQ39JXgFD4nuCxUFrW/MuzMPBGyoXEOZE7411nhG4wgDQPpbJ
HS4oQ+1sTHvwQas8gLuwmCTNLEJprqMyybC8jhESyQ+dFbZ7GKJZfAefIcpd
WqiQen1t3MC6ktnGBilcC9ES0AtIWyAVIDjiDoyi1ucwTTobYf9HQ77RQIEa
NUkaZ4QFCY66WfresKNHfafaBw3OeLqe1RQvzgGaXMyZYieBeMd8xeTS118+
7vhazJ27yiOpLytlGrzbhFdSSivplVvYni1mys0fyl3OWRKnR2ieAvfn3lqQ
ateCgkoQN0bTc0o0YdOkuiwaNSdfceoj57dbpmt6gWZLyfW9xo5R/a7VP/yu
5W7od66mJnpUbXM3ttbRyGupq2GtkWLNJWRs79Y4ujjda742Yb32MT3oJLnB
ihg2OJaG53PMYjmsCcnaB6kBVrV81aUBapdHdDImvGZrIs6lOIRTGmc6IVVT
u5rY9N7i+9p5pqyx3qOH+7024bnzii8xbDx+syoA31fO3Rtyi7M0hrsIAqgs
TgF6/HGxMF52A70rvCBovEnNbXCZ5JwvEfrrJHypsL5QwtilMT4mRcXt7hbO
DcZlqZ1zdSC4oYf7ZhCu5FJUkawLdyjHGHw28zVbLmsS9m/w4rVcrkXcBi0x
1Yr7+0D6qQaYKAHXNfo1rpv6LjJBiowNro8UerJMs4QJZKqgUby+igJ0saDA
skQKNswwNSrDSywhNFbuBblQ1sWgrZs2X3NHhZf/ylsq99w4C2/zNG8MYQ14
09WKL+rs9mB+/X0TQesXXDtBVmHOcBe6gTOIOThZ5iDGMf+AOyPujF/Yv37/
rZEGjJ02MqQdmTuNBR11YBo1mC5M+FJJwPUhKhZoLhHWCIsmaJpJEcklCNGO
/iaKihyaG/Xh4NKvT5+8dRd5ioncS/Xtm7gERJlvxofYHViu2sVw7kSSgW/T
RAWr1E2grc0biwQX0XrtuEEW/Yyz3wmPscnXR09flgldfXr0c4Ggvo2qOjgN
g48qqpbs6ZMyDP11ofIVV3a+ToNRFkvUs/pCzbtByatQ/7EH8mdhxz8/a1zK
E004CZqAgcqUNna1Uafv6oqxonwaZ1SErxBdtoaqT1mZwD9iACXHIAk570iB
obnBy9XNObleLhJquG5MZgeECYAUXJAX1NFS0mGpoZQb5i+BFwAdEIwQ5sh0
uvuKx94M0j1Mai/1pvHO3zYNzKUY8MZN9paddLfaFZGLLV9mWvdQKfKghng8
nSChi+kCzMmUvcCA1sivInx1BGsI9ytK/iZTqVqMhi5vyGIuOEc5sq4fXHrY
3NU+MZWYekPiNu96UndLYCvXcSVM9ncwkgLPWzxsYCrX72x+9RXKcNmGoq/t
V+PAW61YQDsWK+6FpH4ufsODrTljnbifsXgO0r+30Wubuvsx0jJxbnCUgK85
4MMPRp3NiGtZvLP6asc6J1tn8mq+IWPiJADdfc+itYS5liBgjnaF3I3GrA2d
+aNqn5hsgLft7rGzGztrT6pikcb46Ad+Qoy/pAJ9MEgSh0TwmO823fXvgwAL
CSZPNkCw9sRDcMhP9Jpr9utAsAZ4t8LrPUijDZBsG+C3Ip9TLtTdwf+DQvg4
DAU+7oSRgU8L1IFK3gwdxEeQ1n73uhJJdKm1KEMsRPvNH0PPmXODr8LC+ohC
awG6EwMxvOzZDlpuUpvKV8woYMknbi6iUE2i80LXOilz8pvWIi5tYj7wXs7g
UvOOvIlL2kMaaAq0bOP3f1RMEgL9qyMTvDDzmWikfc4vDBEaOG3Gji21GY5c
v2fuOgm/HtCLKqq4HYu+Efd/YScWDVWfBvUn/P6ZD7Y3FTlWEXnHK/LirXMK
6WUrXh22dtTRbbSSv/zENMn47R+VWWBarR4TTExgWTfxuKDMGei6allOSBYw
i0YXiuBB0BpFU4vpVKCt9yQHAVgIKyFb0LOG8M/ESy010Qyb2ragdtwZlZ3A
nX8rHi4+Pc1BtCm1iRfrqjTT+wuJKrLIVm/F7ZfYQOoSHBsgWt01d7zP4tTf
c/cKi4H+5hve8ZtvDvCiuYvRmuqO2AwDOvRb6zkOSpq7kMazVlOu6D7uoMSp
Acw4r3XXP+z57iEwOFxCbWYvAIgXCg+HK100OsVxnosuwWOPYnFpqHs3db07
fPODLplRb3vtm7cIf0X+v+Uy1VrKFaOPpjaQ+ADWxFocqQvCouJXUVnX+kwQ
SmxAUtDXbgRjjhpnrgvYWni4JwmuoIbcKOX6hg3aD45yLFGb5FAF7jVmXQ9p
VEe27DBywB7FRjoUvOxQ2xXeX3AZt/qR9YYmLH7nXhjdAesrnVZhyT7mrAHd
iABE06VikiSJnYgDKLO6WvBr86RiYTG5T78NfBXDYu6Rx9W/8VXpxczMyWNq
MrvcDqY0aMJZijDAXXnLRmnXxtza1nEgoyzGhKiZm/aAgVy3BDv1oVqapqE5
UvuWV+jwyzKDC3DsOuVApFbB0ukFf4utjRPSBsIj2GzDr4eTS9342kt85WAE
PDAH5l3mJTxHAadOC2xWKm7r1034hVCykQG4rPVIu9scjjF8ZI1zsITEbT64
MFnBAckHJoThe92Qh3cbhGkoCV80hHVrpqNb36h+PX51cvFmfHTSc/mPkJCq
EaK6Vwqu+XVMBDmBK0ZmmWp5ZL4tsb6DSqwj/feYrpe0QuiHkU3DcJdbRnx0
UvuH/mCcZKlf8BICSnkGUI1LemfIEVhEdLPkMoq6PDs+o7f2jV+P1x7u7Gy4
S9+8id9+7xrW3Q32kdGCpblO8eV0rHrJsKjP3s537ziStzTWm6XGdpQsudLd
dKoN3T2hFhssz7TfiIa5Ov/KAIoV1cH6iYIx2OJOtwhaZ+Red/f09/i2iAr1
qqcV/nyx+a0CeuNbBdBvlyqn0uw7csjRfLuAUv4COd9uCHDd3/r+hJpyjXco
+LvpVp8LFtvkqxHqrFrnvnUCcmx4Txa/pSCjpGxKXbKb7sk378iLq7d+T379
msCWe/LtO/J6yy351g15rbdckm9dkGe38DVgRo7lWk30RePey7k0oFAzgH9X
4d63zJX4ykwMo9X/ALP2XeudWQAA

-->

</rfc>
