Commit Graph
40 Commits
Author SHA1 Message Date
Michał OsadnikandFacebook Github Bot 247fc6774f Accept all types for objects' and arrays' elements
Summary:
Previously we accepted only very limited set of types for schema parser. However, in many cases we want to provide more specific typings e.g. accept enum or touple.

Currently, we don't take any advantages for codegen from specifying type of elements for object or array. All of them fallback to the same cpp code.

That's why I decided not to throw exception if types of arrays' and objects' elements are different than currently supported. Then I want to fallback to `undefined`.

Reviewed By: rickhanlonii

Differential Revision: D16325028

fbshipit-source-id: 3d7990ca0207c31f0ed522e7316a9cb17b6b1bcb
2019-07-17 06:21:51 -07:00
Michał OsadnikandFacebook Github Bot a70a8d0e75 Add support for stringish in codegen for modules
Summary: Currently codegen for components supposts stringish. I add it also for components. It fallbacks to StringTypeAnnotation (like in codegen for components).

Reviewed By: rickhanlonii

Differential Revision: D16284381

fbshipit-source-id: 8f03cb79d7e2e1dabbdf4f9353d18dd1daf739fd
2019-07-17 06:21:50 -07:00
Michał OsadnikandFacebook Github Bot d1931344b0 Fix support for objects' types defined in file
Summary: By my mistake previosly it was not poossible to return object defined somewhere in file or return promise containing that object. I changed it to consider value which might be takes from `types` object.

Reviewed By: rickhanlonii

Differential Revision: D16283800

fbshipit-source-id: e9b0ad85b921022732ea0a11db9b58115e87aaa5
2019-07-17 06:21:49 -07:00
Michał OsadnikandFacebook Github Bot ae840287e6 Temporarily get rid of not nullable boolean and number checks
Summary: NativeUIManager and NativeAnimatedModule are using nullable args. I believe we may teporarly don't care about that

Reviewed By: RSNara

Differential Revision: D16282683

fbshipit-source-id: 8071a9446c0e1e437391db17c16f82e131094c81
2019-07-17 06:21:48 -07:00
Michał OsadnikandFacebook Github Bot b4ac9ddcd5 Allow key of objects to be nullable
Summary: In this diff I handle the case where the key of an object may be nullable. To do that, I added a nullable param to the schema.

Reviewed By: rickhanlonii

Differential Revision: D16282081

fbshipit-source-id: cb7668d754e2ff30aef22df582351a512c988016
2019-07-17 06:21:48 -07:00
Michał OsadnikandFacebook Github Bot f7695e0183 Harden the Flow parser to handle more AST formats for commands and props
Summary:
This diff allows for parsing more flexible AST format.

Reusing logic used for methods, I add similar support for props and commands in components. Now it's possible to define separated type for props and commands in another part of the file.

Also, extracted this method to another file for reusing purposes.

Added tests.

Reviewed By: rickhanlonii

Differential Revision: D16221445

fbshipit-source-id: 21553bf5ade66588dd7dc0320d25333260b0ada9
2019-07-16 07:32:35 -07:00
Michał OsadnikandFacebook Github Bot c20eaa5ae9 Change module parser to consider extends instead of default exports
Summary:
Following out internal communication we decided to change logic of current parser to consider types which extend 'TurboModule' instead of looking at default exports.
It also cassed for minor changes in testing logic and updating snapshots.

Reviewed By: rickhanlonii

Differential Revision: D16205707

fbshipit-source-id: c75cd4febf773ba5101e6b60ed1a921773246009
2019-07-12 02:15:29 -07:00
Ben ChengandFacebook Github Bot f83f611f56 Revert D16200939: [codegen] Change module parser to consider extends instead of default exports
Differential Revision:
D16200939

Original commit changeset: a21cbfc46164

fbshipit-source-id: a551d5a9dbc7eef5c67b725e59d712fb323bd01e
2019-07-11 10:05:16 -07:00
Michał OsadnikandFacebook Github Bot cbd4ad43c0 Change module parser to consider extends instead of default exports
Summary:
Following out internal communication we decided to change logic of current parser to consider types which extend 'TurboModule' instead of looking at default exports.

It also cassed for minor changes i n testing logic and updating snapshots.

Reviewed By: rickhanlonii

Differential Revision: D16200939

fbshipit-source-id: a21cbfc461647df2b9210c0eca4c2c95c285dfe1
2019-07-11 09:30:52 -07:00
Michał OsadnikandFacebook Github Bot 4d50f5f4b8 Add support for Float and Int32 in flow parser
Summary: Int32 and Float can be represented on native site in a different after cpp code generation. Inspired by component codegen.

Reviewed By: rickhanlonii

Differential Revision: D16201358

fbshipit-source-id: a5c6c449d69f162ad9cd2a998d57e9c65bc17706
2019-07-11 08:43:19 -07:00
Michał OsadnikandFacebook Github Bot 0b5aa39671 Minor fixes in Flow parser
Summary:
This diff includes minor codestyle changes.
All these fixes was discussed with Rick.

Reviewed By: rickhanlonii

Differential Revision: D16169332

fbshipit-source-id: e561e2f2b116b6fdf8434c3dfc20c3e610d7ecad
2019-07-10 06:47:18 -07:00
Michał OsadnikandFacebook Github Bot dc52f8c2e6 Force property to be optional if value has WithDefault
Summary: It's pointless to handle non optional key if value has withDefaul so I'm adding a rule into parser preventing from such cases

Reviewed By: lunaleaps

Differential Revision: D16166709

fbshipit-source-id: 38cef522b217917a3a4886d857720932f2ebb475
2019-07-09 14:44:43 -07:00
Michał OsadnikandFacebook Github Bot a269c1f6c2 Add support for callback
Summary: This part of writing codegen was straightforward. I've added check for 'FunctionTypeAnnotation' and then reuse exisiting methods' parser for generating schema for callback.

Reviewed By: TheSavior

Differential Revision: D16131213

fbshipit-source-id: 2ec0e241f2174dee3a93857563db0626013d004e
2019-07-08 09:40:21 -07:00
Michał OsadnikandFacebook Github Bot a7664dbaf1 Add support for nullable params
Summary:
I'm not very confident with this part, but actually in existing codegen we wrap param into another object marked as `NullableTypeAnnotion`. It makes logic a little  more complicated. Also it allows for multiple `?` before type which is useless in code generation as well as nullable types inside arrays which also does not have impact on a final code generation.
I suggest adding `nullable` field into param which covers all existing cases (and probably all cases needed).

Reviewed By: TheSavior

Differential Revision: D16121609

fbshipit-source-id: 6e086d4d26bbd0aab3015ec7ecae106ebbaa5a2c
2019-07-08 09:40:21 -07:00
Michał OsadnikandFacebook Github Bot 233c64c675 Add support for complex objects
Summary: Add support for Object reusing mostly the code for arrays

Reviewed By: TheSavior

Differential Revision: D16122314

fbshipit-source-id: c1b201c659e6fdc98bed553fb16280ed5ce9e647
2019-07-08 09:40:20 -07:00
Michał OsadnikandFacebook Github Bot 702489caa8 Add support for basic objects
Summary: This implementation is a bit different than current one since previously object annotation was always wrapped into `GenericTypeAnnotation` object which is not needed in every of current use cases.

Reviewed By: TheSavior

Differential Revision: D16121727

fbshipit-source-id: e0de1852e13c66f459efd7a3bcde449e412d8b95
2019-07-08 09:40:20 -07:00
Michał OsadnikandFacebook Github Bot b848af3b08 Add support for optional methods
Summary:
This diff adds an optional property.

#Facebook
Following this doc: https://our.intern.facebook.com/intern/wiki/React_Native/rctexport-interface-support/?vitals_event=wiki_click_navigation_link
I suppose it's vital to support this property as well. However i don't know if it's really useful, so thus I made a separated diff for it.

Reviewed By: TheSavior

Differential Revision: D16121408

fbshipit-source-id: 15491575e999ee4fcddfd176f52d927789458061
2019-07-08 06:24:19 -07:00
Michał OsadnikandFacebook Github Bot 929c5d7c10 Add support for promises
Summary:
This diff add support for promises. It wraps promise's type into a special type annotation.

#Facebook
Currently the shape of promises parsing is:

```
{
  name: 'getValueWithPromise',
  optional: false,
  typeAnnotation: {
    type: 'FunctionTypeAnnotation',
    params: [
      {
        name: 'error',
        typeAnnotation: {
          type: 'BooleanTypeAnnotation',
        },
      },
    ],
    returnTypeAnnotation: {
      type: 'GenericTypeAnnotation',
      typeId: {
        hasteModuleName: 'NativeSampleTurboModule',
        name: 'Promise',
      },
      typeParameters: [
        {
          type: 'StringTypeAnnotation',
        },
      ],
    },
    returnTypeNameOverride: null,
  },
  rawTypeAnnotation: '(error: boolean) => Promise<string>',
  documentation: null,
};

```

which is a bit unclear for me. I suggest sth way more easier:

```
{
  "modules": {
    "SampleTurboModule": {
      "nativeModules": {
        "SampleTurboModule": {
          "properties": [
            {
              "name": "getValueWithPromise",
              "typeAnnotation": {
                "type": "FunctionTypeAnnotation",
                "returnTypeAnnotation": {
                  "type": "PromiseTypeAnnotation",
                  "resolvingType": {
                    "type": "StringTypeAnnotation"
                  }
                },
                "params": [
                  {
                    "name": "error",
                    "typeAnnotation": {
                      "type": "BooleanTypeAnnotation"
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}
```

However, I'd be happy to see some feedback / other solutions as well!

Reviewed By: TheSavior

Differential Revision: D16130941

fbshipit-source-id: c7dfd3f260b7c3028ce0e6208e96c62bd099ca7b
2019-07-08 06:13:05 -07:00
Michał OsadnikandFacebook Github Bot 690bcdf45e Add suport for array as a param and returning value
Summary: Now `Array<T>` is supported as a returning values or a param of function's definition. Also, Array of Array is allowed.

Reviewed By: TheSavior

Differential Revision: D16121246

fbshipit-source-id: 59c484120c4025a152e3ba8044eecf11dbbea1f7
2019-07-08 04:54:04 -07:00
Michał OsadnikandFacebook Github Bot 59b8ee86c8 Prepare generic mechanism for extracting types from external type definitions
Summary: This diff a adds generic mechansm for extracting types from types' difinitions defined in other part of the file.

Reviewed By: TheSavior

Differential Revision: D16131742

fbshipit-source-id: 006b6980fa9f6a064d5bb8734ba2740b802b6989
2019-07-08 03:23:20 -07:00
Michał OsadnikandFacebook Github Bot e8c5495961 Add support for primitive returning type
Summary:
In this I add support for primitive types as return
- String
- Number
- Boolean
- Any
- Void

Reviewed By: TheSavior

Differential Revision: D16108273

fbshipit-source-id: 2dbd1d5a852a8cf5baf378a73d860492fe2f87cb
2019-07-05 13:15:54 -07:00
Michał OsadnikandFacebook Github Bot 3a5bdc17bb Add support for primitive types parsing for params
Summary:
In this diff I add handling basic primitives:
- Bool
- Number
- String

as params basing on prev schema.

Also, added flow types.

Reviewed By: TheSavior

Differential Revision: D16107737

fbshipit-source-id: 82b1534667e5cfe5b91a3306fdb6d0db44cd3a62
2019-07-05 13:15:53 -07:00
Michał OsadnikandFacebook Github Bot 11ff5670a9 Prepare a skeleton for native modules schema json generating
Summary: It's a skeleton for preparing schema json from native modules. Right not it does nothing, but it should considered as a kind of workplace for further work

Reviewed By: TheSavior, cpojer, RSNara

Differential Revision: D16107216

fbshipit-source-id: 12717d015e7409d980ef16cccd81330fa978b0b1
2019-07-04 05:41:16 -07:00
Michał OsadnikandFacebook Github Bot 61e95e5cbf Force WithDefault not to be an optional value
Summary:
`WithDefault` appears not to be required to be prefixed with `?` because it's option value per se.

Fixed tests, removed `?` where needed, updated snapshots and review them. Added mechanism fro throwing error when `?WithDefault` found. Add tests for it.

Reviewed By: rubennorte

Differential Revision: D16048463

fbshipit-source-id: f55ed7454aacf0b8c42944a9b5c1037ad1b360fe
2019-07-02 03:30:55 -07:00
Michał OsadnikandFacebook Github Bot 75d01075d4 Allow primitivies without default values
Summary:
It's not needed to keep required providing default values even if they are not actually relevant.

Here I add a support for `null`, `0` of `false` instead by default and remove throwing errors if no other default value provided.

Reviewed By: rubennorte

Differential Revision: D16049047

fbshipit-source-id: bc4961af3873190568f2753fc4ec975354896df5
2019-07-01 07:51:25 -07:00
Michał OsadnikandFacebook Github Bot 0f83dfab8e Transform BubbleEvent and DirectEvent into DirectEventHandler and BubblingEventHandler
Summary:
It appears that `(e: BubblingEvent<T>) = mixed` exists only in given context and it's pointless to keep in this way. It could be simplified to `BubblingEventHandler<T>` without any negative consequences and that's the motivation of this diff.

The only tradeoff of this decision is leaving an opportunity to declare Bubbling/Direct event in the top of the file bc then analysing the code becomes much more difficult. However, it's not used anywhere so it's not a problem now and probably any time.

Also, changes the names to `DirectEventHandler` and `BubblingEventHandler` which are more related to current state. The names were updated in many places in code.

Reviewed By: rubennorte

Differential Revision: D16054571

fbshipit-source-id: 741d075eb46b80bac8eb73a6b30fc0b448cb3902
2019-07-01 05:13:53 -07:00
Rick HanlonandFacebook Github Bot 9a84970c35 Add paperTopLevelNameDeprecated
Summary:
This diff adds a way for the codegen to handle view configs with non-standard top event names by adding a `paperTopLevelNameDeprecated` field to events in the schema.

## The problem
The problem this is solving is that Android host components build their own options for event settings in the view config. So instead of enforcing `onChange` to use the top level event name `topChange` like iOS does, Android can use `change` or `forbarChange` or anything the person adding the component wanted at the time:

```
// Expected
topChange: {
  registrationName: 'onChange',
},

// Android
bringBackStargateYouCowards: {
  registrationName: 'onChange',
},
```

This is possible because of the way Android builds these settings
```
// On iOS, notice that there's no option to change the top level name:
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTDirectEventBlock);

// On Android, you provide the top level event name
Override
public Map getExportedCustomDirectEventTypeConstants() {
  return MapBuilder.of(
      "bringBackStargateYouCowards",
      MapBuilder.of("registrationName", "onChange"));
}
```

Since the codegen does not allow us to specify the top level event name (similar to iOS), we don't have a way to customize the names to support android

## The solution
To fix this, we're adding an extra option the event flow types:

```
onBubblingChange: (event: BubblingEvent<Event, 'customBubblingName'>) => void,
onDirectChange: (event: DirectEvent<Event, 'customDirectName'>) => void,
```

These will register **both** top level names in the view config:

```
{
  directEventTypes: {
     // Notice the same registration name is configured for different top level events
    topChange: {
      registrationName: 'onChange',
    },
    bringBackStargateYouCowards: {
      registrationName: 'onChange',
    },
  }
}
```
This means when either `topChange` or `bringBackStargateYouCowards` fires it will call the onChange listener. **This gives us the flexibility to rename the native event name without breaking backwards compatibility.** Old apps will work when `bringBackStargateYouCowards` is fired, and new apps with an update will work when `topChange` fires.

Note: only the correct name will be generated for Fabric so technically we don't even really need to migrate the paper names and this prop can be deleted when paper is gone.

Reviewed By: cpojer

Differential Revision: D16042065

fbshipit-source-id: 40d076b43ffbbfc6c65c3c19de481d922a2add62
2019-06-28 06:50:36 -07:00
Eli WhiteandFacebook Github Bot 365cf96fcb Remove commented out code
Summary: This shouldn't have gotten committed

Reviewed By: rickhanlonii

Differential Revision: D16033668

fbshipit-source-id: b34f9be3525af7b4a81fa7d445769dec20f280d1
2019-06-27 12:18:46 -07:00
Eli WhiteandFacebook Github Bot 9ad60131ba Support parsing View Commands into the schema
Summary: The schema for these view commands is lifted wholesale from the schema for TurboModules: P67239314

Reviewed By: rickhanlonii

Differential Revision: D15943109

fbshipit-source-id: a0ccd4e47067b62970218df6a32527c15868c4a5
2019-06-24 18:54:41 -07:00
Rick HanlonandFacebook Github Bot ff5592cff4 Add paperComponentName and paperComponentNameDeprecated
Summary:
This diff removes an option from the codegen and replaces it with two new options

Removes:
- `isDeprecatedPaperComponentNameRCT`

Adds:
- `paperComponentName`: a better version of the removed option that allows more than just adding RCT
- `paperComponentNameDeprecated`: a new option that allows migrating native code to a new name

```
  // Use for components with no current paper rename in progress
  // Does not check for new name
  paperComponentName?: string,

  // Use for components currently being renamed in paper
  // Will use new name if it is available and fallback to this name
  paperComponentNameDeprecated?: string,
```

For example, Slider uses `paperComponentName: 'RCTSlider'` because it has a different name in fabric but is not currently being migrated to a new name. Because of other work in progress, we don't want to use UIManager check if we don't need to

Reviewed By: shergin

Differential Revision: D15857629

fbshipit-source-id: ca0d3b7dc4a75e00d136ae1f5c84f7423960399d
2019-06-19 09:56:04 -07:00
Rick HanlonandFacebook Github Bot 2deb39b8f6 Add support for enum event arguments
Summary:
This diff adds codegen support for event arguments such as:

```
type Event = $ReadOnly<{|
    orientation: ('portrait' | 'landscape'),
|}>;
```

Facebook
 #noautofix

Reviewed By: shergin

Differential Revision: D15769046

fbshipit-source-id: b2ad8d044b06c2394a9aa75a198ea504672cde68
2019-06-18 06:32:31 -07:00
Cameron BourkeandFacebook Github Bot be07435e6a Allow type exports from the typed native component
Summary:
## Context
At the moment, the codegen process does not expect any types defined in a native component (*NativeComponent.js) to be exported. For example, the `NativeProps` type may be defined as:

```
// RCTSegmentedControlNativeComponent.js

type NativeProps = $ReadOnly<{|
   ...
   onChange?: ?(event: BubblingEvent<Event>) => mixed,
|}>;
```

However, it would be helpful to be able to reuse `NativeProps` in the user facing component:

```
// SegmentedControlIOS.js

type Props = $ReadOnly<{|
   ...NativeProps
  onValueChange?: ?(value: number) => mixed,
|}>;
```

## Changes
- updates the `getTypes` function to unwrap the type declaration inside exported declarations
- add test to verify that exported types are parsed as expected

Reviewed By: rickhanlonii

Differential Revision: D15851693

fbshipit-source-id: a9cd375c69cbb8fe9a38be3d2a681227444fb33d
2019-06-17 09:05:09 -07:00
Rubén NorteandFacebook Github Bot e371978539 Add support for the Stringish type
Summary: `Stringish` is commonly used in components to accept either strings or values coming from Fbt tags. The codegen should support them as they can be used transparently as strings.

Reviewed By: rickhanlonii

Differential Revision: D15821882

fbshipit-source-id: fb94f702d82820677c5a737325b7b46ff4c88151
2019-06-14 06:30:11 -07:00
Rick HanlonandFacebook Github Bot c2824dd426 Add schema support for prop array enums
Summary:
This diff adds codegen support for flow types such as:

```
type ModuleProps = $ReadOnly<{|
  size: $ReadOnlyArray<('small', 'large')>
|}>
```

These array enums are codegen'd as bitmaps in c++

Reviewed By: sammy-SC

Differential Revision: D15766763

fbshipit-source-id: 8c55303fb3a0ab151eae2b441119ab078e2c5d3d
2019-06-12 08:10:35 -07:00
Rick HanlonandFacebook Github Bot 0f7bf518ce Add support for WithDefault<string, null>
Summary:
This diff adds support for:

```
propName: WithDefault<string, null>,
```

It will throw if null is used for any other type like boolean

Reviewed By: TheSavior, cpojer

Differential Revision: D15748556

fbshipit-source-id: 925457ca1739bfad08e4776ecb47c0beb3acacf5
2019-06-11 06:33:47 -07:00
Rick HanlonandFacebook Github Bot 504fc0c7d0 Update flow parser to use codegenNativeComponent
Summary:
This diff updated the codegen flow types syntax replacing:

```
type Options = {
  isDeprecatedPaperComponentNameRCT: true,
};

type ActivityIndicatorNativeType = CodegenNativeComponent<
  'ActivityIndicatorView',
  NativeProps,
  Options,
>;

module.exports = ((requireNativeComponent(
  'RCTActivityIndicatorView',
): any): ActivityIndicatorNativeType);
```
with:

```
export default codegenNativeComponent<NativeProps>('ActivityIndicatorView', {
  isDeprecatedPaperComponentNameRCT: true,
});
```

This is from Tim's comment in the [View Config Codegen Quip](https://fb.quip.com/jR2aASHad4Se):

> What it CodegenNativeComponent were instead `NativeComponent.fromFlow<T>('…')` that returned `'...'`?
>And the Babel plugin swapped it for NativeComponent.fromSchema('...', {…}) which would both register and return '...'?

I went with `codegenNativeComponent` because it has nice parity with `requireNativeComponent`

I also didn't update the babel output here (we can update that whenever) because I think `registerGeneratedViewConfig` is more clear for what it's doing

Reviewed By: cpojer

Differential Revision: D15602077

fbshipit-source-id: 2d24dc32136ba6d31724f8c929b51417ba625a58
2019-06-07 12:31:36 -07:00
Rick HanlonandFacebook Github Bot efec97f2be Add view config babel plugin
Summary:
This diff adds a babel plugin for the generated view configs which will inline them in the file instead of needing to check the view configs in (fb only)

The way it works is:
- babel reads the code
- looks for type alias `CodegenNativeComponent` in `*NativeComponet.js` files
- run the flow parser on the file source to create a schema
- run the schema into codegen to get the view config source code
- inject the generated source code back into the NativeComponent.js file
- remove the original export
- profit

After this diff we will remove the `js1 build viewconfigs` command and the checked-in NativeViewConfig.js files

Note: since this plugin is not published to open source, for now OSS will continue using the `requireNativeComponent` function

Reviewed By: cpojer

Differential Revision: D15516062

fbshipit-source-id: a8efb077773e04fd9753a7036682eeaae9175e09
2019-06-07 12:31:36 -07:00
Rick HanlonandFacebook Github Bot ebb8caa4df Add handling for ColorArray
Summary: This diff adds support for ColorArrayValue in the flow parser

Reviewed By: cpojer

Differential Revision: D15502923

fbshipit-source-id: 6a906b6d609168378fabeb49d0080de011a34d78
2019-06-03 07:21:20 -07:00
Rick HanlonandFacebook Github Bot 057ea6a5c7 Add flow parser
Summary:
This diff initializes the codegen flow parser using a proposal for some new syntaxes in flow file to handle missing  information like:

- Float vs Int32
- Bubbling Events vs Direct Events
- Default props
- Codegen options
- Specifying the component name

For a deep dive on the proposal see:  https://fb.quip.com/kPYJAjCHxlgO

Note: there are still some todos to follow up with:
  - Array props
  - Enum props
  - Object event arguments

Note also: the parser code is a little rough, I didn't want spend too much time cleaning it up before we agreed on the format

[General][Added] Add codegen flow parser

Reviewed By: cpojer

Differential Revision: D15417733

fbshipit-source-id: dd80887c0b2ac46fdc3da203214775facd204e28
2019-05-24 09:21:26 -07:00
Rick HanlonandFacebook Github Bot 9e97f71579 Organize files
Summary:
This diff reorganizes some of the code in react-native-codegen as requested in T44120025

There are two new dirs: `scr/cli` and `src/parsers`

```
buck_tests/
src/
  cli/
  generators/
  parsers/
```

We moved anything cli-ish from `buck_tests` to the `src/cli` directory:
```
src/
  cli/
    combine/
      combine_js_to_schema.sh
      combine_js_to_schema-cli.js
      combine_js_to_schema.js
    viewconfigs/
      generate-view-configs-cli.js
      generate-view-configs.js
      generate-view-configs.sh
```

And we created a new `src/parsers` directory that will contain the flow parser and the current schema parser:

```
src/
  parsers/
    flow/
      index.js
    schema/
      index.js
```

This should organize the code a little better and make it easier to contribute 👍

Reviewed By: cpojer

Differential Revision: D15414264

fbshipit-source-id: 376af2e91def033855f6ed72a9a9cc4369c33c7d
2019-05-22 06:02:03 -07:00