Commit Graph

78 Commits

Author SHA1 Message Date
Pascal Hartig
dde68356eb Upgrade Babel
Summary:
Just minor version bumps so this doesn't have any noticeable effects.
Doing some cleanups after danielbuechele pointed out that it's important
for us to stay close to the upstream releases in the last team meeting.

Reviewed By: jknoxville

Differential Revision: D14665264

fbshipit-source-id: 91efb0663693823f394284457550716f22c40938
2019-03-28 08:36:13 -07:00
Pascal Hartig
fd6cab2a7b Launcher cycle detection
Summary:
Flipper Electron delegates to the Launcher if it is found right on startup to fetch the most recent/compatible version of Flipper. The Launcher then opens the downloaded app with a `--no-launcher` option to avoid bouncing back and forth between the Electron app and the Launcher.

This depends on the argument processing working unchanged. In the past this has been somewhat difficult to guarantee as this doesn't happen in one place and dev/prod builds have handled arguments different due to Electron weirdness (requiring a `--` passed in, for instance).

If anything here goes wrong, we end up in a very nasty scenario where the launcher and the Electron app rapidly open and close, making it nearly impossible for users to escape that vicious cycle. `pkill -f Flipper` being the best option, if you can focus a terminal for long enough.

In order to avoid this from ever happening in the future, this introduces a quick check for the last startup is written with a timestamp and if this is less than 5s in the past, we will skip delegating to the Launcher altogether, keeping the current instance running.

Reviewed By: jknoxville

Differential Revision: D14598136

fbshipit-source-id: b3335ce7ec7dc3e5e014d459db31df4c8a774fc6
2019-03-25 11:36:19 -07:00
Pascal Hartig
ec42fd62ac Wire up --file/--url on Flipper startup
Summary:
When passing --file or --url explicitly on startup, they should
be used in the same way that event handlers are used.

Reviewed By: jknoxville

Differential Revision: D14598688

fbshipit-source-id: 07179227da3b6c754a4d3a9e15342474e39d72b7
2019-03-25 11:31:24 -07:00
Pascal Hartig
759329bbc3 Pass URL and file arguments to launcher
Summary:
Changes where we delegate to the launcher to a later point so we can successfully intercept file open events and custom URI events.

There's more information in Phase 1 in this paragraph of the doc: https://fb.quip.com/tpqnAbxnJw1w#UNZACAnVVGs

Reviewed By: danielbuechele

Differential Revision: D14563585

fbshipit-source-id: a8757a6072386e56102f15b0668456369a44aad7
2019-03-22 12:18:10 -07:00
Pascal Hartig
939cc531e2 Fix revision bundling
Summary:
This fixes headless not terminating due to the `package.json` not being readable.
I instead write this to the `global` object in the same way that the version is
set.

Reviewed By: jknoxville

Differential Revision: D14579316

fbshipit-source-id: 238afe912366c423552305e120088f4abac4c20b
2019-03-22 10:41:01 -07:00
Pascal Hartig
3b53aff55c Add --file option
Summary:
Positional arguments with yargs are a mess, so I'm adding a `--file` instead.
This can then be used to pass parameters on through the launcher.

Reviewed By: danielbuechele

Differential Revision: D14525320

fbshipit-source-id: f04ebed85b6eb9e3c82e76736695d41e7bafb301
2019-03-20 05:30:59 -07:00
Daniel Büchele
79124891a9 url handler downloads
Summary:
Adding support for downloading archived Flipper data using a URL handler.
A URL looks like `flipper://import/?url=` and will download the file specified in the url param. While downloading the file, a spinner is shown in the app's titlebar.

Reviewed By: jknoxville

Differential Revision: D14262763

fbshipit-source-id: 6538fc78c07a48cef7b71b3f7bdbcb712d054593
2019-03-01 04:30:22 -08:00
Daniel Büchele
ffa586dd49 adding keytar native module
Summary:
`keytar` is developped by the Nuclide team and allows cross-platform access to the system's keychain. As `keytar` has a native dependency, we need to make sure Metro doesn't try to bundle it as part of our JS bundle. We are adding another rule to our electron-transform, to not bundle `.node` files (which are native node modules).

Secondly, we need to make sure, the native module is compiled for the correct version of node.js. Usually native modules are compiled for the node version that is running on the system it is installed on. However, we need to make sure it is compiled with the node version that is bundled with electron. That's exactly what `electron-rebuild` does: It recompiles all native modules with the electron's node version.

More on native modules: https://electronjs.org/docs/tutorial/using-native-node-modules

Reviewed By: jknoxville

Differential Revision: D14224402

fbshipit-source-id: 6414a53391a861a23a5d95bf6f18cd0058d9178f
2019-02-28 07:28:25 -08:00
Daniel Büchele
13f7444013 electron update
Summary:
Started with upgrading electron from 3.0.0 to 4.0.5. This required a bunch of subsequent updates:
* upgrading `electron-builder` to latest version, because the old version couldn't build electron 4 apps.
  * `appDir` is deprecated in builder config, `projectDir` is used instead, which we already had set, so its fine to just remove this ([see GitHub commit](a5e457163e)).
* upgrading `jest-runner/electron` because the old version couldn't run electron 4 tests.
  * upgrading our custom dependency resolution to use electron 4.0.5, because the test runner still resolves to 2.0.8 ([see GitHub issue](https://github.com/facebook-atom/jest-electron-runner/issues/31)).
* updating `sandcastle.sh` to use the new cache files from D14131344.
* removing `package-lock.json` as is was causing warnings. We use `yarn` and `yarn.lock` anyways. This file must have been committed by accident.
* updating our check to only run one version of Flipper at a time to use the new electron API `app.requestSingleInstanceLock` as the old one was removed in electron 4.
* updating the snapshot test that checks App rendering, which changed a little due to the electron upgrade.
* upgrading flow-type definitions to `electron-v4.0.5.js` generated by [electron-flowtype-definitions](https://github.com/danielbuechele/electron-flowtype-definitions).

**PS: Best new feature in Electron 4: Copy&paste working in dev tools**

Reviewed By: jknoxville

Differential Revision: D14131360

fbshipit-source-id: d7ed9643875629a1fa1860bb61b11dd0c64112ab
2019-02-21 02:46:12 -08:00
Daniel Büchele
6ada04bc38 ignore flipper-public/dist folder in build
Summary:
Builds in flipper-public are failing, because duplicate imports: https://our.intern.facebook.com/intern/sandcastle/job/22517998213713260

That's most likely because the `flipper-public` is not blacklisted in metro, so let's add it!

Reviewed By: passy

Differential Revision: D14134423

fbshipit-source-id: 52f87196957c8578b8ac7f578efa74e3c13fe1bb
2019-02-20 06:58:54 -08:00
Daniel Büchele
517262bbf2 fix version number
Summary: The electron stub is used by the headless version of Flipper. For that reason, the version number was always `1`. The headless version has a the actual version written to a global variable. So let's use it here.

Reviewed By: passy

Differential Revision: D14149692

fbshipit-source-id: c4781987fd3201e67897eaf31627b0bb2970ffcb
2019-02-20 06:42:21 -08:00
Pascal Hartig
e53f8fa98d Provide clearer message about launcher delegation (#373)
Summary:
To make it more obvious how to disable this if unwanted (e.g. when
testing local builds).
Pull Request resolved: https://github.com/facebook/flipper/pull/373

Reviewed By: jknoxville

Differential Revision: D14130771

Pulled By: passy

fbshipit-source-id: 82c83c1ad14737c8c7791de71a1ee23fcea5ec18
2019-02-19 03:27:31 -08:00
Daniel Büchele
8d134ba89e disable babel cache
Summary: as per title. see explanation in code comment

Reviewed By: jknoxville

Differential Revision: D14125820

fbshipit-source-id: 9b8e31214a65a184397852544cebd7b69ea0aadb
2019-02-18 12:49:34 -08:00
Daniel Büchele
c6752110cf watch recursive
Summary: Plugin files in subfolders were not watched. Adding recursive flag to reload plugins, even when there are changes in any of the plugin's subdirectories.

Reviewed By: jknoxville

Differential Revision: D14100394

fbshipit-source-id: 2a0b5e35df4bbbfe6cf8a0fafd5271222d99a46c
2019-02-15 06:31:31 -08:00
Pascal Hartig
c0b5f10693 Add --launcher-msg option to pass to desktop app
Summary:
Allows the launcher to provide messages to the user. Currently, in the form
of the red notification bar at the bottom. This is just meant as a temporary measure
during the alpha to have some clearly noticeable way of getting the user's attention.

I consider removing this a blocker for the release as this mechanism is not well
suited for this in many ways.

The current use case for this is providing a warning if a cached version is used
instead of the requested one, e.g. "Could not fetch requested Flipper version 'deadbeef', using cached version instead."

Reviewed By: jknoxville, priteshrnandgaonkar

Differential Revision: D14073687

fbshipit-source-id: 85630347027063103315eeb1286731fe2478e261
2019-02-14 06:02:44 -08:00
Pascal Hartig
a41d8eb4f8 Delegate to launcher app on startup
Summary:
For the production version, if the Launcher is installed and no `--no-launcher` (note the double-negation) is supplied, then
let the launcher start the app instead.

The launcher will pass the `--no-launcher` option back to prevent this from looping.

Reviewed By: jknoxville

Differential Revision: D14066620

fbshipit-source-id: 27d305efac36005e5e1082076829f10ef14aba0d
2019-02-14 02:33:06 -08:00
Pascal Hartig
2b9e3c54c6 Set up --no-launcher flag
Summary: For future use to disable launcher loops.

Reviewed By: jknoxville

Differential Revision: D13979653

fbshipit-source-id: db56f7d71d7a4d1322cb36622313dbad4307396d
2019-02-14 02:33:06 -08:00
Pritesh Nandgaonkar
029377a849 Change the export file extension type
Summary: This diff imports and exports data in a `.flipper` file extension. This diff also adds the support to open flipper app by double clicking on the `.flipper` file.

Reviewed By: danielbuechele

Differential Revision: D14042846

fbshipit-source-id: 17e6b55bf2796d9abdf985411fce799600f7792b
2019-02-12 06:48:06 -08:00
Pascal Hartig
08e74e617b Polyfill fetch() for tests
Summary: Per title. Required as Scribe is now being used for device tests.

Reviewed By: jknoxville, danielbuechele

Differential Revision: D13971892

fbshipit-source-id: 2df36d44d4e45a579cc9cca0d4cad9105ba8a383
2019-02-06 16:33:24 -08:00
Pascal Hartig
719dd65340 Warn when console.error is used in tests
Summary:
It's a bit hacky but apparently the recommended solution:
https://stackoverflow.com/questions/28615293/is-there-a-jest-config-that-will-fail-tests-on-console-warn

This will bail when a call to `console.error` is used in a test.
If you *need to* use console.error in a test, then mock it.

This will likely not pass yet, but let's fix all failures and then land it.

Reviewed By: danielbuechele

Differential Revision: D13898383

fbshipit-source-id: 0ca222a07433a9a311dc6bdf0d264342a59208be
2019-02-06 08:51:47 -08:00
Daniel Büchele
e78bd57514 build headless
Summary:
- create a zip-file when building the headless version of Flipper
- restore pkg cache in Sandcastle from pantri
- run build script in sandcastle.

Changes need to go together with D13942919

Reviewed By: passy

Differential Revision: D13942701

fbshipit-source-id: caac7d6cda99fec2a6836c652957ff609a0bf8bb
2019-02-05 11:35:52 -08:00
Pascal Hartig
259ae35284 Fix ESLint issues
Summary: Accepted the Phabricator suggestions but looks like they weren't actually applied ...

Reviewed By: danielbuechele

Differential Revision: D13958095

fbshipit-source-id: 58f3a374fc76a6e3ebccb87732af0abd0ccd52f8
2019-02-05 09:29:16 -08:00
Pascal Hartig
74a726aaf9 Use yargs for non-headless Flipper args parsing
Summary:
This seems like a better approach than ad-hoc lookup in
`electron.remove.argv`. Left a note to a task to provide
a better interface to this.

I also need this in order to ensure we're starting
Flipper through the launcher which needs to happen
before we start the Electron runtime.

Reviewed By: jknoxville

Differential Revision: D13881355

fbshipit-source-id: 69c70d71035a47084f789ddb4dc969b45ba4648b
2019-02-05 04:49:38 -08:00
Pascal Hartig
dc412ce0bc Replace ad-hoc home dir expansion with package
Summary:
Instead of replacing the tilde with home-dirs on an incomplete, ad-hoc
basis, let's use a package for this. It also supports `~USER` resolution
which someone might reasonbly expect to work if `~/DIR` is working.

Reviewed By: jknoxville

Differential Revision: D13940956

fbshipit-source-id: 5bfa9b8b2540fed8c05c856ff736e48e925f985d
2019-02-04 04:42:18 -08:00
Pascal Hartig
ce80e03e8f Add expand-tilde package
Summary:
Just splitting the diff adding the dep from using it
because this is always quite noisy.

Reviewed By: jknoxville

Differential Revision: D13940957

fbshipit-source-id: b31a953a7ebdce9a6611c47ee007c051cdcac147
2019-02-04 04:42:18 -08:00
Pascal Hartig
09a93cd9e6 Upgrading flow and fixing lint errors
Summary:
Upgrading to flow 0.91, fixing a bunch of `$FloxFixMe`s that were introduced by upgrading to 0.86.
Also fixing some linting issues.

Reviewed By: priteshrnandgaonkar

Differential Revision: D13900794

fbshipit-source-id: 5d0a1b62371f3b5d34b909bae0876583acb6f977
2019-02-01 06:51:01 -08:00
Daniel Büchele
500007ccca use perf_hooks
Summary:
We were using `window.performance` to measure performance. This was because the equivalent node.js API `perf_hooks` wasn't available in the electron version we were using back then.
However, `perf_hooks` has landed in electron meanwhile, so I am moving to this API, as it works for the headless version and jest tests, too.

This allows us to delete the babel transform that was used for node-based tests, where the browser API was replaced with the node API

Reviewed By: jknoxville

Differential Revision: D13860133

fbshipit-source-id: cf1395004fac046dd55751ff465af494173b2cbf
2019-01-29 09:32:05 -08:00
Daniel Büchele
771be72b3f remove window dependency
Summary:
Fixes required to be able to run Flipper in node.js:
* Adds checks if the `window`-object exists before using it, to allow running in node.
* Imports from within Flipper should directly reference the file they are requiring instead of `import from 'flipper'`. This was done in most of the places. Fixed a few occurrences where this wasn't the case. This is to prevent cyclic dependencies in node.
* shared packages (React, ReactDOM and Flipper) were exposed on the `window` before, changed this to `global` as this works in browser and node.
* Adds some missing methods to our electron stubs (used for testing and headless Flipper)

Reviewed By: passy

Differential Revision: D13786577

fbshipit-source-id: 145d560f1446e7d0bdec2acd8dd54dae983d7b36
2019-01-25 12:19:07 -08:00
Daniel Büchele
7ac6a09af1 build headless version
Summary:
* Adds `build-headless.js` to bundle the app using metro
* the build script replaces the prelude code added by metro with our own to make it work in node. Metro will add an API to add custom prelude code in the next version.
* Pins down metro's dependency of `temp` to `v0.9.0` (instead of `0.8.3`) to be compatible with node 10. (This will be fixed in a metro upgrade)

Reviewed By: passy

Differential Revision: D13786574

fbshipit-source-id: bddb3542c370c068d90a90c4b59337f995e4fa3f
2019-01-25 12:19:07 -08:00
Daniel Büchele
e02d823e5f split setup
Summary:
`static/index.js` is called by Electron's main process, it does the setup required to run Flipper. However, some of this setup is electron specific, other is not. This moves all non-Electron specific code into `setup.js` which later can be called from node, too. All Electron specific stuff is still in `static/index.js`.

On a side note, this remove the renaming from `.sonar` to `.flipper` config folder, as I think most users should have been migrated by now, users that are not yet migrated will lose their settings, which isn't too much of an issue as our settings are very minimal anyways.

Reviewed By: passy

Differential Revision: D13638253

fbshipit-source-id: 22ab2a65ffec87b40bd86899630d582d9dc5d05c
2019-01-25 12:19:07 -08:00
George Zahariev
c6e0517640 Enable Flow Strict Local for 13 files in xplat/sonar
Summary:
First add a Flow Strict config, then enable Flow Strict Local for 13 files in xplat/sonar.

each change can land seperately:
drop-conflicts

Reviewed By: passy

Differential Revision: D13368791

fbshipit-source-id: 5bc1f9d3a179f4b9a554cc8cc629db0fda468a36
2018-12-11 13:49:14 -08:00
Daniel Büchele
f7ddf3b496 Add empty .watchmanconfig
Summary: An empty .watchmanconfig is required inside the application resources for the plugin loading to work. This diffs adds the file to the `static` folder, which is copied to the application ressources.

Reviewed By: jknoxville

Differential Revision: D13376834

fbshipit-source-id: 1b34a89c5be6f938a640c79ddb3e9ea784bd2d22
2018-12-07 08:06:07 -08:00
John Knox
40f50d48e3 Add physical iOS support to internal build
Summary: Adds support for physical iOS devices, when the necessary dependencies are present. Unfortunately these aren't open sourced yet so the open source build won't get this feature yet.

Reviewed By: priteshrnandgaonkar

Differential Revision: D13001473

fbshipit-source-id: d8c2bcd53b7972bec676717c8af0112800b918d0
2018-12-03 11:34:53 -08:00
John Knox
54d09aa951 Fix open source yarn start
Summary: The fb-stubs transform is getting applied when it shouldn't. Fix it by only applying it if src/fb exists.

Reviewed By: danielbuechele

Differential Revision: D13236217

fbshipit-source-id: 940def377839d16f34c49504948cb062916a3d6a
2018-11-29 08:50:24 -08:00
John Knox
d9a9439dfa Fix emulator launching bug
Summary:
I was getting the following error when trying to launch an emulator:
`PANIC: Missing emulator engine program for 'x86' CPU.`

It seems like emulator/emulator is more reliable than tools/emulator: https://stackoverflow.com/questions/26483370/android-emulator-error-message-panic-missing-emulator-engine-program-for-x86

So put them both on the path in that order.

Reviewed By: passy

Differential Revision: D13040325

fbshipit-source-id: 11e8b24b2a99e02955128d5fb7c17764b98388fa
2018-11-13 11:18:34 -08:00
Pascal Hartig
3150daf4fa Upgrade Metro to 0.49.0
Summary: Just keeping it up-to-date. Includes a fix for source maps which could be interesting.

Reviewed By: jknoxville

Differential Revision: D13023339

fbshipit-source-id: 4c68029bb3cef408e2a7b28a1cde39f246dc046d
2018-11-12 07:16:24 -08:00
Daniel Büchele
8cb715bb3a adding actions to notifications
Summary: This diff adds action buttons to the notifications. Notifications with actions can only be sent from the main process. This is why we need to send a message to the main process which then shows the notification. The action callbacks are sent back to the renderer process to handle the action and log the event.

Reviewed By: passy

Differential Revision: D12999886

fbshipit-source-id: b415fded3172582fad11d88cabf0cfc5b3b8d4f9
2018-11-12 01:49:48 -08:00
Pascal Hartig
ac6575850e Fail build when plugins don't compile
Summary:
This adds an option to the compilePlugin function that
allows specifying whether or not to throw an exception
if compiling a plugin fails.

While this seems like a sensible default while development,
it seems like a pretty bad idea when building releases.

Reviewed By: jknoxville

Differential Revision: D12904570

fbshipit-source-id: aee365074af129296a9d493804b959cb9513f9cc
2018-11-04 04:36:09 -08:00
Rafael Oleza
afd3e5e6a2 Bump react-deep-force-update
Summary: This diff should make HMR work again with the latest version of React

Reviewed By: yungsters

Differential Revision: D12900009

fbshipit-source-id: f9d4dad3ccb4e236f0545983534c167c8fcfbf31
2018-11-02 10:34:27 -07:00
Pritesh Nandgaonkar
1dd5a72ab6 Update metro (#311)
Summary:
- [ ] Solve failing JS travis job
Pull Request resolved: https://github.com/facebook/flipper/pull/311

Reviewed By: jknoxville

Differential Revision: D12822934

Pulled By: priteshrnandgaonkar

fbshipit-source-id: 2cc47372a3dde3500119e1e183aa97111cfe7f6a
2018-11-01 04:47:14 -07:00
John Knox
f0262d91f0 Oneworld connectivity test
Summary:
Gets a oneworld device (just android for now), installs an app. Checks it connects and stays connected for 5s.

The app installed is in an array, we just need to add more targets for further tests.

Reviewed By: danielbuechele

Differential Revision: D10231083

fbshipit-source-id: c33fb091c1b7914a33690398a79fd700c445c06c
2018-10-22 11:38:36 -07:00
John Knox
76d40e7ddf Use node's perf_hooks
Summary:
I tried switching Flipper to use the node.js module: https://nodejs.org/api/perf_hooks.html instead of electrons window.performance. But the module couldn't be found.

So instead, I'm just replacing it in the pure node tests.

This means tests without node can work without issues.

Reviewed By: danielbuechele

Differential Revision: D10302114

fbshipit-source-id: b3b8aa5fb350a8246fcdfc2a80cc72daec2448d7
2018-10-22 09:00:38 -07:00
John Knox
87830ff106 Add transform for stubbing electron
Summary:
The idea behind this is to enable tests running in pure node, without electron, because electron requires display drivers and complicated things.

I've been lazy and only added the bare minimum electron api's for the connection test to pass.
It would be awesome to auto generate it properly.

Reviewed By: danielbuechele

Differential Revision: D10238132

fbshipit-source-id: d4a2da2baf5f8964184b532a581c3a75ee33ef06
2018-10-22 09:00:38 -07:00
Pascal Hartig
48f9b350fe Upgrade Metro to 0.48
Summary:
Just to stay up-to-date. No breaking changes affecting us:
https://github.com/facebook/metro/releases/tag/v0.48.0

Also bumping babel-generator to be in line with the others.

Reviewed By: danielbuechele

Differential Revision: D10446300

fbshipit-source-id: b373bc6b1e6e53f2f760730679d1667928002e5f
2018-10-18 14:52:48 -07:00
Daniel Büchele
6d18701d6a disable ASAR
Summary:
Metro's new version using `jest-haste-map` wants to access files inside our ASAR bundle, not using electron's require function. This fails, because it can not read from inside the ASAR bundle. For this reason we are disabeling ASAR for now.

Additionally, we are disabling reloads when a hidden file changes. This is because watchman creates a `.watchman-cookie` which shoudln't triggers a reload. But in general I think it's safe to not reload when hidden files are changed, as they are unlikely to have actual code in them.

Reviewed By: passy

Differential Revision: D10426715

fbshipit-source-id: 6ad9dcf88c62d5b65a9736eff28aadaf89c6af7a
2018-10-18 02:56:17 -07:00
Pritesh Nandgaonkar
ce996ba8af Add listener in the renderer process for deeplink
Summary:
- Set userPrefferedPlugin for external deeplink
- Listen for deeplink in renderer process and navigate accordingly

Reviewed By: passy

Differential Revision: D10339035

fbshipit-source-id: 4de6249a0672f9ce02b0dfb78a4563302c308578
2018-10-17 06:21:01 -07:00
Pritesh Nandgaonkar
4f914a655e Register flipper: scheme for deeplink
Summary: This diff adds a basic setup of deeplink, with this diff whenever the link is entered in the browser the flipper app is opened and the corresponding.

Reviewed By: passy

Differential Revision: D10149797

fbshipit-source-id: ddff3d794aec66f9e878abcf4c81e87dfadca070
2018-10-17 06:21:01 -07:00
Daniel Büchele
8d7774c409 don't minify plugins
Summary: The minifier removed `debugger` statements from the plugins. We don't need to minify the plugins, because we don't care about bundle size, so we can just disable minification for plugins.

Reviewed By: alangenfeld

Differential Revision: D10334694

fbshipit-source-id: 0b3e23db107f960a3dbeb6a79aa24bacca41c230
2018-10-15 03:05:16 -07:00
Daniel Büchele
e86a756e3c remove PortForwarder
Summary: Removing PortForwarderMacApp as it is not used anymore. Before it was used to allow us to debug physical iOS device. However, the support for physical iOS device was removed a while ago for security reasons. The PortForwarder was not in use anymore so it is safe to remove it.

Reviewed By: passy

Differential Revision: D10337888

fbshipit-source-id: 93f508ec524a0fc055141176c06d7e7169d83f16
2018-10-15 03:03:35 -07:00
John Knox
4889f5dc6a Allow plugins to require from /static/
Summary:
Disallowing plugins from requiring anything but flipper or their own package broke lots of plugins at yarn start.
The ones that broke, require from the static directory.
Allowing them for now to unblock people.

Reviewed By: passy

Differential Revision: D10358733

fbshipit-source-id: 37077c806e022a6eb7ecf9bc95a455bf6f9a34d8
2018-10-12 05:48:24 -07:00