<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<rfc ipr="trust200902" category="std" docName="draft-ietf-calext-jscalendar-icalendar-04">
    <?rfc toc="yes"?>
    <?rfc symrefs="yes"?>
    <?rfc sortrefs="yes"?>
    <?rfc compact="no"?>
    <?rfc subcompact="no"?>
    <?rfc private=""?>
    <?rfc topblock="yes"?>
    <?rfc comments="no"?>

    <front>
        <title abbrev="JSCalendar">JSCalendar: Converting from and to iCalendar</title>
        <author initials="N.M." surname="Jenkins" fullname="Neil Jenkins">
            <organization>FastMail</organization>
            <address>
                <postal>
                    <street>PO Box 234</street>
                    <street>Collins St West</street>
                    <city>Melbourne</city>
                    <code>VIC 8007</code>
                    <country>Australia</country>
                    <region/>
                </postal>
                <phone/>
                <email>neilj@fastmailteam.com</email>
                <uri>https://www.fastmail.com</uri>
            </address>
        </author>
        <author initials="R." surname="Stepanek" fullname="Robert Stepanek">
            <organization>FastMail</organization>
            <address>
                <postal>
                    <street>PO Box 234</street>
                    <street>Collins St West</street>
                    <city>Melbourne</city>
                    <code>VIC 8007</code>
                    <country>Australia</country>
                    <region/>
                </postal>
                <email>rsto@fastmailteam.com</email>
                <uri>https://www.fastmail.com</uri>
            </address>
        </author>
        <author initials="M." surname="Douglass" fullname="Michael Douglass">
            <organization abbrev="BCS">Bedework Commercial Services</organization>
            <address>
                <postal>
                    <street>226 3rd Street</street>
                    <city>Troy</city>
                    <region>NY</region>
                    <code>12180</code>
                    <country>United States of America</country>
                </postal>
                <email>mdouglass@bedework.com</email>
                <uri>http://bedework.com</uri>
            </address>
        </author>
        <date year="2021" month="February" day="21"/>
        <area>Applications</area>
        <workgroup>Calendaring extensions</workgroup>
        <keyword>JSON</keyword>
        <keyword>iCalendar</keyword>
        <keyword>calendar</keyword>
        <keyword>events</keyword>
        <keyword>date</keyword>
        <keyword>time</keyword>
        <abstract>
            <t>
                This document provides the required methods for converting
                JSCalendar from and to iCalendar.
            </t>
        </abstract>
    </front>

    <middle>
        <section anchor="introduction" title="Introduction">

            <section anchor="introductory-note" title="Note (to be deleted later)">
                <t>
                    This is still very much a work in progress. There
                    are implementations of the mapping but there may
                    be changes over the coming weeks.
                </t>
            </section>

            <section anchor="motivation" title="Motivation">
                <t>
                    The JSCalendar <xref target="draft-ietf-calext-jscalendar"/> data format
                    is used to represent calendar data, and is meant as an alternative to
                    the widely deployed iCalendar <xref target="RFC5545"/> data format.
                </t>
                <t>
                    While new calendaring services and applications might use JSCalendar
                    as their main data format to exchange calendaring data, they are
                    likely to interoperate with services and clients that just support iCalendar.
                    Similarly, existing calendaring data is stored in iCalendar format
                    in databases and other calendar stores, and providers and users might
                    want to represent this data also in JSCalendar. Lastly, there is a
                    requirement to preserve custom iCalendar properties that have no
                    equivalent in JSCalendar when converting between these formats.
                </t>
                <t>
                    To support these use cases, this document provides the
                    required approach when converting JSCalendar data from and to
                    iCalendar.
                </t>
            </section>

            <section anchor="scope" title="Scope and caveats">
                <t>
                    JSCalendar and iCalendar have a lot of semantics in common, but
                    they are not interchangeable formats:
                    <list style="symbols">
                        <t>
                            JSCalendar contains a richer data model to express calendar
                            information such as event locations and participants.
                            while future iCalendar extensions
                            may allow a direct mapping, for now there may be no representation
                            directly in iCalendar of some properties. These values
                            may have to be extracted from a full copy of the iCalendar
                            format provided as a property in the JSCalendar data.
                        </t>
                        <t>
                            iCalendar may contain arbitrary, non-standardised data with custom
                            properties/attributes. These will be translated using the same approach
                            as jCal.
                        </t>
                        <t>
                            iCalendar has some obsolete features that have been removed from JSCalendar
                            due to not being useful and/or supported in the real world (e.g. custom
                            email alerts to send to random people). Translating these may lose some
                            of the original fidelity.
                        </t>
                        <t>
                            Implementations may use a custom property to store data that could not
                            be mapped directly in either direction in the original or a custom format,
                            however this is not interoperable.
                        </t>
                    </list>
                    Accordingly, this document defines a canonical translation
                    between iCalendar and JSCalendar, and implementations MUST follow
                    the approaches specified here when iCalendar data is represented in JSCalendar
                    and vice-versa.
                </t>

                <t>
                    This document defines mappings for the following specifications.
                    <list style="symbols">
                        <t>
                            <xref format="title" target="RFC5545"/>
                        </t>
                        <t>
                            <xref format="title" target="RFC5546"/>
                        </t>
                        <t>
                            <xref format="title" target="RFC7986"/>
                        </t>
                        <t>
                            <xref format="title" target="draft-ietf-calext-eventpub-extensions"/>
                        </t>
                        <t>
                           <xref format="title" target="draft-ietf-calext-ical-relations"/>
                        </t>
                        <t>
                            <xref format="title" target="draft-ietf-calext-valarm-extensions"/>
                        </t>
                    </list>
                    Therefore
                    all of these specifications MUST be implemented to follow this
                    specification.
                </t>
            </section>

            <section anchor="notational-conventions" title="Notational Conventions">
                <t>
                    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT",
                    "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in
                    <xref target="RFC2119"/>.
                </t>
            </section>

        </section>

        <section anchor="new-icalendar-parameters"
                 title="New iCalendar parameters">
            <section anchor="fractional-parameter" title="FRACTIONAL parameter">
                <t>
                    <list style='hanging'>
                        <t hangText="Parameter name:">
                            FRACTIONAL
                        </t>
                        <t hangText="Purpose:">
                            This parameter is used to contain a value with fractional seconds for
                            time values and durations.
                            FRACTIONAL MUST NOT be used in date-time calculations or comparisons in 
                            iCalendar.
                            It is meant to preserve time precision on time
                            values and duration with sub-second precision, without
                            increasing the time value range within iCalendar.
                        </t>
                        <t hangText="Description:">
                            This parameter MAY be specified on properties of type DATE-TIME
                            or DURATION.
                            It MUST be a valid iCalendar DATE-TIME or DURATION value with
                            the addition of
                            fractional seconds. The value MUST NOT be negative
                            for durations but MAY be negative for alarm triggers.
                            iCalendar implementations SHOULD ignore this parameter in date
                            time arithmetic.
                            Implementations MUST ignore presence of the FRACTIONAL parameter
                            on RECURRENCE-ID properties when determining recurrence overrides.
                        </t>
                        <t>
                            Applications receiving a property with a FRACTIONAL parameter
                            MUST ensure its value is consistent with the value of the
                            property. The property value must match:
                            <vspace/>
                            - a positive FRACTIONAL value rounded up to the next non-fractional second
                            or
                            <vspace/>
                            - a negative FRACTIONAL value rounded down the next non-fractional second
                        </t>
                        <t>
                            If the values do not match the the application
                            MUST assume that the property value has been
                            updated by an application that is unaware
                            of the FRACTIONAL parameter. The parameter should be
                            ignored in this case.
                        </t>
                        <t hangText="Format Definition:">
                            <figure>
                                <preamble>
                                    This parameter is defined by the following notation:
                                </preamble>

                                <artwork type="abnf">
    fractional-param = DATE-TIME or DURATION
                                </artwork>
                            </figure>
                        </t>
                        <t hangText="Example:">
                            <figure>
                                <artwork><![CDATA[
    DTSTART;FRACTIONAL=20190605T133015.03:20190605T133015
]]></artwork>
                            </figure>
                        </t>
                    </list>
                </t>
            </section>
        </section>

        <section anchor="icalendar-preprocessing"
                 title="iCalendar pre-processing">
            <t>
                iCalendar uses a line-folding mechanism to limit lines of data to a
                maximum line length (typically 75 octets) to ensure the maximum
                likelihood of preserving data integrity as it is transported via
                various means (e.g., email) -- see Section 3.1 of <xref target="RFC5545"/>.
            </t>
            <t>
                iCalendar data uses an "escape" character sequence for text values
                and property parameter values.  See Sections 3.1 and 3.3 of <xref target="RFC5545"/>
                as well as [RFC6868].
            </t>
            <t>
                There is a subtle difference in the number representations between
                JSON and iCalendar.  While in iCalendar, a number may have leading
                zeros, as well as a leading plus sign; this is not the case in JSON.
                Numbers should be represented in whatever way needed for the
                underlying format.
            </t>
            <t>
                When converting from iCalendar to JSCalendar: First, iCalendar lines MUST
                be unfolded.  Afterwards, any iCalendar escaping MUST be unescaped.
                Finally, JSON escaping, as described in Section 7 of <xref target="RFC7159"/>, MUST
                be applied.  The reverse order applies when converting from JSCalendar to
                iCalendar, which is further described in Section ?.
            </t>
            <t>
                iCalendar uses a base64 encoding for binary data.  However, it does
                not restrict the encoding from being applied to non-binary value
                types.  So, the following rules are applied when processing a
                property with the "ENCODING" property parameter set to "BASE64":
                <list style="symbols">
                    <t>
                        If the property value type is "BINARY", the base64 encoding MUST
                        be preserved.
                    </t>
                    <t>
                        If the value type is not "BINARY", the "ENCODING" property
                        parameter MUST be removed, and the value MUST be base64 decoded.
                    </t>
                </list>
                When base64 encoding is used, it MUST conform to Section 4 of
                [RFC4648], which is the base64 method used in [RFC5545].
            </t>
            <t>
                One key difference in the formatting of values used in iCalendar and
                JSCalendar is that, in JSCalendar, the specification uses date/time values aligned
                with the extended format of [ISO.8601.2004], which is more commonly
                used in Internet applications that make use of the JSON format.  The
                sections of this document describing the various date and time
                formats contain more information on the use of the complete
                representation, reduced accuracy, or truncated representation.
            </t>
        </section>

        <section anchor="translate-icalendar-components"
                 title="Translating iCalendar components to JSCalendar">
            <t>
                This section is an alphabetic list of
                <xref target="RFC5545"/> components and
                how they are mapped to JSCalendar.
            </t>

            <t>
                At present VFREEBUSY and VJOURNAL are not mapped in
                jscalendar.
            </t>

            <section anchor="translate-ical-comp-valarm" title="VALARM">
                <t>
                    An <xref target="RFC5545"/> VALARM component is mapped
                    to a member of a JSCalendar "alerts" object with a
                    type of "Alert" and a small id.
                    <figure>
                        <artwork><![CDATA[
  BEGIN: VEVENT
  ...
  BEGIN: VALARM
  ...
  END: VALARM
  BEGIN: VALARM
  ...
  END: VALARM
  END: VEVENT

  maps to

  {
    "@type": "jsevent",
    ...
    "alerts": {
      "1": {
        "@type": "Alert",
        ...
      },
      "2": {
        "@type": "Alert",
        ...
      }
    }
  }
]]></artwork>
                    </figure>
                </t>

                <t>
                    The <xref target="RFC5545"/> VALARM has a number of
                    problems which are not carried over into JSCalendar.
                    Clients tend to choose how, and in some cases when
                    to notify the user.
                </t>

                <t>
                    For example, if the user has a smart-watch they may
                    get tapped on the wrist. The method of notification
                    may depend on which device is being used and the
                    context, for example a meeting or driving.
                </t>

                <t>
                    Also, many clients are taking into consideration the
                    travel time and notifying the user earlier if it
                    seems necessary.
                </t>

                <t>
                    Specifying that a client should send emails to all
                    attendees is both annoying and dangerous. Attendees
                    have their own preferences for how and when they
                    should be notified.
                </t>

                <t>
                    Accordingly, the specification only allows for "display"
                    and "email" actions and - other than specifying
                    when - does not allow much else. Clients and/or
                    servers will generally use the associated event or
                    task title as identification. User preferences
                    generally indicate what actions they prefer.
                </t>

                <t>
                    An <xref target="RFC5545"/> ACTION property
                    can take the defined values
                    "AUDIO" / "DISPLAY" / "EMAIL" whereas the
                    JSCalendar "action" property only supports
                    "display" and "email".
                </t>

                <t>
                    An "AUDIO" alarm SHOULD be mapped to a "display"
                    alert. Any attachment MUST be ignored.
                </t>

                <t>
                    The <xref target="RFC5545"/> example VALARMs will
                    be mapped as follows, assuming they are all in the
                    same event:
                    <figure>
                        <artwork><![CDATA[
  BEGIN:VEVENT
  ...
  BEGIN:VALARM
  TRIGGER;VALUE=DATE-TIME:19970317T133000Z
  REPEAT:4
  DURATION:PT15M
  ACTION:AUDIO
  ATTACH;FMTTYPE=audio/basic:ftp://example.com/pub/
  sounds/bell-01.aud
  END:VALARM
  BEGIN:VALARM
  TRIGGER:-PT30M
  REPEAT:2
  DURATION:PT15M
  ACTION:DISPLAY
  DESCRIPTION:Breakfast meeting with executive\n
   team at 8:30 AM EST.
  END:VALARM
  BEGIN:VALARM
  TRIGGER;RELATED=END:-P2D
  ACTION:EMAIL
  ATTENDEE:mailto:john_doe@example.com
  SUMMARY:*** REMINDER: SEND AGENDA FOR WEEKLY STAFF MEETING ***
  DESCRIPTION:A draft agenda needs to be sent out to the attendees
  to the weekly managers meeting (MGR-LIST). Attached is a
  pointer the document template for the agenda file.
  ATTACH;FMTTYPE=application/msword:http://example.com/
  templates/agenda.doc
  END:VALARM
  END:VEVENT

  maps to

  {
    "@type": "jsevent",
    ...
    "alerts": {
      "1": {
        "@type": "Alert",
        "action": "display",
        "trigger": {
          "@type": "AbsoluteTrigger",
          "when": "19970317T133000Z"
        }
      },
      "2": {
        "@type": "Alert",
        "action": "display",
        "trigger": {
          "@type": "OffsetTrigger",
          "offset": "-PT30M"
        }
      }
      "3": {
        "@type": "Alert",
        "action": "email",
        "trigger": {
          "@type": "OffsetTrigger",
          "offset": "-P2D",
          "relativeTo": "end"
        }
      }
    }
  }
]]></artwork>
                    </figure>
                </t>

                <t>
                    Note that the ATTACH, ATTENDEE, DESCRIPTION, DURATION, REPEAT and
                    SUMMARY properties have been dropped.
                </t>
            </section>

            <section anchor="translate-ical-comp-vcalendar" title="VCALENDAR">
                <t>
                    A <xref target="RFC5545"/> VCALENDAR component may be mapped
                    to a JSCalendar object with a type of "jsgroup".
                    <figure>
                        <artwork><![CDATA[
  BEGIN: VCALENDAR
  PRODID:-//ABC Corporation//NONSGML My Product//EN
  ...
  END: VCALENDAR

  maps to

  {
    "@type": "jsgroup",
    "prodid": "-//ABC Corporation//NONSGML My Product//EN",
    ...
  }
]]></artwork>
                    </figure>
                </t>
                <t>
                    Note that a single JSEvent or JSTask MAY be converted
                    without a surrounding JSGroup if the VCALENDAR
                    component only contains PRODID and CALSCALE properties.
                    In this case the prddid can go in the JSEvent or JSTask.
                    The CALSCALE property is dropped - there is no equivalence
                    in JSCalendar.
                </t>
            </section>

            <section anchor="translate-ical-comp-vevent" title="VEVENT">
                <t>
                    A <xref target="RFC5545"/> VEVENT component is mapped
                    to a JSCalendar object with a type of "jsevent".
                    <figure>
                        <artwork><![CDATA[
  BEGIN: VEVENT
  ...
  END: VEVENT

  maps to

  {
    "@type": "jsevent",
    ...
  }
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-ical-comp-vlocation"
                     title="VLOCATION">
                <t>
                    A <xref target="draft-ietf-calext-eventpub-extensions"/>
                    VLOCATION component is mapped
                    to a JSCalendar object with a type of "Location". Any
                    properties within the VLOCATION must be mapped as
                    described below.
                </t>
                <t>
                    <figure>
                        <artwork><![CDATA[
  BEGIN: VEVENT
  ...
  BEGIN: VLOCATION
  ...
  END: VLOCATION
  END: VEVENT

  maps to

  {
    "@type": "jsevent",
    ...
     "locations": {
       "1": {
         "@type": "Location",
         ...
       }
     }
  }
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-ical-comp-vtimezone"
                     title="VTIMEZONE, STANDARD, DAYLIGHT">
                <t>
                    A <xref target="RFC5545"/> VTIMEZONE component is mapped
                    to a member of a JSCalendar "timezones" object with a
                    type of "TimeZone" and an id which follows the
                    restrictions specified.
                </t>
                <t>
                    The STANDARD and DAYLIGHT components map to
                    JSCalendar TimeZoneRule objects as members of the
                </t>
                <t>
                    Note that
                    <list style="symbols">
                        <t> There is no current approach for defining
                            standalone sets of timezones.
                        </t>
                        <t>
                            Timezones defined in the IANA timezone database
                            SHOULD NOT be redefined in the object.
                            Only custom timezones will be defined.
                        </t>
                    </list>
                    <figure>
                        <artwork><![CDATA[
  BEGIN: VTIMEZONE
  TZID: Example/Somewhere
  ...
  END: VTIMEZONE
  BEGIN: VTIMEZONE
  TZID: Example/Somewhere-else
  ...
  END: VTIMEZONE
  BEGIN: VEVENT
  ...
  END: VEVENT

  maps to

  {
    "@type": "jsevent",
    ...
    "timezones": {
      "/Example/Somewhere: {
        "@type": "TimeZone",
        ...
      },
      "/Example/Somewhere-else": {
        "@type": "TimeZone",
        ...
      }
    }
  }
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-ical-comp-vtodo" title="VTODO">
                <t>
                    A <xref target="RFC5545"/> VTODO component is mapped
                    to a JSCalendar object with a type of "jstask".
                    <figure>
                        <artwork><![CDATA[
  BEGIN: VTODO
  ...
  END: VTODO

  maps to

  {
    "@type": "jstask",
    ...
  }
]]></artwork>
                    </figure>
                </t>
            </section>
        </section>

        <section anchor="translate-icalendar-properties"
                 title="Translating iCalendar properties to JSCalendar">
            <t>
                This section is an alphabetic list of
                <xref target="RFC5545"/> and <xref target="RFC7986"/> properties and
                how they are mapped to JSCalendar.
            </t>

            <section anchor="translate-ical-attach" title="ATTACH">
                <t>
                    A <xref target="RFC5545"/> ATTACH allows for two types
                    of attachment:
                    <list style="symbols">
                        <t>A uri value</t>
                        <t>A binary value</t>
                    </list>
                    Both map to a JSCalendar "link" object with a
                    "rel" of "enclosure"
                    and the "href" set to the value of the property.
                </t>

                <t>
                    If the FMTTYPE parameter is set then add a
                    JSCalendar "contentType" property to the link
                    object.
                </t>

                <t>
                    For a binary value use a base64 data uri.
                </t>

                <t>
                    For an example of a recurring event with ATTACH
                    see <xref target="example-recurring-attach"/>
                </t>
            </section>

            <section anchor="translate-ical-attendee" title="ATTENDEE">
                <t>
                    An <xref target="RFC5545"/> ATTENDEE maps to the
                    JSCalendar "participant" property with a
                    JSCalendar "role" of "attendee". The value for role
                    should always be set.
                </t>

                <t>
                    In the simplest case a JSCalendar "participant" property
                    will be created and added to the JSCalendar "participants"
                    property.
                </t>

                <t>
                    The value of the ATTENDEE property is used to add an
                    "imip" method to the
                    JSCalendar "sendTo" property.
                    The value of the entry will be the ATTENDEE property
                    value.
                </t>
                <t>
                    For example:
                    <figure>
                        <artwork><![CDATA[
  ...
  ATTENDEE:mailto:user01@example.org
  ...

  maps to

  {
  ...
      "participants": {
        "be450b70-9bf7-4f6e-8f65-971ede566ce3": {
          "@type": "Participant",
          "sendTo": {
            "imip": "user01@example.org"
          },
  ...
  }
]]></artwork>
                    </figure>
                </t>

                <t>
                    The attendee parameters are mapped to
                    JSCalendar "participant" properties as follows:
                    <list style="hanging">
                        <t hangText="CN:">
                            The value of the CN parameter is used to set the
                            JSCalendar "name" property.
                        </t>
                        <t hangText="CUTYPE:">
                            This maps on to the
                            JSCalendar "kind" property as follows:
                        </t>
                        <t>
                            <list style="hanging">
                                <t hangText="INDIVIDUAL">"individual"</t>
                                <t hangText="GROUP">"group"</t>
                                <t hangText="RESOURCE">"resource"</t>
                                <t hangText="ROOM">"location"</t>
                                <t hangText="UNKNOWN">No value</t>
                            </list>
                            Any other value should be converted to
                            lower case and assigned to the
                            JSCalendar "kind" property.
                        </t>
                        <t hangText="DELEGATED-FROM:">
                            Split the value at any commas and add each
                            resulting element to the
                            JSCalendar "delegatedFrom" property
                        </t>
                        <t hangText="DELEGATED-TO:">
                            Split the value at any commas and add each
                            resulting element to the
                            JSCalendar "delegatedFrom" property
                        </t>
                        <t hangText="DIR:">
                            If non-null look in the
                            participant "links" property
                            for a
                            JSCalendar "link" property
                            with an href with the same value as the
                            DIR parameter. You may need to search the
                            current override and the master.
                        </t>
                        <t>
                            If none is found create a new one with the
                            JSCalendar "href" property
                            set to the value of the DIR parameter and the
                            JSCalendar "rel" property
                            set to "alternate"
                        </t>
                        <t hangText="LANG:">
                            set the
                            JSCalendar "language" property
                            to the value of the LANG parameter.
                        </t>
                        <t hangText="MEMBER:">
                            If this is set there should be a corresponding
                            ATTENDEE object with a value equal to the value
                            of the member parameter. If not it is
                            appropriate to skip this parameter.
                        </t>
                        <t>
                            If there is a corresponding ATTENDEE then
                            there should be a corresponding
                            JSCalendar "participant" property. This
                            suggests that CUTYPE=GROUP ATTENDEE
                            properties should be processed ahead of the
                            others.
                        </t>
                        <t>
                            Locate the
                            JSCalendar "participant" property
                            for the group. This may be in the current
                            override or in the master. Add the id to the
                            current participants
                            JSCalendar "memberOf" property.
                        </t>
                        <t hangText="PARTSTAT:">
                            If the PARTSTAT parameter is set and is not
                            "NEEDS-ACTION" then set the
                            JSCalendar "participationStatus" property
                            to the lower-cased value of the PARTSTAT.
                        </t>
                        <t hangText="ROLE:">
                            This is mapped to the
                            JSCalendar "roles" property as follows:
                        </t>
                        <t>
                            <list style="hanging">
                                <t hangText="CHAIR">"attendee" and "chair"</t>
                                <t hangText="REQ-PARTICIPANT">"attendee"</t>
                                <t hangText="OPT-PARTICIPANT">"attendee" and "optional"</t>
                                <t hangText="NON-PARTICIPANT">"informational"</t>
                            </list>
                            Any other value should be converted to
                            lower case and added to the
                            JSCalendar "roles" property.
                        </t>
                        <t hangText="RSVP:">
                            If the value of the RSVP parameter is TRUE
                            set the
                            JSCalendar "expectReply" property
                            to "true" otherwise omit it.
                        </t>
                        <t hangText="SCHEDULE-AGENT:">
                            If the value is "CLIENT" (ignoring case)
                            set the
                            JSCalendar "scheduleAgent" property
                            to "client" otherwise omit it.
                        </t>
                        <t hangText="SCHEDULE-FORCE-SEND:">
                            Set the
                            JSCalendar "scheduleForceSend" property
                            to the lower-cased value of the
                            <xref target="RFC6638"/> SCHEDULE-FORCE-SEND parameter.
                        </t>
                        <t hangText="SCHEDULE-STATUS:">
                            Split the value at any commas and add each
                            resulting element to the
                            JSCalendar "scheduleStatus" property.
                        </t>
                        <t hangText="SENT-BY:">
                            The value of the SENT-BY parameter is used
                            to set the
                            JSCalendar "invitedBy" property.
                        </t>
                    </list>
                </t>
            </section>

            <section anchor="translate-ical-calscale" title="CALSCALE">
                <t>
                    A <xref target="RFC5545"/> CALSCALE has no equivalence
                    in JSCalendar. It is ignored.
                </t>
            </section>

            <section anchor="translate-ical-categories"
                     title="CATEGORIES">
                <t>
                    These map on to the JSCalendar "keywords" property
                    with each category being the key to an entry.
                    <figure>
                        <artwork><![CDATA[
  ...
  CATEGORIES:APPOINTMENT,EDUCATION
  CATEGORIES:MEETING
  ...

  maps to

  ...
  "keywords": {
       "APPOINTMENT": true,
       "EDUCATION": true,
       "MEETING": true
     },
  ...
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-ical-class" title="CLASS">
                <t>
                    Maps to the "privacy" property. The iCalendar property
                    value maps to the JSCalendar value as follows:
                    <list style="hanging">
                        <t hangText="CONFIDENTIAL">"secret"</t>
                        <t hangText="PRIVATE">"private"</t>
                        <t hangText="PUBLIC">"public"</t>
                        <t hangText="iana-token and x-name">verbatim copy</t>
                    </list>
                </t>
            </section>

            <section anchor="translate-ical-color" title="COLOR">
                <t>
                    Maps to the "color" property. Copy the verbatim value.
                </t>
            </section>

            <section anchor="translate-ical-comment" title="COMMENT">
                <t>
                    There is no direct mapping for this property which
                    may appear multiple times in  <xref target="RFC5545"/>.
                </t>

                <t>
                    For a scheduling reply it is presumably a message
                    by the participant so the value or values should
                    be used to set the
                    JSCalendar "participantComment" property.
                </t>
            </section>

            <section anchor="translate-ical-completed" title="COMPLETED">
                <t>
                    Set the JSCalendar "progress" property to "completed"
                    and the "progressUpdated" property to the reformatted
                    date/time.
                    <figure>
                        <artwork><![CDATA[
  ...
  COMPLETED: "20101010T101010Z"
  ...

  maps to

  ...
  "progressUpdated": "2010-10-10T10:10:10Z",
  "progress": "completed",
  ...
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-ical-concept" title="CONCEPT">
                <t>
                    This <xref target="draft-ietf-calext-ical-relations"/>
                    property may appear multiple times in components.
                </t>

                <t>
                    Each instance of the property is mapped on to a
                    member of the
                    JSCalendar "categories" property.
                    <figure>
                        <artwork><![CDATA[
  ...
  CONCEPT:http://example.com/event-types/arts/music
  CONCEPT:http://example.com/performance-types/arts/live
  ...

  maps to

  ...
  "categories": {
    "http://example.com/event-types/arts/music": true,
    "http://example.com/performance-types/arts/live": true
  }
  ...
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-ical-conference" title="CONFERENCE">
                <t>
                    Maps to a "VirtualLocation" object. The property value maps
                    to the "uri" property of the virtual location.
                </t>
                <t>
                    Mapping parameters:
                    <list style="hanging">
                        <t hangText="FEATURE:">
                            Maps to the "features" property of the virtual location.
                        </t>
                        <t hangText="LABEL:">
                            Maps to the "name" property of the virtual location.
                        </t>
                        <t hangText="LANGUAGE:">
                            No mapping.
                        </t>
                    </list>
                </t>
            </section>

            <section anchor="translate-ical-contact" title="CONTACT">
                <t>
                    The CONTACT property is mapped on to a participant
                    object with a "roles" property of
                    "contact" and an "order" property of 1 (one). This
                    defines the participant as a primary contact.
                </t>
                <t>
                    Mapping parameters:
                    <list style="hanging">
                        <t hangText="ALTREP">
                            Use the same process as for the ATTENDEE
                            DIR parameter: create a link property with
                            the "rel" property set to "alternate" and the
                            "href" property set to the value of the
                            ALTREP parameter. Then add the link
                            to the participants "links" property.
                        </t>
                        <t hangText="LANG">
                            Set the participants "language" property.
                        </t>
                    </list>
                </t>
                <t>
                    For an example see <xref target="example-simple-contact" />
                </t>
            </section>

            <section anchor="translate-ical-created" title="CREATED">
                <t>
                    The CREATED property is mapped on to a "created"
                    property with a json formatted form of the date.
                    Example:
                    <figure>
                        <artwork><![CDATA[
  BEGIN:VEVENT
  ...
  CREATED:19960329T133000Z
  ...
  END:VEVENT

  maps to

  {
    "@type": "jsevent",
    ...
    "created": "1996-03-29T13:30"00Z",
    ...
  }
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-ical-description" title="DESCRIPTION">
                <t>
                    Copy the value, preprocessed according to
                    <xref target="icalendar-preprocessing" /> into the
                    "description" property.
                </t>
                <t>
                    Mapping parameters:
                    <list style="hanging">
                        <t hangText="ALTREP">
                            No mapping.
                        </t>
                        <t hangText="LANG">
                            Use the "locale" property.
                        </t>
                    </list>
                </t>
                <t>
                    Example:
                    <figure>
                        <artwork><![CDATA[
  BEGIN:VEVENT
  ...
  DESCRIPTION:We are having a meeting all this week at 12 pm fo
   r one hour\, with an additional meeting on the first day 2 h
   ours long.\nPlease bring your own lunch for the 12 pm meetin
   gs.
  ...
  END:VEVENT

  maps to

  {
    "@type": "jsevent",
    ...
    "description": // Note: comments and string concatenation are not
            // allowed per the JSON specification and is used here
            // to avoid long lines.
        "We are having a meeting all this week at 12 pm for one " +
        "hour, with an additional meeting on the first day 2 " +
        "hours long.\nPlease bring your own lunch for the 12 pm " +
        "meetings.",
    ...
  }
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-ical-times"
                     title="DTEND, DTSTART, DUE, DURATION">
                <t>
                    If the DTSTART is a DATE only property then add
                    the JSCalendar showWithoutTime property with the value set
                    to "true". The
                    JSCalendar "start" property
                    is set with zero time values.
                </t>

                <t>
                    If the DTSTART has a TZID parameter then set the
                    JSCalendar "timeZone" property to the value of TZID.
                </t>

                <t>
                    If the DTSTART has a UTC value then set the
                    JSCalendar "timeZone" property to the value "Etc/UTC".
                    The JSCalendar "start" property is set
                    without any UTC indicator.
                </t>

                <t>
                    JSCalendar has no equivalent to DTEND. If the component
                    has a DTEND then calculate a value for
                    "DURATION" from that
                    property and DTSTART and proceed as below.
                </t>

                <t>
                    If the DTEND has a TZID parameter with a value that
                    differs from the DTSTART TZID parameter then a
                    "location" object should be created with a "relativeTo"
                    property set to "end" and a "timezone" property set
                    to the value of the "TZID" parameter.
                </t>

                <t>
                    Note that a task is not required to have a DTSTART
                    so the JSCalendar "timezone" property needs to be set
                    from the DUE property.
                </t>

                <t>
                    Convert a DURATION property to the JSCalendar duration.
                </t>

                <t>
                    Example - DTSTART and DTEND in same timezone:
                    <figure>
                        <artwork><![CDATA[
  BEGIN:VEVENT
  ...
  DTSTART;TZID=America/New_York:20170315T150000
  DTEND;TZID=America/New_York:20170315T160000

  ...
  END:VEVENT

  maps to

  {
    "@type": "jsevent",
    ...
    "start": "2017-03-15T15:00:00",
    "timeZone": "America/New_York",
    "duration": "PT1H"
    ...
  }
]]></artwork>
                    </figure>
                </t>
                <t>
                    Example - DTSTART and DTEND in different timezone:
                    <figure>
                        <artwork><![CDATA[
  BEGIN:VEVENT
  ...
  DTSTART;TZID=America/New_York:20170315T150000
  DTEND;TZID=America/LosAngeles:20170315T190000

  ...
  END:VEVENT

  maps to

  {
    "@type": "jsevent",
    ...
    "start": "2017-03-15T15:00:00",
    "timeZone": "America/New_York",
    "duration": "PT7H"
    ...
    "locations": {
       "1": {
              "@type": "location",
              "relatedTo": "end",
              "timeZone": "America/Los_Angeles"
            }
       }
  }
]]></artwork>
                    </figure>
                </t>
                <t>
                    Example - 3 day event:
                    <figure>
                        <artwork><![CDATA[
  BEGIN:VEVENT
  ...
  DTSTART;VALUE=DATE:20210315
  DTEND;VALUE=DATE:20210318

  ...
  END:VEVENT

  maps to

  {
    "@type": "jsevent",
    ...
    "start": "2017-03-15T00:00:00",
    "duration": "P3D",
    "showWithoutTime": true,
    ...
  }
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-ical-exdate"
                     title="EXDATE">
                <t>
                    Create a patch object with the recurrence id set
                    from the EXDATE value. Add a single JSCalendar
                    "excluded" property with the value set to true.
                    There MUST NOT be any other properties set - other
                    than "@type".
                </t>
            </section>

            <section anchor="translate-ical-exrule" title="EXRULE">
                <t>
                    Maps to the "excludedRecurrenceRules" property.
                    Also see <xref target="translate-ical-rrule"/>.
                </t>
            </section>

            <section anchor="translate-ical-dtstamp-lastmod"
                     title="DTSTAMP and LAST-MODIFIED">
                <t>
                    The mapping depends on whether or not the component is a
                    scheduling entity.
                <list style='hanging'>
                    <t hangText="Not a scheduling entity:">
                        The <xref target="RFC5545"/> DTSTAMP and LAST-MODIFIED
                        properties have essentially the same meaning. If both are
                        present use the value of the latest for the "updated"
                        property. Otherwise set from whichever is present.
                    </t>

                    <t hangText="Is a scheduling entity:">
                        DTSTAMP should be used to set the "ScheduleUpdated"
                        property in the "participant" object for the attendee.
                    </t>

                    <t>
                        If present LAST-MODIFIED should be used to set the
                        "updated" property - otherwise set it from the DTSTAMP.
                    </t>
                </list>
                </t>
            </section>

            <section anchor="translate-ical-geo" title="GEO">
                <t>
                    Maps to a Location object, with only the "coordinates"
                    property set. Note that the JSCalendar coordinates
                    property value MUST be a valid "geo" URI, so replace
                    the ";" character in the iCalendar value with "," and
                    prepend the resulting string with "geo:".
                </t>
            </section>

            <section anchor="translate-ical-image" title="IMAGE">
                <t>
                    Maps to a Link object with the iCalendar property
                    value mapped to the location "href" property, and
                    the "rel" property set to "icon".
                </t>
                <t>
                    For a binary value use a base64 data uri
                    in the "href" property.
                </t>
                <t>
                    Mapping parameters:
                    <list style="hanging">
                        <t hangText="ALTREP">
                            No mapping.
                        </t>
                        <t hangText="FMTTYPE">
                            Maps to the "contentType" property of the Link object.
                        </t>
                        <t hangText="DISPLAY">
                            Maps to the "display" property of the Link object.
                            The property values "BADGE", "GRAPHIC", "FULLSIZE"
                            and "THUMBNAIL" map to their lower-case equivalent
                            in JSCalendar.
                        </t>
                    </list>
                </t>
            </section>

            <section anchor="translate-ical-location"
                     title="LOCATION">
                <t>
                    If any <xref target="draft-ietf-calext-eventpub-extensions"/>
                    "VLOCATION" components are present, then the
                    <xref target="RFC5545"/>"LOCATION" property should
                    be ignored.
                </t>

                <t>
                    To map the property create a "locations" property
                    with a single "location" and set the "description"
                    property to the value of the
                    <xref target="RFC5545"/>"LOCATION" property.
                </t>

                <t>
                    Mapping parameters:
                    <list style="hanging">
                        <t hangText="ALTREP">
                            Maps to a Link object in the Location "links"
                            property, with the "href" property set to
                            the parameter value.
                        </t>
                    </list>
                </t>
            </section>

            <section anchor="translate-ical-method" title="METHOD">
                <t>
                    Maps to the "method" property of the JSCalendar object.
                    The JSCalendar property value is the lowercase equivalent
                    of the iCalendar property value.
                </t>
            </section>

            <section anchor="translate-ical-organizer" title="ORGANIZER">
                <t>
                    Maps to the "replyTo" property of the JSCalendar object.
                    An iCalendar property value in the "mailto:" URI scheme,
                    maps to the "imip" method, any other value maps to
                    the "other" method.
                </t>
                <t>
                    If the iCalendar component also contains an ATTENDEE
                    with the same calendar user address then map that
                    ATTENDEE as defined in <xref target="translate-ical-attendee"/>
                    and add the "owner" role to the Participant "roles" property.
                    Otherwise, use the ORGANIZER property to map to a Participant
                    object. The "roles" property of the Participant MUST only
                    contain the "owner" role and the "expectReply" property value
                    MUST be "false". Any iCalendar parameters map as defined
                    for ATTENDEE.
                </t>
                <t>
                    TBD: SENT-BY parameter. Example.
                </t>
            </section>

            <section anchor="translate-ical-percent-complete"
                     title="PERCENT-COMPLETE">
                <t>
                    For all methods other than REPLY (or no method), the
                    PERCENT-COMPLETE applies to the VTODO as a whole.
                    In this case it the value is used to set the
                    JSCalendar "percentComplete" property in the task
                    object.
                    <figure>
                        <artwork><![CDATA[
  BEGIN: VCALENDAR
  PRODID:-//ABC Corporation//NONSGML My Product//EN
  METHOD:PUBLISH
  BEGIN:VTODO
  ...
  PERCENT-COMPLETE:39
  END:VTODO
  END: VCALENDAR

  maps to

  {
    "@type": "jstask",
    "prodid": "-//ABC Corporation//NONSGML My Product//EN",
    ...
    "percentComplete": 39
  }
]]></artwork>
                    </figure>
                </t>
                <t>
                    PERCENT-COMPLETE in a REPLY is used to indicate the
                    level of completeness of the ATTENDEE. There should
                    only be a single ATTENDEE in the VTODO object.
                </t>
                <t>
                    As ever recurrences complicate matters. For a
                    non-recurring event or an override that contains
                    the single participant, set the
                    JSCalendar "percentComplete" property in the
                    JSCalendar "participant" object representing the
                    attendee.
                    <figure>
                        <artwork><![CDATA[
  BEGIN: VCALENDAR
  PRODID:-//ABC Corporation//NONSGML My Product//EN
  METHOD:REPLY
  BEGIN:VTODO
  ...
  ATTENDEE:mailto:douglm@example.org
  PERCENT-COMPLETE:39
  END:VTODO
  END: VCALENDAR

  maps to

  {
    "@type": "jstask",
    "prodid": "-//ABC Corporation//NONSGML My Product//EN",
    ...
    "participants": {
      "be450b70-9bf7-4f6e-8f65-971ede566ce3": {
        "@type": "Participant",
        "sendTo": {
          "imip": "mailto:douglm@example.org"
        },
        "percentComplete": 39,
        "roles": {
          "attendee": true
        }
      },
      ...
  }
]]></artwork>
                    </figure>
                </t>
                <t>
                    In the case of an override with the participant
                    appearing in the master then add a patch to the
                    override.
                    <figure>
                        <artwork><![CDATA[
  BEGIN: VCALENDAR
  PRODID:-//ABC Corporation//NONSGML My Product//EN
  METHOD:REPLY
  BEGIN:VTODO
  ...
  ATTENDEE:mailto:douglm@example.org
  END:VTODO
  BEGIN:VTODO
  ...
  RECURRENCE-ID:20200523T120000
  ...
  ATTENDEE:mailto:douglm@example.org
  PERCENT-COMPLETE:39
  END:VTODO
  END: VCALENDAR

  maps to

  {
    "@type": "jstask",
    "prodid": "-//ABC Corporation//NONSGML My Product//EN",
    ...
    "participants": {
      "be450b70-9bf7-4f6e-8f65-971ede566ce3": {
        "@type": "Participant",
        "sendTo": {
          "imip": "mailto:douglm@example.org"
        },
        "roles": {
          "attendee": true
        }
      },
      "recurrenceOverrides": {
        "2020-05-23T12:00:00": {
          "participants/be4...6ce3/percentComplete": 39
        },
      ...
    }
  }
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-ical-prority"
                     title="PRIORITY">
                <t>
                    Simply copy value into the JSCalendar "priority"
                    property.
                </t>
            </section>

            <section anchor="translate-ical-prodid" title="PRODID">
                <t>
                    For a vcalendar JSGroup object with multiple JSEvent
                    and/or JSTask object the <xref target="RFC5545"/> VCALENDAR PRODID is
                    mapped to a JSCalendar "prodid" property in the group.
                </t>
                <t>
                    When mapping to a single JSEvent and/or JSTask object
                    the <xref target="RFC5545"/> VCALENDAR PRODID is
                    mapped to a JSCalendar "prodid" property in the group
                    <figure>
                        <artwork><![CDATA[
  BEGIN: VCALENDAR
  PRODID:-//ABC Corporation//NONSGML My Product//EN
  BEGIN:VEVENT
  ...
  END:VEVENT
  END: VCALENDAR

  maps to

  {
    "@type": "jsevent",
    "prodid": "-//ABC Corporation//NONSGML My Product//EN",
    ...
  }
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-ical-recurrence-id"
                     title="RECURRENCE-ID">
                <t>
                    Refer to <xref target="translate-icalendar-recurrences" />
                    for information on mapping recurrence ids.
                </t>
            </section>

            <section anchor="translate-ical-related-to"
                     title="RELATED-TO">
                <t>
                    This is mapped to the JSCalendar "relatedTo" property
                    which is a map of relations with the target UID as the
                    keys. The iCalendar relation is by default a PARENT
                    relationship. There is no default for JSCalendar
                    so the relationship must be explicitly specified.
                </t>
                <t>
                    The RELTYPE parameter values map to their lowercase
                    equivalents in the "relation" property.
                </t>
                <t>
                    Also note that the iCalendar relationship types are
                    not identical. CHILD and PARENT map to JSCalendar
                    "child" and "parent" but the best match for iCalendar
                    SIBLING is "next"
                    <figure>
                        <artwork><![CDATA[
  ...
  RELATED-TO:jsmith.part7.19960817T083000.xyzMail@example.com
  RELATED-TO;RELTYPE=SIBLING:
   19960401-080045-4000F192713-0052@example.com
  ...

  maps to

  "relatedTo" : {
    "jsmith.part7.19960817T083000.xyzMail@example.com" : {
      "@type" : "Relation",
      "relation" : {
        "parent" : true
      }
    },
    "19960401-080045-4000F192713-0052@example.com" : {
      "@type" : "Relation",
      "relation" : {
        "next" : true
      }
    },
  },
  {
    "@type": "jsevent",
    "prodid": "-//ABC Corporation//NONSGML My Product//EN",
    ...
  }
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-ical-request-status"
                     title="REQUEST-STATUS">
                <t>
                    Copy the value into the JSCalendar "requestStatus" property.
                </t>
            </section>

            <section anchor="translate-ical-resources"
                     title="RESOURCES">
                <t>
                    The RESOURCES property value is a comma-separated
                    list of resources. First split this into the separate
                    resource names and then each resource is mapped on a
                    participant object with a "kind" property of
                    "resource" and the "name" property set to the
                    resource name.
                </t>
                <t>
                    Mapping parameters:
                    <list style="hanging">
                        <t hangText="ALTREP">
                            Use the same process as for the ATTENDEE
                            DIR parameter: create a link property with
                            the "rel" property set to "alternate" and the
                            "href" property set to the value of the
                            ALTREP parameter. Then add the link
                            to the participants "links" property.
                        </t>
                        <t hangText="LANG">
                            Set the participants "language" property.
                        </t>
                    </list>
                </t>
                <t>
                    For an example see <xref target="example-simple-resource" />
                </t>
            </section>

            <section anchor="translate-ical-rdate"
                     title="RDATE">
                <t>
                    If the RDATE has a RANGE=THISANDFUTURE parameter
                    then the recurrence MUST be split at this RDATE.
                </t>
                <t>
                    Truncate the original object before this RDATE,
                    create a new master representing the object and
                    link them by setting the
                    jscalendar "relatedTo" property in both.
                </t>
                <t>
                    Otherwise create a patch object with the recurrence id set
                    from the RDATE value. If the instance has overrides
                    the differences will also be set in the object.
                </t>
            </section>

            <section anchor="translate-ical-rrule"
                     title="RRULE">
                <t>
                    Each RRULE is converted to an object in the
                    JSCalendar "recurrenceRules" property. Each entry
                    has the type "RecurrenceRule".
                    <figure>
                        <artwork><![CDATA[
  ...
  RRULE:...
  ...

  maps to

  ...
  "recurrenceRules" : [{
      "@type" : "RecurrenceRule",
      ...
    }],
    ...
]]></artwork>
                    </figure>
                </t>
                <t>
                    The recurrence rule object has one property for each
                    element of the recurrence rule. The iCalendar rule has
                    to be parsed out and the individual jscalendar
                    property values set. Most take the same type but
                    there are exceptions.

                    <list style="hanging">
                        <t hangText="FREQ (mandatory)">
                            Copy into the jscalendar "frequency" property
                            converted to lowercase.
                        </t>
                        <t hangText="INTERVAL">
                            If present and not 1 copy into the
                            jscalendar "interval" property.
                        </t>
                        <t hangText="RSCALE">
                            If present copy into the jscalendar "rscale" property
                            converted to lowercase.
                        </t>
                        <t hangText="SKIP">
                            If present copy into the jscalendar "skip" property
                            converted to lowercase.
                        </t>
                        <t hangText="WKST">
                            If present copy into the jscalendar "firstDayOfWeek" property
                            converted to lowercase.
                        </t>
                        <t hangText="BYDAY">
                            If present each element becomes an entry in the
                            jsCalendar "byDay" propety. This is an array
                            of NDay objects which may have 2 properties:
                            <list style="hanging">
                                <t hangText="day">
                                    The two character weekday abbreviation.
                                </t>
                                <t hangText="nthOfPeriod">
                                    If the weekday abbreviation is preceded
                                    by a signed integer value set the
                                    jscalendar "nthOfPeriod" property.
                                </t>
                            </list>
                            <figure>
                                <artwork><![CDATA[
  ...
  RRULE:...,BYDAY=-1MO
  ...

  maps to

  ...
  "recurrenceRules" : [{
      "@type" : "RecurrenceRule",
      ...
      "byday": [{
          "day": "mo",
          "nthOfPeriod": -1
        }]
      ...
    }],
    ...
]]></artwork>
                            </figure>
                        </t>
                        <t hangText="BYMONTHDAY">
                            If present each element will be an element
                            in the jscalendar "byMonthDay" property.
                        </t>
                        <t hangText="BYMONTH">
                            If present each element will be an element
                            in the jscalendar "byMonth" property.
                        </t>
                        <t>
                            Note that the iCalendar values are numeric
                            but the JSCalendar values are strings. This is
                            because of the possible "L" suffix for leap months.
                        </t>
                        <t hangText="BYYEARDAY">
                            If present each element will be an element
                            in the jscalendar "byYearDay" property.
                        </t>
                        <t hangText="BYWEEKNO">
                            If present each element will be an element
                            in the jscalendar "byWeekNo" property.
                        </t>
                        <t hangText="BYHOUR">
                            If present each element will be an element
                            in the jscalendar "byHour" property.
                        </t>
                        <t hangText="BYMINUTE">
                            If present each element will be an element
                            in the jscalendar "byMinute" property.
                        </t>
                        <t hangText="BYSECOND">
                            If present each element will be an element
                            in the jscalendar "bySecond" property.
                        </t>
                        <t hangText="BYSETPOS">
                            If present each element will be an element
                            in the jscalendar "bySetPosition" property.
                        </t>
                        <t hangText="COUNT">
                            If present set
                            in the jscalendar "count" property.
                        </t>
                        <t hangText="UNTIL">
                            If present set the jscalendar "until" property
                            with the appropriately reformatted value.
                            If the is no time part append a 0 time and
                            reformat as a jscalendar local date/time.
                        </t>
                    </list>
                </t>
                <t>
                    Some examples:
                    <figure>
                        <artwork><![CDATA[
  ...
  RRULE:FREQ=DAILY;COUNT=10
  ...

  maps to

  ...
  "recurrenceRules" : [{
      "@type" : "RecurrenceRule",
      "frequency": "daily",
      "count": 10
    }],
    ...
]]></artwork>
                    </figure>
                    <figure>
                        <artwork><![CDATA[
  ...
  RRULE:FREQ=YEARLY;UNTIL=20220512T140000Z;
   BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA
  ...

  maps to

  ...
  "recurrenceRules" : [{
      "@type" : "RecurrenceRule",
      "frequency": "yearly",
      "byMonth": ["1"],
      "byDay": [{
            "day": "su"
          },
          }
            "day": "mo"
          },
          }
            "day": "tu"
          },
          }
            "day": "we"
          },
          }
            "day": "th"
          },
          }
            "day": "fr"
          },
          }
            "day": "sa"
          }],
      "until": "2022-05-12T10:00:00"
    }],
    ...
]]></artwork>
                    </figure>
                    <figure>
                        <artwork><![CDATA[
  ...
  RRULE:FREQ=MONTHLY;COUNT=6;BYDAY=-2MO
  ...

  maps to

  ...
  "recurrenceRules" : [{
      "@type" : "RecurrenceRule",
      "frequency": "monthly",
      "byDay": [{
          "day": "mo",
          "nthOfPeriod": -2
        }],
      "count": 6
    }],
    ...
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-ical-sequence"
                     title="SEQUENCE">
                <t>
                    Copy the value into the JSCalendar "sequence"
                    property.
                </t>
            </section>

            <section anchor="translate-ical-status"
                     title="STATUS">
                <t>
                    For a VEVENT copy the lower-cased value into the
                    JSCalendar "status" property.
                </t>
                <t>
                    For a VTODO copy the lower-cased value into the
                    JSCalendar "progress" property.
                </t>
            </section>

            <section anchor="translate-ical-structured-data"
                     title="STRUCTURED-DATA">
                <t>
                    This property is mapped on to a JSCalendar "link"
                    object with the value mapped on to the
                    JSCalendar "href" property in a manner depending on
                    the "STRUCTURED-DATA" "VALUE" parameter:
                    <list style="hanging">
                        <t hangText="VALUE=TEXT">
                            Copy the value as a <xref target="RFC2397"/>
                            data uri either as plain
                            text or by encoding as a base64 value. If plain text
                            the value may need escaping as per <xref target="RFC2397"/>.
                        </t>
                        <t hangText="VALUE=BINARY">
                            Copy the value as a <xref target="RFC2397"/>
                            data uri speifying base64 encoding.
                        </t>
                        <t hangText="VALUE=URI">
                            Copy the value as-is into the href.
                        </t>
                    </list>
                </t>
                <t>
                    The "STRUCTURED-DATA" "SCHEMA" parameter is mapped on
                    to a JSCalendar "schema" property within the link object.
                </t>
                <t>
                    The "STRUCTURED-DATA" "FMTTYPE" parameter is mapped on
                    to a JSCalendar "contentType" property within the link object.
                </t>
                <t>
                    For example:
                    <figure>
                        <artwork><![CDATA[
  ...
  STRUCTURED-DATA;FMTTYPE=application/ld+json;
      SCHEMA="https://schema.org/SportsEvent";
      VALUE=TEXT:{\n
        "@context": "http://schema.org"\,\n
        "@type": "SportsEvent"\,\n
        "homeTeam": "Pittsburgh Pirates"\,\n
        "awayTeam": "San Francisco Giants"\n
      }\n
  ...

  maps to (with data truncated)

  ...
  "links": {
    "1": {
      "@type" : "Link",
      "contentType": "application/ld+json",
      "schema": "https://schema.org/SportsEvent",
      "href": "data:base64;ewogICAgICAgICJAY29udGV4dCI6IC..."
    }
  }
  ...
]]></artwork>
                    </figure>

                </t>
            </section>

            <section anchor="translate-ical-summary"
                     title="SUMMARY">
                <t>
                    Copy the value into the
                    JSCalendar "title" property.
                </t>
                <t>
                    Mapping parameters:
                    <list style="hanging">
                        <t hangText="ALTREP">
                            No mapping.
                        </t>
                        <t hangText="LANG">
                            Use the "locale" property.
                        </t>
                    </list>
                </t>
            </section>

            <section anchor="translate-ical-transp"
                     title="TRANSP">
                <t>
                    If the value of the TRANSP property (ignoring case)
                    is "opaque" set the JSCalendar "freeBusyStatus" property
                    to the value "busy".
                </t>

                <t>
                    Otherwise set the JSCalendar "freeBusyStatus" property
                    to the value "free".
                </t>
            </section>

            <section anchor="translate-ical-uid"
                     title="UID">
                <t>
                    Copy the value into the
                    JSCalendar "uid" property.
                </t>
            </section>

            <section anchor="translate-url"
                     title="URL">
                <t>
                    Maps to a Link object in the JSCalendar object's "links"
                    property, with the URL property value mapped to the Link
                    "href" property.
                </t>
            </section>
        </section>

        <section anchor="translate-icalendar-recurrences"
                 title="Translating iCalendar Recurrences">
            <section anchor="translate-icalendar-recurrences-simple"
                     title="Translating iCalendar Recurrences: Simple objects with overrides">
                <t>
                    A simple object with overrides will be converted to a
                    jsCalendar master event with the rules, recurrence
                    dates and exclusion dates translated appropriately.
                </t>

                <t>
                    Overrides MUST be mapped on to a jsCalendar patch
                    object and added to the "recurrenceOverrides"
                    property of the master event with the key being
                    the value of the iCalendar RECURRENCE-ID translated
                    to a json format.
                </t>

                <t>
                    Any override property with the same value as the
                    master SHOULD be ommitted.
                    Remaining properties MAY be added in full. Where appropriate,
                    differences SHOULD be expressed as a patch.
                </t>

                <t>
                    This can result in a significant reduction in
                    size for objects with small changes to overrides,
                    for example changing the participation status of
                    an attendee.
                </t>
            </section>

            <section anchor="translate-icalendar-recurrences-nomaster"
                     title="Translating iCalendar Recurrences: Overrides with no master">
                <t>
                    When inviting an attendee to a single instance of a recurring
                    event, only that override should be sent to the attendee.
                    In this case the override should be a complete jsCalendar
                    object with the type set to the type of the master.
                </t>

                <t>
                    Additionally, there MUST be a recurrenceId property
                    set to the value of the recurrence id for that override.
                    If the timezone of the start of the instance is
                    different from the master value, then there must
                    also be a "recurrenceIdTimeZone" property set to
                    the start timezone of the master.
                </t>
            </section>
        </section>

        <section anchor="translate-icalendar-further-examples"
                 title="Translating iCalendar: Further examples">
            <t>
                This section provides more complete examples of translating
                from <xref target="RFC5545"/> to JSCalendar.
            </t>

            <t>
                As usual note that json string values may be split
                because of line width limits. This is not legal json.
            </t>

            <section anchor="example-recurring-attach"
                     title="Recurring event with ATTACH">
                <t>
                    This is an example of a recurring event with overrides.
                    The first override removes an ATTACH property and
                    adds an ATTACH property. The second override removes all
                    ATTACH properties.
                    <figure>
                        <artwork><![CDATA[
  BEGIN:VCALENDAR
  CALSCALE:GREGORIAN
  PRODID:-//example.org//EN
  VERSION:2.0
  BEGIN:VEVENT
  DTSTAMP:20200522T142047Z
  DTSTART;TZID=America/New_York:20200522T120000
  DURATION:PT1H
  RRULE:FREQ=DAILY;COUNT=8
  SUMMARY:recurring daily 8 times
  UID:6252D6C40A8308BFE25BBDErecur-1
  ATTACH;FMTTYPE=text/plain:http://example.org/doc1.txt
  ATTACH;FMTTYPE=text/plain:http://example.org/doc2.txt
  ATTACH;FMTTYPE=text/plain:http://example.org/doc3.txt
  END:VEVENT
  BEGIN:VEVENT
  DTSTAMP:20200522T142047Z
  DTSTART;TZID=America/New_York:20200523T120000
  DURATION:PT1H
  RECURRENCE-ID;TZID=America/New_York:20200523T120000
  SUMMARY:recurring daily 8 times
  UID:6252D6C40A8308BFE25BBDErecur-1
  ATTACH;FMTTYPE=text/plain:http://example.org/doc2.txt
  ATTACH;FMTTYPE=text/plain:http://example.org/doc3.txt
  ATTACH;FMTTYPE=text/plain:http://example.org/doc4.txt
  END:VEVENT
  BEGIN:VEVENT
  DTSTAMP:20200522T142047Z
  DTSTART;TZID=America/New_York:20200524T120000
  DURATION:PT1H
  RECURRENCE-ID;TZID=America/New_York:20200524T120000
  SUMMARY:recurring daily 8 times
  UID:6252D6C40A8308BFE25BBDErecur-1
  END:VEVENT
  END:VCALENDAR

  maps to

  {
    "prodId": "//example.org//EN",
    "entries": [
      {
        "links": {
          "1": {
            "@type": "Link",
            "rel": "enclosure",
            "contentType": "text/plain",
            "href": "http://example.org/doc1.txt"
          },
          "2": {
            "@type": "Link",
            "rel": "enclosure",
            "contentType": "text/plain",
            "href": "http://example.org/doc2.txt"
          },
          "3": {
            "@type": "Link",
            "rel": "enclosure",
            "contentType": "text/plain",
            "href": "http://example.org/doc3.txt"
          }
        },
        "created ": "2020-05-23T17:04:50Z",
        "start": "2020-05-22T12:00:00",
        "timeZone": "America/New_York",
        "duration": "PT1H",
        "title": "recurring daily 8 times",
        "uid": "6252D6C40A8308BFE25BBDErecur-1",
        "recurrenceRules": [
          {
            "@type": "RecurrenceRule",
            "frequency": "daily",
            "count": 8
          }
        ],
        "recurrenceOverrides": {
          "2020-05-23T12:00:00": {
            "recurrenceId": "2020-05-23T12:00:00",
            "links/d4a618d4-929c-4c81-ae5b-322afe407a00": null,
            "links/fb75b76a-a159-4a86-bd3d-7ace6b39c6c3": {
              "@type": "Link",
              "rel": "enclosure",
              "contentType": "text/plain",
              "href": "http://example.org/doc4.txt"
            }
          },
          "2020-05-24T12:00:00": {
            "recurrenceId": "2020-05-24T12:00:00",
            "links/d4a618d4-929c-4c81-ae5b-322afe407a00": null,
            "links/6c54e72e-3413-487c-ae14-fb318a90db43": null,
            "links/44087e9a-132c-4a5d-b25d-4ce580edb004": null
          }
        }
      }
    ]
  }
]]></artwork>
                    </figure>
                </t>
            </section>
            <section anchor="example-simple-contact"
                     title="Simple event with CONTACT">
                <t>
                    This example shows the conversion of a simple
                    event with a single CONTACT property in JSCalendar.
                    <figure>
                        <artwork><![CDATA[
    BEGIN:VCALENDAR
    CALSCALE:GREGORIAN
    PRODID:-//Example//EN
    VERSION:2.0
    BEGIN:VEVENT
    DTSTAMP:20200522T142047Z
    DTSTART;TZID=America/New_York:20200622T120000
    DURATION:PT1H
    SUMMARY:event with contact
    UID:6252D6C40A8308BFE25BBEFcontact-1
    CONTACT;ALTREP="ldap://example.com:6666/o=ABC%20Industries\,
     c=US???(cn=Jim%20Dolittle)":Jim Dolittle\, ABC Industries\,
     +1-919-555-1234
    END:VEVENT
    END:VCALENDAR

    translates to

    {
      "@type": "jsgroup",
      "prodId": "//Example.org//Example V3.13.2//EN",
      "entries": [
        {
          "@type": "jsevent",
          "participants": {
            "40288108-733187c1-0173-3188007b-00000001": {
              "@type": "Participant",
              "roles": {
                "contact": true
              },
              "description": "Jim Dolittle, ABC Industries,\
                             +1-919-555-1234",
              "links": {
                "1": {
                  "@type": "Link",
                  "href": "ldap://example.com:6666/o=ABC%20Industries,\
                                 c=US???(cn=Jim%20Dolittle)",
                  "rel": "alternate"
                }
              }
            }
          },
          "created ": "2020-07-09T03:04:23Z",
          "start": "2020-06-22T12:00:00",
          "timeZone": "America/New_York",
          "duration": "PT1H",
          "title": "event with contact",
          "uid": "6252D6C40A8308BFE25BBEFcontact-1"
        }
      ]
    }
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="example-simple-resource"
                     title="Simple event with RESOURCES">
                <t>
                    TBD
                </t>
            </section>

            <section anchor="example-recur-overrides1"
                     title="Recurring event. Attendees only in overrides">
                <t>
                    In this more complex example there is no ORGANIZER or ATTENDEEs
                    in the master event. There are overrides which
                    invite one or more attendees.
                </t>

                <t>
                    For one overrride the ORGANIZER is also an ATTENDEE.
                    In the other that is not the case. This is reflected
                    in the "roles" property for the organizer.
                </t>

                <t>
                    Note that each override has its own "participants"
                    property and the first has a links property to handle
                    the DIR parameter on one attendee.
                    <figure>
                        <artwork><![CDATA[
    BEGIN:VCALENDAR
    PRODID://Example.org//Example V3.13.2//EN
    VERSION:2.0
    BEGIN:VEVENT
    CREATED:20200704T035515Z
    DURATION:PT1H
    DTSTAMP:20200704T035706Z
    DTSTART;TZID=America/New_York:20200522T120000
    LAST-MODIFIED:20200704T035706Z
    SUMMARY:recurring daily 8 times
    UID:6252D6C40A8308BFE25BBEFrecur1-1
    RRULE:FREQ=DAILY;COUNT=8
    END:VEVENT
    BEGIN:VEVENT
    RECURRENCE-ID;TZID=America/New_York:20200523T120000
    ATTENDEE:mailto:douglm@example.org
    ATTENDEE;RSVP=TRUE;SCHEDULE-STATUS=1.2;DIR="http://example.org/
     vcards/vbede.vcf":mailto:vbede@example.org
    CREATED:20200704T035515Z
    DURATION:PT1H
    DTSTAMP:20200704T035706Z
    DTSTART;TZID=America/New_York:20200523T120000
    LAST-MODIFIED:20200704T035706Z
    ORGANIZER:mailto:douglm@example.org
    SUMMARY:recurring daily 8 times
    UID:6252D6C40A8308BFE25BBEFrecur1-1
    END:VEVENT
    BEGIN:VEVENT
    RECURRENCE-ID;TZID=America/New_York:20200524T120000
    ATTENDEE;RSVP=TRUE;SCHEDULE-STATUS=1.2:mailto:user01@example.org
    ATTENDEE;RSVP=TRUE;SCHEDULE-STATUS=1.2:mailto:vbede@example.org
    CREATED:20200704T035515Z
    DURATION:PT1H
    DTSTAMP:20200704T035706Z
    DTSTART;TZID=America/New_York:20200524T120000
    LAST-MODIFIED:20200704T035706Z
    ORGANIZER:mailto:douglm@example.org
    SUMMARY:recurring daily 8 times
    UID:6252D6C40A8308BFE25BBEFrecur1-1
    END:VEVENT
    END:VCALENDAR

    translates to

    {
      "@type": "jsgroup",
      "prodId": "//Example.org//Example V3.13.2//EN",
      "entries": [
        {
          "@type": "jsevent",
          "created ": "2020-07-04T03:57:06Z",
          "start": "2020-05-22T12:00:00",
          "timeZone": "America/New_York",
          "duration": "PT1H",
          "title": "recurring daily 8 times",
          "uid": "6252D6C40A8308BFE25BBEFrecur1-1",
          "recurrenceRules": [
            {
              "@type": "RecurrenceRule",
              "frequency": "daily",
              "count": 8
            }
          ],
          "recurrenceOverrides": {
            "2020-05-23T12:00:00": {
              "participants": {
                "be450b70-9bf7-4f6e-8f65-971ede566ce3": {
                  "@type": "Participant",
                  "sendTo": {
                    "imip": "mailto:douglm@example.org"
                  },
                  "roles": {
                    "attendee": true,
                    "owner": true
                  }
                },
                "a539dfe3-4463-4f28-b9de-17d3a0e99faf": {
                  "@type": "Participant",
                  "sendTo": {
                    "imip": "mailto:vbede@example.org"
                  },
                  "expectReply": true,
                  "links": {
                    "1": {
                      "@type": "Link",
                      "href": "http://example.org/vcards/vbede.vcf",
                      "rel": "alternate"
                    }
                  },
                  "roles": {
                    "attendee": true
                  },
                  "scheduleStatus": "1.2"
                }
              },
              "replyTo": {
                "imip": "mailto:douglm@example.org"
              }
            },
            "2020-05-24T12:00:00": {
              "participants": {
                "daeae4cf-6f6a-4ce3-9f4d-6bd884650d3d": {
                  "@type": "Participant",
                  "sendTo": {
                    "imip": "mailto:user01@example.org"
                  },
                  "expectReply": true,
                  "roles": {
                    "attendee": true
                  },
                  "scheduleStatus": "1.2"
                },
                "a6de6de3-271f-4679-9241-1b3bca6b602d": {
                  "@type": "Participant",
                  "sendTo": {
                    "imip": "mailto:vbede@example.org"
                  },
                  "expectReply": true,
                  "roles": {
                    "attendee": true
                  },
                  "scheduleStatus": "1.2"
                },
                "aaa8483b-b18b-4dbd-b218-77d8db027d35": {
                  "@type": "Participant",
                  "sendTo": {
                    "imip": "mailto:douglm@example.org"
                  },
                  "roles": {
                    "owner": true
                  }
                }
              },
              "replyTo": {
                "imip": "mailto:douglm@example.org"
              }
            }
          }
        }
      ]
    }
]]></artwork>
                    </figure>
                </t>
            </section>
        </section>

        <section anchor="security-considerations" title="Security Considerations">
            <t>
                The same security considerations as for <xref target="draft-ietf-calext-jscalendar"/> apply.
            </t>
        </section>

        <section anchor="iana-considerations" title="IANA Considerations">
            <t>
                None.
            </t>
        </section>

        <section anchor="acknowledgments" title="Acknowledgments">
            <t>
                The authors would like to thank the members of CalConnect for their valuable contributions. This
                specification originated from the work of the API technical committee of CalConnect, the Calendaring and
                Scheduling Consortium.
            </t>
        </section>
    </middle>

    <back>
        <references title="Normative References">
            <?rfc include="http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"?>
            <?rfc include="http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2397.xml"?>
            <?rfc include="http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.5545.xml"?>
            <?rfc include="http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.5546.xml"?>
            <?rfc include="http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.6638.xml"?>
            <?rfc include="http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7159.xml"?>
            <?rfc include="http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7265.xml"?>
            <?rfc include="http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7986.xml"?>
            <reference anchor="draft-ietf-calext-eventpub-extensions"
                       target="https://tools.ietf.org/html/draft-ietf-calext-eventpub-extensions">
                <front>
                    <title>Event Publishing Extensions to iCalendar</title>
                    <author/>
                    <date/>
                </front>
            </reference>
            <reference anchor="draft-ietf-calext-ical-relations"
                       target="https://tools.ietf.org/html/draft-ietf-calext-ical-relations">
                <front>
                    <title>Support for iCalendar Relationships</title>
                    <author/>
                    <date/>
                </front>
            </reference>
            <reference anchor="draft-ietf-calext-valarm-extensions"
                       target="https://tools.ietf.org/html/draft-ietf-calext-valarm-extensions">
                <front>
                    <title>VALARM Extensions for iCalendar</title>
                    <author/>
                    <date/>
                </front>
            </reference>
        </references>

        <references title="Informative References">
            <reference anchor="draft-ietf-calext-jscalendar"
                target="https://tools.ietf.org/html/draft-ietf-calext-jscalendar">
                <front>
                    <title>Task Extensions to iCalendar</title>
                    <author/>
                    <date/>
                </front>
            </reference>
            <reference anchor="draft-apthorp-ical-tasks"
                       target="https://tools.ietf.org/html/draft-apthorp-ical-tasks">
                <front>
                    <title>Task Extensions to iCalendar</title>
                    <author/>
                    <date/>
                </front>
            </reference>
        </references>

      <section title="Outdated document sections">

        <section anchor="translate-jscalendar-components"
                 title="Translating JSCalendar properties to iCalendar components">
            <t>
                This section is an alphabetic list of all JSCalendar
                property types that map on to components.
            </t>

            <section anchor="translate-jscal-jsevent" title="jsevent">
                <t>
                    A JSCalendar object with a type of "jsevent" is mapped on to a
                    <xref target="RFC5545"/> VEVENT component.
                </t>
                <t>
                    If it is a single VEVENT then a
                    <xref target="RFC5545"/> VCALENDAR component must
                    surround it and the JSCalendar "prodid" property
                    will be converted to a <xref target="RFC5545"/> PRODID.
                    <figure>
                        <artwork><![CDATA[
  {
    "@type": "jsevent",
    "prodid": "-//ABC Corporation//NONSGML My Product//EN",
    ...
  }

  maps to

  BEGIN: VCALENDAR
  PRODID:-//ABC Corporation//NONSGML My Product//EN
  BEGIN:VEVENT
  ...
  END:VEVENT
  END: VCALENDAR
]]></artwork>
                    </figure>
                </t>
                <t>
                    When converting multiple JSEvent or JSTask objects
                    the surrounding <xref target="RFC5545"/> VCALENDAR
                    object must have a <xref target="RFC5545"/> PRODID
                    set from either the JSGroup "prodid" or generated.
                </t>
            </section>

            <section anchor="translate-jscal-jsgroup" title="jsgroup">
                <t>
                    A JSCalendar object with a type of "jsgroup" is mapped on to a
                    <xref target="RFC5545"/> VCALENDAR component.
                    <figure>
                        <artwork><![CDATA[
  {
    "@type": "jsgroup",
    "prodid": "-//ABC Corporation//NONSGML My Product//EN",
    ...
    {
      "@type": "jsevent",
      ...
    }
    {
      "@type": "jsevent",
      ...
    }
  }

  maps to

  BEGIN: VCALENDAR
  PRODID:-//ABC Corporation//NONSGML My Product//EN
  BEGIN:VEVENT
  ...
  END:VEVENT
  BEGIN:VEVENT
  ...
  END:VEVENT
  END: VCALENDAR
]]></artwork>
                    </figure>
                </t>
            </section>

            <section anchor="translate-jscal-jstask" title="jstask">
                <t>
                    A JSCalendar object with a type of "jstask" is mapped on to a
                    <xref target="RFC5545"/> VTODO component.
                </t>
                <t>
                    If it is a single VTODO then a
                    <xref target="RFC5545"/> VCALENDAR component must
                    surround it and the JSCalendar "prodid" property
                    will be converted to a <xref target="RFC5545"/> PRODID.
                    <figure>
                        <artwork><![CDATA[
  {
    "@type": "jstask",
    "prodid": "-//ABC Corporation//NONSGML My Product//EN",
    ...
  }

  maps to

  BEGIN: VCALENDAR
  PRODID:-//ABC Corporation//NONSGML My Product//EN
  BEGIN:VTODO
  ...
  END:VTODO
  END: VCALENDAR
]]></artwork>
                    </figure>
                </t>
                <t>
                    When converting multiple JSEvent or JSTask objects
                    the surrounding <xref target="RFC5545"/> VCALENDAR
                    object must have a <xref target="RFC5545"/> PRODID
                    set from either the JSGroup "prodid" or generated.
                </t>
            </section>

            <section anchor="translate-jscal-timezones-comp"
                     title="timezones">
                <t>
                    The JSCalendar TimeZone objects within a "timezones"
                    property are mapped on to
                    <xref target="RFC5545"/> VTIMEZONE components within
                    the surrounding VCALENDAR component. Each mapped
                    TimeZone MUST only appear once.
                    <figure>
                        <artwork><![CDATA[
  {
    "@type": "jsevent",
    ...
    "timezones": {
      "/Example/Somewhere: {
        "@type": "TimeZone",
        ...
      },
      "/Example/Somewhere-else": {
        "@type": "TimeZone",
        ...
      }
    }
  }

  maps to

  BEGIN: VTIMEZONE
  TZID: /Example/Somewhere
  ...
  END: VTIMEZONE
  BEGIN: VTIMEZONE
  TZID: /Example/Somewhere-else
  ...
  END: VTIMEZONE
  BEGIN: VEVENT
  ...
  END: VEVENT
]]></artwork>
                    </figure>
                </t>
                <t>
                    When converting multiple JSEvent or JSTask objects
                    the surrounding <xref target="RFC5545"/> VCALENDAR
                    object must have a <xref target="RFC5545"/> PRODID
                    set from either the JSGroup "prodid" or generated.
                </t>
            </section>

            <section anchor="translate-jscal-locations" title="locations">
                <t>
                    JSCalendar locations should be mapped on to
                    <xref target="draft-ietf-calext-eventpub-extensions"/>VLOCATION
                    components. Additionally, for backwards compatibility,
                    a location should be mapped on to a
                    <xref target="RFC5545"/> LOCATION property. This property
                    should be mapped from the only location or the one
                    related to the start.
                </t>
            </section>

            <section anchor="translate-jscal-participants"
                     title="participants">
                <t>
                    JSCalendar participants will be mapped on to
                    different iCalendar properties and components depending on
                    their jsCalendar role values.
                </t>
                <t>
                    A participant with a role containing "contact"
                    MUST be mapped on to an iCalendar CONTACT property
                    and SHOULD also be mapped on to a
                    <xref target="draft-ietf-calext-eventpub-extensions"/>PARTICIPANT
                    component which provides a better mapping.
                </t>
                <t>
                    A participant with a role containing "owner"
                    MUST be mapped on to an iCalendar ORGANIZER property
                    and SHOULD also be mapped on to a
                    <xref target="draft-ietf-calext-eventpub-extensions"/>PARTICIPANT
                    component which provides a better mapping.
                </t>
                <t>
                    A participant with a role containing any of "attendee",
                    "optional" or "informational"
                    MUST be mapped on to an iCalendar ATTENDEE property
                    and SHOULD also be mapped on to a
                    <xref target="draft-ietf-calext-eventpub-extensions"/>PARTICIPANT
                    component which provides a better mapping.
                </t>

                <t>
                    A more complete mapping may be achieved by creating a
                    <xref target="draft-ietf-calext-eventpub-extensions"/>PARTICIPANT
                    component.
                </t>

                <t>
                    For all properties the participants jsCalendar "language"
                    property, if present, is mapped on to the iCalendar
                    "LANG" property parameter.
                </t>

                <t>
                    For all properties if the participant contains a
                    jsCalendar "link" with a "rel" of "alternate" then
                    the value of the link is used for the iCalendar
                    "ALTREP" property parameter.
                </t>

                <t>
                    Where do we get the cua?
                </t>

            </section>
        </section>

        <section anchor="Note" title="Note">
            <t>
                The sections following this one are all the original ones
                from draft 1 writen by Robert/Neil - there for reference.
            </t>
        </section>

        <section anchor="translate-jsevent" title="JSEvent">
            <t>
                A JSEvent maps to the the iCalendar VEVENT component type
                <xref target="RFC5545"/>.
                The following tables maps the JSEvent-specific properties to iCalendar:
            </t>

            <texttable anchor="translate-jsevent-properties" title="Mapping JSEvent properties">
                <ttcol align='left'>Property</ttcol>
                <ttcol align='left'>iCalendar counterpart</ttcol>
                <c>duration</c>
                <c>
                    DURATION property.
                    If the VEVENT contains a DTEND
                    property, the this maps to the duration property
                    as the time span between DTSTART and DTEND when converting the
                    respective time points to the UTC time zone.
                    Fractional seconds SHOULD be preserved with the SUBSECOND parameter.
                </c>
            </texttable>
        </section>

        <section anchor="translate-jstask" title="JSTask">
            <t>
                A JSTask object maps to the iCalendar VTODO component type
                <xref target="RFC5545"/>.
                The following tables maps the JSTask-specific properties to iCalendar:
            </t>
            <texttable anchor="translate-jstask-time-table" title="Mapping JSTask properties">
                <ttcol align='left'>Property</ttcol>
                <ttcol align='left'>iCalendar counterpart</ttcol>
                <c>due</c>
                <c>
                    Maps to the DUE property. See <xref target="translate-time"/>.
                </c>
                <c>estimatedDuration</c>
                <c>
                    ESTIMATED-DURATION property in the RFC draft <xref target="draft-apthorp-ical-tasks"/>,
                    or the DURATION property otherwise.
                    Fractional seconds SHOULD be preserved with the SUBSECOND parameter.
                </c>

                <c>statusUpdatedAt</c>
                <c>
                    COMPLETED property. The JSTask status property
                    MUST have value <spanx style="verb">completed</spanx>.
                    Fractional seconds SHOULD be preserved with the SUBSECOND parameter.
                </c>

                <c>progress</c>
                <c>
                    PARTSTAT and COMPLETED properties, including the
                    definitions in the RFC draft <xref target="draft-apthorp-ical-tasks"/>.
                </c>

                <c>status</c>
                <c>
                    STATUS property, including the
                    definitions in the RFC draft <xref target="draft-apthorp-ical-tasks"/>.
                </c>

            </texttable>
        </section>

        <section title="JSGroup">
            <t>
                A JSGroup maps to a iCalendar VCALENDAR containing VEVENT or VTODO components.
            </t>
            <texttable anchor="translate-jsgroup-table" title="Mapping JSGroup properties">
                <ttcol align='left'>Property</ttcol>
                <ttcol align='left'>iCalendar counterpart</ttcol>

                <c>entries</c>
                <c>
                    VEVENT and VTODO components embedded in a VCALENDAR component.
                </c>

                <c>source</c>
                <c>
                    SOURCE property.
                </c>
            </texttable>
        </section>

        <section anchor="icalendar-translation" title="Common properties">
            <t>
                This section contains recommendations how to map JSCalendar from and to iCalendar.
                It lists all common JSCalendar object properties in alphabetical order.
            </t>

            <texttable anchor="translate-commonprops-table"
                       title="Translation between JSCalendar and iCalendar">

                <ttcol align='left'>Property</ttcol>
                <ttcol align='left'>iCalendar counterpart</ttcol>

                <c>@type</c>
                <c>
                    Determined by the iCalendar component type: <spanx style="verb">jsevent</spanx>
                    for VEVENT, <spanx style="verb">jstask</spanx> for VTODO,
                    <spanx style="verb">jsgroup</spanx> for VCALENDAR.
                </c>

                <c>alerts</c>
                <c>
                    Each entry maps to a VALARM component.

                    The action property maps to iCalendar ACTION, where
                    both iCalendar <spanx style="verb">DISPLAY</spanx> and <spanx style="verb">AUDIO</spanx>
                    values map to the <spanx style="verb">display</spanx> action. An EMAIL value maps
                    to a JSCalendar <spanx style="verb">email</spanx> action.
                    <spanx style="emph">relativeTo</spanx> and <spanx style="emph">offset</spanx>
                    map to the TRIGGER property.
                </c>

                <c>categories</c>
                <c>
                    CONCEPT property, defined in <xref target="draft-ietf-calext-ical-relations"/>.
                </c>

                <c>color</c>
                <c>
                    COLOR property, as specified in <xref target="RFC7986"/>.
                </c>

                <c>created</c>
                <c>
                    CREATED property.
                    Fractional seconds SHOULD be preserved with the SUBSECOND parameter.
                </c>

                <c>description</c>
                <c>
                    DESCRIPTION property.
                </c>

                <c>descriptionContentType</c>
                <c>
                    Implementation-specific.
                </c>

                <c>excluded</c>
                <c>
                    EXDATE property.
                    Fractional seconds SHOULD be preserved with the SUBSECOND parameter.
                </c>

                <c>freeBusyStatus</c>
                <c>
                    TRANSP property.
                </c>

                <c>invitedBy</c>
                <c>
                    Implementation-specific.
                </c>

                <c>keywords</c>
                <c>
                    CATEGORIES property, as specified in <xref target="RFC7986"/>.
                </c>

                <c>links</c>
                <c>
                    ATTACH (<xref target="RFC5545"/>), URL or IMAGE (<xref target="RFC7986"/>)
                    properties with URI value types map to the the Link <spanx style="emph">href</spanx>.
                    The FMTTYPE parameter maps to <spanx style="emph">type</spanx>,
                    the SIZE parameter to <spanx style="emph">size</spanx>.
                    Mapping other properties is implementation-specific.
                </c>

                <c>locale</c>
                <c>
                    LANGUAGE parameter of the SUMMARY or DESCRIPTION property.
                </c>

                <c>localizations</c>
                <c>
                    Implementation-specific.
                </c>

                <c>locations</c>
                <c>
                    See <xref target="translate-locations"/>.
                </c>

                <c>method</c>
                <c>
                    METHOD property of the embedding VCALENDAR.
                </c>

                <c>participants</c>
                <c>
                    See <xref target="translate-participants"/>.
                </c>

                <c>priority</c>
                <c>
                    PRIORITY property.
                </c>

                <c>privacy</c>
                <c>
                    CLASS property.
                </c>

                <c>prodId</c>
                <c>
                    PRODID property.
                </c>

                <c>recurrenceOverrides</c>
                <c>
                    RDATE and EXDATE properties, and any VEVENT or
                    VTODO instances with a recurrence-id and same UID
                    as the mapped main object. If the DTSTART property
                    defines a SUBSECOND parameter, but the RECURRENCE-ID
                    of a recurrence instance does not, then use the
                    SUBSECOND parameter value of DTSTART to determine
                    the recurrence override time stamp.
                </c>

                <c>recurrenceRule</c>
                <c>
                    RRULE property. For all-day calendar objects,
                    map the <spanx style="verg">until</spanx> property value to an iCalendar
                    DATE (effectively removing the time component). To convert a DATE-typed UNTIL
                    from iCalendar, set the time components of the LocalDateTime value to
                    <spanx style="verb">23:59:59</spanx>. If the iCalendar UNTIL value is a
                    UTC date time, convert it to the local time in the JSCalendar calendar
                    object time zone. To convert to iCalendar where the DTSTART or DUE property
                    is of type DATE, omit the time component of the LocalDateTime value.
                </c>

                <c>relatedTo</c>
                <c>
                    RELATED-TO property.
                </c>

                <c>replyTo</c>
                <c>
                    An iCalendar ORGANIZER with a mailto: URI mapped to the
                    <spanx style="verb">imip</spanx> method, or any other
                    URI mapped to the <spanx style="verb">other</spanx>
                    method. Mapping multiple methods is implementation-specific.
                </c>

                <c>sequence</c>
                <c>
                    SEQUENCE property.
                </c>

                <c>showWithoutTime</c>
                <c>
                    Implementation-specific.
                </c>

                <c>start</c>
                <c>
                    Maps to the DTSTART property. See <xref target="translate-time"/>.
                </c>

                <c>status</c>
                <c>
                    STATUS property.
                </c>

                <c>timeZone</c>
                <c>
                    Maps to the TZID parameter.  See <xref target="translate-time"/>.
                </c>

                <c>timeZones</c>
                <c>
                    Each entry in the property maps to a VTIMEZONE in the embedding VCALENDAR component.
                </c>

                <c>title</c>
                <c>
                    SUMMARY property.
                </c>

                <c>uid</c>
                <c>
                    UID property.
                </c>

                <c>updated</c>
                <c>
                    DTSTAMP and LAST-MODIFIED properties.
                    Fractional seconds SHOULD be preserved with the SUBSECOND parameter.
                </c>

                <c>useDefaultAlerts</c>
                <c>
                    Implementation-specific.
                </c>

                <c>virtualLocations</c>
                <c>
                    See <xref target="translate-locations"/>.
                </c>

            </texttable>

            <section anchor="translate-time" title="Time properties and types">
                <t>
                    iCalendar defines two different time types, DATE and DATE-TIME, where
                    the latter may occur in three forms (with local time, with UTC time,
                    with local time and time zone reference). In contrast, JSCalendar does
                    not define a distinct type for dates, and date times are defined with the
                    LocalDateTime type only.
                    <vspace blankLines="1"/>
                    A JSCalendar time maps to the iCalendar DATE type if all of the following
                    criteria apply:
                    <list style="symbols">
                        <t>
                            The <spanx style="verb">start</spanx> (<spanx style="verb">due</spanx>)
                            property value has zero time, or is not set.
                        </t>
                        <t>
                            The <spanx style="verb">duration</spanx>
                            (<spanx style="verb">estimatedDuration</spanx>) property value has
                            zero time, or is a multiple of days or weeks, or is not set.
                        </t>
                        <t>
                            The <spanx style="verb">timeZone</spanx> property value is null,
                            or is not set.
                        </t>
                    </list>
                    <vspace blankLines="1"/>
                    For all other cases, the time maps to an iCalendar DATE-TIME:
                    <list style="symbols">
                        <t>
                            With local time and time zone reference, if the <spanx style="verb">timeZone</spanx>
                            property value is set and does not equal <spanx style="verb">Etc/UTC</spanx>.
                        </t>
                        <t>
                            With UTC time, if the <spanx style="verb">timeZone</spanx> property value
                            equals <spanx style="verb">Etc/UTC</spanx>.
                        </t>
                        <t>
                            With local time, if the <spanx style="verb">timeZone</spanx>
                            property value is null or not set.
                        </t>
                    </list>
                    Fractional seconds SHOULD be preserved with the SUBSECOND parameter.
                </t>
            </section>

            <section anchor="translate-locations" title="Locations">
                <t>
                    The iCalendar counterpart for JSCalendar Location objects is the iCalendar
                    <xref target="RFC5545"/> LOCATION property, or implementation-specific.
                  </t>
                <texttable anchor="translate-locations-table"
                  title="Mapping Location properties">
                  <ttcol align='left'>Property</ttcol>
                  <ttcol align='left'>iCalendar counterpart</ttcol>

                  <c>coordinates</c>
                  <c>
                      GEO property.
                  </c>

                  <c>description</c>
                  <c>
                      Implementation-specific.
                  </c>

                  <c>name</c>
                  <c>
                      LOCATION property value.
                  </c>

                  <c>rel</c>
                  <c>
                      Implementation-specific.
                  </c>

                  <c>timeZone</c>
                  <c>
                      Implementation-specific.
                  </c>

                  <c>uri</c>
                  <c>
                      The LOCATION ALTREP parameter.
                  </c>

                </texttable>
                <t>
                    The iCalendar counterpart for JSCalendar VirtualLocation objects is the iCalendar
                    <xref target="RFC7986"/> CONFERENCE property.
                </t>
                <texttable anchor="translate-virtualLocations-table"
                    title="Mapping virtualLocation properties">
                    <ttcol align='left'>Property</ttcol>
                    <ttcol align='left'>iCalendar counterpart</ttcol>
                    <c>description</c>
                    <c>
                        Implementation-specific.
                    </c>

                    <c>name</c>
                    <c>
                        LABEL parameter.
                    </c>

                    <c>uri</c>
                    <c>
                        CONFERENCE property value.
                    </c>
                </texttable>
            </section>

            <section anchor="translate-participants" title="Participants">
                <t>
                    The following table outlines translation of JSCalendar participants.
                    An iCalendar ORGANIZER maps to both the replyTo property
                    and a participant with role <spanx style="verb">owner</spanx>. If
                    an ATTENDEE with the same CAL-ADDRESS value exists, then it maps
                    to the same participant as the ORGANIZER participant. Other participants
                    map to ATTENDEEs.
                </t>
                <texttable anchor="translate-participants-table"
                    title="Mapping Participant properties">
                    <ttcol align='left'>Property</ttcol>
                    <ttcol align='left'>iCalendar counterpart</ttcol>

                    <c>attendance</c>
                    <c>
                        ROLE parameter values REQ-PARTICIPANT, OPT-PARTICIPANT and
                        NON-PARTICIPANT.
                    </c>

                    <c>delegatedFrom</c>
                    <c>
                        DELEGATED-FROM parameter
                    </c>

                    <c>delegatedTo</c>
                    <c>
                        DELEGATED-TO parameter
                    </c>

                    <c>email</c>
                    <c>
                        EMAIL parameter, if
                        defined. Otherwise the CAL-ADDRESS property value, if it is a mailto: URI.
                    </c>

                    <c>expectReply</c>
                    <c>
                        RSVP parameter
                    </c>

                    <c>kind</c>
                    <c>
                        CUTYPE parameter
                    </c>

                    <c>locationId</c>
                    <c>
                        Implementation-specific.
                    </c>

                    <c>memberOf</c>
                    <c>
                        MEMBER parameter
                    </c>

                    <c>name</c>
                    <c>
                        CN parameter
                    </c>

                    <c>participationStatus</c>
                    <c>
                        PARTSTAT parameter
                    </c>

                    <c>roles</c>
                    <c>
                        ROLE parameter.
                    </c>

                    <c>scheduleSequence</c>
                    <c>
                        SEQUENCE property of the participant's latest iMIP message
                    </c>

                    <c>scheduleUpdated</c>
                    <c>
                        DTSTAMP property of the participant's latest iMIP message
                    </c>

                    <c>sendTo</c>
                    <c>
                        A CAL-ADDRESS with a mailto: URI maps to the
                        JSCalendar <spanx style="verb">imip</spanx> method, any other
                        URI to the <spanx style="verb">other</spanx>
                        method. Mapping multiple methods is implementation-specific.
                    </c>

                </texttable>
            </section>

        </section>

        <section anchor="translate-custom" title="Custom properties">
            <t>
                Mapping custom or unknown properties between JSCalendar and iCalendar
                is implementation-specific. Implementations might use vendor-extension
                properties, which could
                also serve as basis for discussion for a JSCalendar standard extension.
                Alternatively, an implementation could preserve iCalendar properties
                and components in JSCalendar by use of a vendor-extension
                property formatted as jCal <xref target="RFC7265"/> data.
            </t>
        </section>
    </section>
    </back>
</rfc>
