W3C home > Mailing lists > Public > public-houdini@w3.org > April 2018

[Houdini] Minutes Berlin F2F 2018-04-09 Part I: Typed OM

From: Dael Jackson <daelcss@gmail.com>
Date: Wed, 25 Apr 2018 20:26:58 -0400
Message-ID: <CADhPm3t+3sSB38o=3MKSu20jjDPxm+SrBAWsfdULxuv2sx_s4A@mail.gmail.com>
To: public-houdini@w3.org
Cc: CSS WG <w3c-css-wg@w3.org>
=================================================
   These are the official Houdini Task Force
     minutes. Unless you're correcting the
      minutes, please respond by starting
 a new thread with an appropriate subject line.
=================================================


Typed OM
---------

  - TabAtkins reviewed the work that has been done to begin defining
      how to reify style values
(https://drafts.css-houdini.org/css-typed-om/#reify-stylevalue )
      in order to ensure that they're going in the right direction.
      - Generally everyone seemed fine with the approach so TabAtkins
          will continue that approach.
      - There were several actions for TabAtkins to take coming from
          the group's feedback:
          - Look into specifying specified values serializations in
              CSS.
          - Add note about things planning to change, e.g.
              CSSStyleValue expansions.
      - The prefixed properties that have been specified to ensure
          compat will need to be added to the reification list.

  - RESOLVED: When we have this sort of upgrade situation we should,
              if possible, make new complex type subclass whatever it
              was before, but only do it for upgrade situations.
              (Issue #735: Change CSSKeywordValue's attribute to allow
              forward-compatible upgrades)
  - RESOLVED: Spec goes with CSSOMString with an issue saying this is
              being discussed by TAG and should revisit in the future
              (Issue #687: Should we be using DOMString, USVString, or
              CSSOMString?)
  - RESOLVED: Restrict to just window and CSS worklets.
              (Issue #632: Restrict workers that `CSSStyleValue` is
              exposed to)
  - RESOLVED: Accept TabAtkins's proposed design to handle URL
              function (Handle this is always reify the URL function
              to a CSS URL class that exposes basically nothing. Then
              have some methods like asImage that returns a promise
              for an image type.).
  - RESOLVED: We accept this proposal for CSSURLValue
              https://github.com/w3c/css-houdini-drafts/issues/716#issuecomment-368659261
              but also expose the original URL and base URL.
              - Proposal for CSSURLValue:
                  - will expose a .url attribute.
                  - This URL will always be either absolute, or a bare
                  hash. If absolute, it will be absolutized according
                  to standard CSS rules (using the base URL of the
                  stylesheet/document). The underlying value might or
                  might not be absolutized at this point (the timing
                  is currently undefined in CSS), but Typed OM will
                  always present an absolutized URL. This avoids the
                  current undefined behavior in CSS, and gives more
                  author-friendly behavior when moving values between
                  contexts with different base URLs.
                  - will have a constructor that takes a URL; again,
                  it will either be absolutized immediately or left as
                  a bare hash, using the "current setting object's API
                  base url" (per @domenic)
              - "original url" is what's actually specified in url().
                  "base url" is whatever the base URL that CSS uses in
                  the context that the value is encountered.

===== FULL MINUTES BELOW ======

Agenda: https://github.com/w3c/css-houdini-drafts/wiki/Berlin-F2F-April-2018

Present:
  Rossen Atanassov, Microsoft
  Tab Atkins, Google
  David Baron, Mozilla
  Christian Biesinger, Google (observer)
  Brian Birtles, Mozilla
  Oriol Brufau (observer)
  Emilio Cobos, Mozilla (observer)
  Elika Etemad, Invited Expert
  Rob Flack, Google
  Simon Fraser, Apple
  Dael Jackson, Invited Expert
  Ian Kilpatrick, Google
  Rune Lillesveen, Google
  Chris Lilley, W3C
  Peter Linss, Invited Expert, TAG
  Naina Raisinghani, Google
  Francois REMY, Microsoft
  Dirk Schulze, Adobe
  Shane Stephens, Google
  Alan Stearns, Adobe
  Surma, Google
  Majid Valipour, Google
  Lea Verou, Invited Expert

Scribe: dael

Typed OM
=========

Reifying style values
---------------------
  Link: https://drafts.css-houdini.org/css-typed-om/#reify-stylevalue

  TabAtkins: First issue is a quick review of reification and if what
             we have so far looks good.
  TabAtkins: The general rule looks like [shows
             https://drafts.css-houdini.org/css-typed-om/#reify-stylevalue ]
  TabAtkins: Specific computed values are treated the same. You ask
             what the value is and reify it to a value.
  TabAtkins: That's basically how they all work.

  TabAtkins: Reification is making something into an object. Basically
             make the correct mapping type object.
  TabAtkins: background-repeat
(https://drafts.csswg.org/css-backgrounds-3/#propdef-background-repeat
)
             is an extreme one because it has several forms.
  TabAtkins: If you say repeat repeat it becomes repeat. If it's more
             complicated it becomes 2 keywords. Else we send it as
             style value as a string.
  emilio: The string it came from?
  TabAtkins: Depends where drawing from. Specified takes the actual
             string, computed is serialized from.
  Rune: Computed value or resolved?
  TabAtkins: Actual computed.

  dbaron: Are you requiring...specified values maintain some state but
          not all about spec. How much are you specifying? The way
          current ones work there are something things normalized and
          some not.
  TabAtkins: It's not specified so if there's details preserved,
             great. I'm assuming can get authors information.
  dbaron: In many cases it's preserved in a value form and normalizes
          away some distinctions.
  Rune: That's the case for blink as well.
  TabAtkins: I know specified values retain color format.
  Rune: We do that.
  TabAtkins: The numbers in there are normalized.
  emilio: The color case is a special case. When you specify an ID
          that's the only case we keep the string.
  rune: I think that's the case with blink as well.
  dbaron: But we wouldn't preserve if you specify 100.0 or 100.000
  TabAtkins: So I need to have specified value serializations.
  Rossen: That would be good in CSS.
  dbaron: And needs research.
  TabAtkins: As long as I keep it on the level of recomputing it
             should be okay.
  TabAtkins: I'm not trying to spec how the current APIs work, just
             how a new one stringifies. I'll try to be close.
  TabAtkins: I'll need to record that.
  ACTION: TabAtkins Investigate specifying specified values
  <trackbot> Created ACTION-869

  TabAtkins: Continuing.
  TabAtkins: A bunch of things have a final clause. Plan eventually is
             extend the OM to eliminate these. Worse case it may be a
             value list. In many cases we should be able to have a
             more useful object spec to the property and the general
             value shape.
  dbaron: Question: Is that going to be basically fully backwards
          compat so new object has some style value behavior?
  TabAtkins: Yes. Only behavior is it stringifies to something with
             the value.
  dbaron: Type indicator?
  TabAtkins: No.
  dbaron: I think it's probably nice in cases where you intend to
          change in the future to have a note in the spec so that
          people are aware of it for compat.
  TabAtkins: We can note. It'll be most or all that fall to a complex
             value.
  ACTION: TabAtkins Add note about things planning to change, e.g.
          CSSStyleValue expansions
  <trackbot> Created ACTION-870

  TabAtkins: Still got a lot of cases to fill in. I've done 10-20%.
             Most are easy because they're number or keyword.
  TabAtkins: There's one case with specified and computed as different.
  TabAtkins: azimuth
  TabAtkins: The computed value is simpler then specified value. It
             can be keyword, angle or both. As computed it's
             only one. This will be the case for other properties.
  emilio: Different types of lengths? So computed and spec are same in
          OM?
  TabAtkins: Yes.
  TabAtkins: This doesn't care about what unit is used, that's CSS
             domain. All this says is whatever the value is turn it
             into an object.

  emilio: Are engines supposed to preserve calc? Only FF does it
          afaict. Blink treats it as normal int, I believe. Does that
          need to be addressed?
  TabAtkins: It's a bug, but a bug on the typed OM side. If you're not
             preserving the information it will just come out as a 1px
             length. We're just taking the value as it is.

  TabAtkins: If this looks fine I'll continue, if people have specific
             complaints or a property let me know as I do them. I'll
             continue this list and grabbing properties.
  TabAtkins: Do we want prefixed properties in this list?
  Rossen: If you want the web to work.
  TabAtkins: Do we care enough that we want a spec way to deal with
             them.
  Rossen: Let's see how long we can go without.
  gsnedders: I'd favor webkit prefixed that we've specced.
  dbaron: Probably should write a section for spec authors about how
          to write new properties and hopefully new stuff follows
          those rules. I agree prefixed things we spec should be in
          here.
  TabAtkins: Do we have a list?
  gsnedders: I think it's across specs.
  TabAtkins: Then can I request non-webkit browser let me know what
             they impl?

  fremy: If you have properties like each other do you get 2x the
         object?
  TabAtkins: Every time you request the value you get fresh objects.
  fremy: Okay
  TabAtkins: No object reuse. You can reuse them yourself, but it will
             always do fresh.

  brian: How do we maintain going forward?
  TabAtkins: Best for everyone to have a doc we maintain as a living
             standard. Also because everyone goes through one spot we
             can maintain. I'd prefer to handle it that way. A
             separate doc.
  TabAtkins: Is that okay.
  nainar: Yes.
  TabAtkins: Same is typed OM rules for serialization as well. Turning
             a style into a string.

  TabAtkins: We're done with that topic.
  brian: Can we add the definition to typed OM?
  <gsnedders> The answer for -webkit- spec'd props seems to be
              -webkit-line-clamp [CSS Overflow] and
              -webkit-user-select [CSS UI] plus a whole load from
              [Compat]
  TabAtkins: Yes, that would be good. Can you file a bikeshed for me?
             I'll put something in prop defs.
  fantasai: So split into 2 doc?
  TabAtkins: Not yet, but at some point we might.
  TabAtkins: Point I wanted is maintain this list as a single unified
             list that we keep updating. Maybe not standards track,
             but as much as we can.
  TabAtkins: Any further concerns raise it now. Otherwise talk later.

Forwards-compat design choices
------------------------------
  GitHub: https://github.com/w3c/css-houdini-drafts/issues/735

  TabAtkins: One issue...a general issue with any attempt to design
             typed om is what happens when we change value space of a
             property.
  TabAtkins: There are patterns we commonly do like when something is
             a list. There are things not handled well like changing a
             property from being a single keyword to something more
             complex. Which means...the question is how to handle
             reification. If it started simple and we reify as a
             keyword and it becomes more complex there's options:
  TabAtkins: First is we maintain compat. If it's simple it's a
             keyword and more complex it's more complex. When the
             single keyword isn't a special case it's awkward to
             handle. It would mean if you want to test if the weight
             value is specified is it's the keyword or the keyword set.
             You'd have to branch twice. If we know the final value it
             would be more complex.
  TabAtkins: I think I can make it less complex in common cases. In
             the basic types the relevant accessor have a unique name
             and then when it upgrades is still has the accessor.
  TabAtkins: If we start with font-synthesis as a single value and
             then it becomes a double it would be a keyword set with a
             .keyword property that reflects the single value that
             exists. That way any older code will continue working
             properly. Newer code can work more natively.
  TabAtkins: Won't work always, but a lot of cases. Probably changes
             the accessor to .keyword and string to .string.
             .unit.value stays where it is.
  TabAtkins: More basic cases like a hash token we'll add a unique
             value.
  TabAtkins: Is that a good idea or do we accept that as we extend
             we'll have legacy things?

  shane: Is there a combo where we could consider so the special
         object type extends. This is the same trick as the style
         mapping. That gives us the consistency approach to a longer
         list.
  TabAtkins: Likely. What I like is if a property is keyword or
             numeric and people branch on type can still branch on
             type.
  TabAtkins: Means a slightly weird object hierarchy and we can't do
             it on number...Well...math values are more complex.  But
             strings or keywords subclassing keyword value class would
             be fine.
  dbaron: I feel...there's compat risk. Also the risk that once a
          thing is upgraded that people will write new code that only
          works for old stuff.
  TabAtkins: Example?
  dbaron: You're writing new code that only works with single keyword
          case because you forgot this property was upgraded. When the
          compat thing is a thing where you can handle the old values
          you're creating a risk that people will fall into the compat
          risk.
  TabAtkins: True, but only way to handle is break old code.
  dbaron: True.
  dbaron: There might be an advantage to not having the compat for
          properties that weren't upgraded. So if a property starts as
          multiple keywords there's an advantage of not having single
          keyword available.
  TabAtkins: That was my plan. If we know ahead of time something is
             complex it'll descend straight from style.

  TabAtkins: That reflects on a 3rd option, similar to how Ana tried
             to handle this.  Every value had a short named accessor
             that gave you a complex value of it. If it was simple
             you'd get simple, but you could also ask for the complex
             form and if it existed you'd get it.
  fremy: Other similar thing was a problem for c# browser. They solved
         that by when you add a value you give a list of all functions
         you expect and then as the UA you know all the values
         expected by the author and if it's none you can return the
         css style value. You have context. It worked for c# browser.
  TabAtkins: You'd have to put that into the get method.
  fremy: I don't know if it's good design, but it's one way that works.
  TabAtkins: I thought of that, but figured it was too much to write
             on every get call.

  TabAtkins: So, talking this over. Best idea is when we have this
             sort of upgrade situation we should, if possible, make
             new complex type subclass whatever it was before, but
             only do it for upgrade situations.
  fremy: Another thing we could do is when we make a breaking change
         we can make a priority like a .v2 if they don't have it they
         get the old scenario.
  TabAtkins: That's true. That's reasonable. I hadn't thought of the
             escape when we can't upgrade.
  TabAtkins: Reasonable to people?
  Proposed resolution: when we have this sort of upgrade situation we
           should, if possible, make new complex type subclass
           whatever it was before, but only do it for upgrade
           situations

  RESOLVED: When we have this sort of upgrade situation we should, if
            possible, make new complex type subclass whatever it was
            before, but only do it for upgrade situations.

  emilio: How is clamping done in typed om?
  TabAtkins: It's automatic. When it enters the style system clamping
             happens. If you try and set a negative value typed OM is
             fine, when it enters style system it's 0.

Which string type? - DOMString, USVString, or CSSOMString?
----------------------------------------------------------
  Github: https://github.com/w3c/css-houdini-drafts/issues/687

  TabAtkins: Intro: I need to know what type of string to use.
             Everyone familiar with these three?
  TabAtkins: DOMString is just JS strings. USVString is that but you
             can't write unpaired surrogates. Only actual scalar
             values. CSSOMString is one or the other and the UA has to
             choose.
  gsnedders: And it has to be consistent.
  TabAtkins: The arguments. USVString, it's an actual string and
             DOMString allows nonsense. But DOMString is exactly what
             JS uses. Some browsers can naively handle a scalar value
             faster and cheaper under the hood. Servo does that.
  TabAtkins: Earlier we said do USVString and for browsers not doing
             that have a [missed]. Dominic came in and said don't do
             that, we use DOMString for everything except those that
             require scalar values.

  TabAtkins: There was an argument on this on github between Dominic
             and plinss. [scrolls through github]
  <dbaron> https://github.com/heycam/webidl/issues/84 is an open issue
           about whether the WebIDL spec is providing the right advice
           there.
  TabAtkins: So, do we wait for TAG?
  plinss: We discussed in Tokyo. We don't have solid advice yet.
          There's a plan to get JS people and webIDL people together,
          but no answer yet.
  <dbaron> https://github.com/w3ctag/design-principles/issues/93 is
           the TAG issue on this
  TabAtkins: For the spec, I can put an inline in the spec saying it's
             under contention.
  Rossen: You're saying it's one or the other.
  Rossen: Right now it's CSSString and if the TAG narrows down we'll
          align.
  TabAtkins: I can go with that. Change everything to CSSOMString.
  Rossen: Yeah, it's pretty much what we do.
  astearns: But with the inline note saying we're hoping less vague.

  TabAtkins: Prop: spec goes with CSSOMString with an issue saying
             this is discussed by TAG and should resolve in the future
  Rossen: Obj or opinions?
  plinss: Anyone with good info on this issue to help TAG it would be
          good.
  emilio: If we change to DOMString it makes the private style system
          build a non-standard string which is annoying.
  fremy: It would be a mess, switching to surrogate pairs.

  RESOLVED: Spec goes with CSSOMString with an issue saying this is
            discussed by TAG and should resolve in the future

Which Workers to expose to?
---------------------------
  <TabAtkins> GitHub: https://github.com/w3c/css-houdini-drafts/issues/632

  TabAtkins: Currently we specify that all typed OM objects are
             exposed to all worker types because why not? It was
             brought up by the TAG "why do that, we should restrict to
             those needed". Fine with that, it's just if we need some
             in the future we have to edit the spec. No reason to
             disallow because only big contention is not all context
             can access the CSS parser. It's only a few things allowed
             in arbitrary context.
  dbaron: I think the norm is that things aren't on workers unless you
          can get to them there?
  TabAtkins: Yeah. Reasonable argument. If there's a general policy of
             don't expose unless there's a reason I'm happy to.
  dbaron: They're only on window and worklets.
  TabAtkins: Yes.

  dbaron: Is it...the other question is if it's exposed on all
          worklets or just paint worklet and if there should be a base
          class of all CSS worklets so we can expose that without
          interfering.
  iank: TypedOM we spec we need a workflow.
  TabAtkins: We can make a CSS type fast.
  fremy: [missed]
  TabAtkins: No, they're not a post-able type. There's nothing that
             prevents us from making it post-able.
  fremy: If you can send into a worker, that's a reason.
  TabAtkins: People would object to them being in post without a use
             case.
  iank: Only medium term thing that will use the typed OM is the
        canvas APIs. The font accepting a font query value. But we
        could expose that if canvas accepts it.
  TabAtkins: We can wait for a use case.

  TabAtkins: Happy to resolve to restrict to just window and CSS
             worklets for now.
  shane: It does seem to extract that we're going to great lengths to
         differentiate worklets. Through impl details the same APIs
         behave differently across workers has been a pain. It's a
         tiny thing that comes back to bite you.
  shane: Do we really want to make them all look different?
  dbaron: Many platform core APIs are single thread.
  shane: I get having the main thread be distinguished. But this is
         about workers.
  dbaron: There are some APIs that distinguish dedicated, shared and
          service worker.
  shane: Is the question do we need to distinguish these workers by
         the presence of this API?
  dbaron: I don't know. Would be interesting to talk to JS folks about
          performance and complexity. It feels good you can only
          access useful things, but I don't have strong feelings.
  shane: I don't have strong feelings, I wanted to do a counter point.

  cbiesinger: Do we have the parsing restricted?
  TabAtkins: Yes, it's restricted. You can construct values but you
             can't use the parsing to do it.
  TabAtkins: I still think for now restrict to just window and CSS
             worklets. If the discussion tends to being freer with
             worker exposed APIs we can change in the future.
  krit: Note it may change?
  TabAtkins: Yeah.
  Rossen: shane you okay?
  shane: Yes.
  Rossen: Obj?

  RESOLVED: Restrict to just window and CSS worklets.

Approve URL handling/design
---------------------------

  TabAtkins: The core issue is the URL function in CSS has many types.
             These types are not distinguishable at parse time. Like
             mask image you can't tell if URL is a reference to a mask
             or a URL. The things we want to expose when reifying on
             these are different.
  TabAtkins: Because previous resolutions on how to handle these I
             can't tell at time you ask for property what concrete
             type a URL should become. Reasonable in the future more
             cases will be ambiguous. If we let you refer to an SVG
             gradient URLs as an image might be a reference to SVG
             gradient.
  TabAtkins: My proposal to handle this is always reify the URL
             function to a CSS URL class that exposes basically
             nothing. Maybe just loading status. Then have some
             methods like asImage that returns a promise for an image
             type.
  TabAtkins: If you use image function we know it's an image. In
             general you get this featureless things and you have to
             ask. Only way around is to revisit the previous
             resolutions about making URLs a fragment which we
             rejected.
  TabAtkins: If there are better ideas I'd love to see them. Otherwise
             I think we'll have to go with an approach like this. Or
             we have to go back and revisit to let URL types be parse
             time knowable.

  krit: There were multiple discussions on how to do it at parse time.
  TabAtkins: It was always based on fragment or not.
  krit: For fragment you could put a fragment on an image.
  TabAtkins: Absolutely. The way around was you have the image
             function to say this is an image no matter what the URL
             looks like. If that doesn't get what you want you have
             exit clauses.
  krit: Required for author to know what type it has or put both on
        and look for which promise returns?
  TabAtkins: Yeah, ask for both.
  astearns: Or ask for the one you know what to do with.
  TabAtkins: You could have something that gives you what type it
             becomes in the end.

  smfr: Should we have a longer term plan to specify functions that
        are tied and deprecate URL?
  TabAtkins: I would like that. Image is already stronger then URL.
             There are a small number of other types of URLs we take.
             Like fonts.
  TabAtkins: If we impl image and encourage it's use that would
             eliminate a lot of issues.  If we go with the slightly
             awkward when you use URL it would encourage image.
  TabAtkins: Typed OM provides a reason to use image because it
             reifies immediately.

  astearns: Two proposals, one with multiple promises and one with a
            single?
  TabAtkins: No, that's just details. Question is generic or revisit.
  TabAtkins: Does anybody think we should revisit the resolution about
             parse time URL deciding?
  [silence]
  TabAtkins: I'll go with the design I described. You'll see it when
             it's in spec. If anyone objects at that point or has a
             better way, let me know.
  smfr: Should we have actions or issues to make instructions for
        references.
  TabAtkins: We have image. I think for CSS value there's an issue
             already.
  Rossen: Objections to TabAtkins's proposed design?

  RESOLVED: Accept TabAtkins's proposed design.

Loading and absolutization timing
---------------------------------
  github: https://github.com/w3c/css-houdini-drafts/issues/716

  TabAtkins: CSS is currently vague. It happens at some point but we
             don't know when.
  <nainar> https://github.com/w3c/css-houdini-drafts/issues/716#issuecomment-368659261
  TabAtkins: Here's my proposal ^
  TabAtkins: Has a URL attribute. It's either an absolute or a bare
             hash. If it's not a bare hash we'll use CSS rules.
             Underlying value may not be absolutized, but when it
             reifies we turn it absolute. If you move a style from one
             document to another it may be relative in the old way,
             but it's now absolute.
  TabAtkins: I think that's what people want.
  TabAtkins: When you construct a value it's absolutized immediately.

  dbaron: When is it bare hash?
  TabAtkins: When you pass it in as a local reference.
  TabAtkins: That's specified in the value spec?
  plinss: It's a string not a URL?
  TabAtkins: Yes, it's strictly spec that it's a string.
  TabAtkins: Only controversy is the early absolutizing. Is that okay
             or should we make it retain its relativeness and better
             define when it stops being relative.
  TabAtkins: If you want to manipulate the URL the URL spec requires
             an absolute value or a URL with a base. It would be
             harder for authors since it's hard to get the base.
  plinss: Would it make sense to keep it as a relative URL but also
          expose it as a base?
  TabAtkins: Possibly. In the current CSS if you use the OM APIs if
             you pull a relative URL and write it somewhere else it
             changes the base.
  plinss: Are we allowing authors to rationalize it as a valid URL if
          they want to.
  TabAtkins: Do authors want this?
  plinss: Yes.
  TabAtkins: I doubt they do. When this occurs style sheets are
             usually in same folder.

  nainar: If we're being more eager about absolutizing should that be
          in CSS as well?
  TabAtkins: Possibly.

  Brian: I'm wondering if there's a cloning use case?
  TabAtkins: But would people want to do that?
  TabAtkins: I can come up with a reason, but it's a minority case.
  krit: If you provide the base would you still get back relative?
  TabAtkins: You have to know where the split happened. If
             implementations want to preserve I can attach the
             original URL. But the core easiest to use should be
             absolute.
  krit: I'm fine with it as a default.
  plinss: I expect there will be use cases, like editor. In my
          experience any time someone tries to help me with URL they
          get in the way at some point. If it's destructive that's
          painful. If there's a way to preserve the original url.
  dbaron: Seems like it's not crazy to have multiple accessors.
  TabAtkins: I'm happy to put on an original URL value.
  plinss: Should that but the URL.
  TabAtkins: All the DOM apis do absolute URLs.

  TabAtkins: Prop: We accept this proposal but also expose the
             original URL.
  dbaron: You could also expose base URL
  <nainar> Proposal is comment in
https://github.com/w3c/css-houdini-drafts/issues/716#issuecomment-368659261
  TabAtkins: That would have to be dynamic. Oh, base URL as this
             instant. I could do that.
  dbaron: I don't know how useful, but if you're exposing a bunch of
          information.
  Rossen: Okay.
  Rossen: Suggestions, objections?

  RESOLVED: We accept this proposal
https://github.com/w3c/css-houdini-drafts/issues/716#issuecomment-368659261
            but also expose the original URL and base URL

  break: 20 minutes
Received on Thursday, 26 April 2018 00:28:00 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 19:53:28 UTC