├── .editorconfig
├── .eslintrc
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── lerna.json
├── package.json
├── react-progressive-hydration
├── app
│ ├── assets
│ │ ├── hydrate.jpg
│ │ └── hydrate_lg.jpg
│ ├── client.js
│ ├── components
│ │ ├── app.js
│ │ ├── counter.js
│ │ ├── header.js
│ │ ├── hydrator.js
│ │ ├── intro.js
│ │ └── stream.js
│ ├── server.js
│ └── style.css
├── babel.config.js
├── data.json
├── package.json
├── server.js
└── webpack.config.js
├── react-ssr-data
├── app
│ ├── cached-fetch.js
│ ├── client.js
│ ├── comments.js
│ ├── header.js
│ ├── index.js
│ ├── questions.js
│ ├── server.js
│ └── style.css
├── package.json
└── server
│ ├── bundler.js
│ └── index.js
└── react-streaming-ssr
├── app
├── client.js
├── components
│ ├── app.js
│ ├── header.js
│ └── stream.js
├── server.js
└── style.css
├── babel.config.js
├── data.json
├── package.json
├── server.js
└── webpack.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = tab
5 | end_of_line = lf
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 |
10 | [*.md]
11 | trim_trailing_whitespace = false
12 |
13 | [*.json,*.rc,*.yml]
14 | indent_style = space
15 | indent_size = 2
16 | insert_final_newline = false
17 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "developit"
3 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 | package-lock.json
4 | /.env
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to Contribute
2 |
3 | We'd love to accept your patches and contributions to this project. There are
4 | just a few small guidelines you need to follow.
5 |
6 | ## Contributor License Agreement
7 |
8 | Contributions to this project must be accompanied by a Contributor License
9 | Agreement. You (or your employer) retain the copyright to your contribution,
10 | this simply gives us permission to use and redistribute your contributions as
11 | part of the project. Head over to to see
12 | your current agreements on file or to sign a new one.
13 |
14 | You generally only need to submit a CLA once, so if you've already submitted one
15 | (even if it was for a different project), you probably don't need to do it
16 | again.
17 |
18 | ## Code reviews
19 |
20 | All submissions, including submissions by project members, require review. We
21 | use GitHub pull requests for this purpose. Consult
22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
23 | information on using pull requests.
24 |
25 | ## Community Guidelines
26 |
27 | This project follows [Google's Open Source Community
28 | Guidelines](https://opensource.google.com/conduct/).
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright 2019 Google Inc.
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Progressive Rendering: Frameworks Samples
2 |
3 |
4 |
5 | ### Installation
6 |
7 | ```sh
8 | git clone git@github.com:GoogleChromeLabs/progressive-rendering-frameworks-samples.git
9 | cd progressive-rendering-frameworks-samples
10 |
11 | npm install
12 | npm run lerna bootstrap
13 | ```
14 |
15 | ## Run the Progressive Hydration Demo
16 |
17 | ```sh
18 | cd react-progressive-hydration
19 | npm start
20 | ```
21 |
22 | Now check out the demo on http://localhost:2048!
23 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": [
3 | "react-*",
4 | "angular-*",
5 | "vue-*"
6 | ],
7 | "version": "0.0.0"
8 | }
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "progressive-rendering-frameworks-samples",
3 | "version": "0.0.1",
4 | "scripts": {
5 | "lerna": "lerna",
6 | "bench:streaming": "autocannon http://localhost:2048 && autocannon http://localhost:2048/streaming"
7 | },
8 | "license": "Apache-2.0",
9 | "devDependencies": {
10 | "lerna": "^3.13.1"
11 | },
12 | "engines": {
13 | "node": ">=10"
14 | },
15 | "dependencies": {
16 | "autocannon": "^3.2.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/react-progressive-hydration/app/assets/hydrate.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/progressive-rendering-frameworks-samples/82ccd045264753c11966c59bb63dcba76b8b9f5c/react-progressive-hydration/app/assets/hydrate.jpg
--------------------------------------------------------------------------------
/react-progressive-hydration/app/assets/hydrate_lg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/progressive-rendering-frameworks-samples/82ccd045264753c11966c59bb63dcba76b8b9f5c/react-progressive-hydration/app/assets/hydrate_lg.jpg
--------------------------------------------------------------------------------
/react-progressive-hydration/app/client.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './components/app.js';
4 |
5 | ReactDOM.hydrate( , window.approot);
6 |
--------------------------------------------------------------------------------
/react-progressive-hydration/app/components/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Hydrator as ClientHydrator, ServerHydrator } from './hydrator';
3 | import Intro from './intro';
4 | import Header from './header';
5 |
6 | let load = () => import('./stream');
7 | let Hydrator = ClientHydrator;
8 |
9 | if (typeof window === 'undefined') {
10 | Hydrator = ServerHydrator;
11 | load = () => require('./stream');
12 | }
13 |
14 | export default function App() {
15 | return (
16 |
17 |
18 |
19 |
20 |
21 | {/* */}
22 |
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/react-progressive-hydration/app/components/counter.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 |
3 | export default function CounterButton() {
4 | const [count, setCount] = useState(0);
5 |
6 | return setCount(count + 1)}>{count} ;
7 | }
8 |
--------------------------------------------------------------------------------
/react-progressive-hydration/app/components/header.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import Counter from './counter';
3 |
4 | // check if the page is scrolled
5 | const isScrolled = () => typeof window !== 'undefined' && Math.round('scrollY' in window ? window.scrollY : window.pageYOffset) > 0;
6 |
7 | // little helper for global event registration
8 | function useGlobalListener(event, handler) {
9 | useEffect(() => {
10 | addEventListener(event, handler);
11 | return () => removeEventListener(event, handler);
12 | });
13 | }
14 |
15 | export default function Header() {
16 | const [scrolled, setScrolled] = useState(isScrolled);
17 | useGlobalListener('scroll', () => {
18 | setScrolled(isScrolled());
19 | });
20 |
21 | return (
22 |
23 | 🍔
24 | Progressive Hydration
25 |
26 |
27 | );
28 | }
--------------------------------------------------------------------------------
/react-progressive-hydration/app/components/hydrator.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | function interopDefault(mod) {
5 | return mod && mod.default || mod;
6 | }
7 |
8 | export function ServerHydrator({ load, ...props }) {
9 | const Child = interopDefault(load());
10 | return (
11 |
14 | );
15 | }
16 |
17 | export class Hydrator extends React.Component {
18 | shouldComponentUpdate() {
19 | return false;
20 | }
21 |
22 | componentDidMount() {
23 | new IntersectionObserver(async ([entry], obs) => {
24 | if (!entry.isIntersecting) return;
25 | obs.unobserve(this.root);
26 |
27 | const { load, ...props } = this.props;
28 | const Child = interopDefault(await load());
29 | ReactDOM.hydrate( , this.root);
30 | }).observe(this.root);
31 | }
32 |
33 | render() {
34 | return (
35 | this.root = c}
37 | dangerouslySetInnerHTML={{ __html: '' }}
38 | suppressHydrationWarning
39 | />
40 | );
41 | }
42 | }
--------------------------------------------------------------------------------
/react-progressive-hydration/app/components/intro.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default function Intro() {
4 | return (
5 |
6 |
7 |
This is an example of how server-side rendered React can enable progressively hydrated experiences.
8 |
Scroll down. The flash of color you see is an indicator of JavaScript being fetched without any direct change to the UI.
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/react-progressive-hydration/app/components/stream.js:
--------------------------------------------------------------------------------
1 | import React, { useRef, useEffect } from 'react';
2 | import DATA from '../../data.json';
3 |
4 | // function maybeFetch(url, opts) {
5 | // const controller = typeof AbortController!=='undefined' && new AbortController();
6 | // const req = fetch(url, {
7 | // ...opts,
8 | // signal: controller && controller.signal
9 | // });
10 | // req.cancel = () => {
11 | // controller && controller.abort();
12 | // };
13 | // return req;
14 | // }
15 |
16 | // function usePromise(fetcher, props) {
17 | // const v = useMemo(fetcher, props);
18 | // if ('value' in v) return v.value;
19 | // throw v.then(value => { v.value = value; });
20 | // }
21 |
22 | // let r;
23 |
24 | // function getData() {
25 | // let [data, set] = useState();
26 | // let [loading, setLoading] = useState(false);
27 |
28 | // if (data) return data;
29 | // if (loading) return;
30 | // if (typeof window==='undefined') {
31 | // set(data = __non_webpack_require__('../../data.json').map(user => ({
32 | // id: user.login.uuid,
33 | // username: user.login.username,
34 | // name: user.name.first + ' ' + user.name.last
35 | // })));
36 | // }
37 | // else {
38 | // setLoading(true);
39 | // fetch('/api/users').then(r => r.json()).then(data => {
40 | // set(data);
41 | // setLoading(false);
42 | // });
43 | // // r = r || fetch('/api/users').then(r => r.json());
44 | // // if ('value' in r) return r.value;
45 | // // throw (r.then(v => r.value = v));
46 | // }
47 | // }
48 |
49 | // export default function Stream() {
50 | // // let [items, setItems] = useState([]);
51 | // // useEffect(() => {
52 | // // const req = maybeFetch('/api');
53 | // // req.then(r => r.json()).then(setItems);
54 | // // return req.cancel;
55 | // // }, []);
56 |
57 | // const items = DATA.map(user => ({
58 | // id: user.login.uuid,
59 | // username: user.login.username,
60 | // name: user.name.first + ' ' + user.name.last
61 | // }));
62 | // // const items = getData();
63 |
64 | // // if (!items) {
65 | // // return Loading...
;
66 | // // }
67 |
68 | // // let items;
69 | // // if (typeof window==='undefined') {
70 | // // items = __non_webpack_require__('../../data.json').map(user => ({
71 | // // id: user.login.uuid,
72 | // // username: user.login.username
73 | // // }));
74 | // // }
75 | // // else {
76 | // // items = usePromise(async () => console.log('fetching') || await (await fetch('/api')).json());
77 | // // }
78 |
79 | // return (
80 | //
81 | // {items.map((profile, index) =>
82 | //
83 | // )}
84 | //
85 | // );
86 | // }
87 |
88 | export default function Stream() {
89 | const items = DATA.map(user => ({
90 | id: user.login.uuid,
91 | username: user.login.username,
92 | name: user.name.first + ' ' + user.name.last,
93 | avatar: user.picture.medium
94 | }));
95 |
96 | return (
97 |
98 | {items.map(profile =>
99 |
100 | )}
101 |
102 | );
103 | }
104 |
105 |
106 | function Profile({ profile }) {
107 | const base = useRef();
108 | useEffect(() => {
109 | flash(base.current);
110 | }, []);
111 |
112 | return (
113 |
114 |
115 |
116 |
117 |
118 |
119 |
{profile.name}
120 |
{profile.username}
121 |
122 |
123 |
124 | );
125 | }
126 |
127 | /** Turn an element purple and then fade out. */
128 | function flash(element) {
129 | element.style.backgroundColor = '#bd7aff';
130 | requestAnimationFrame(() => {
131 | requestAnimationFrame(() => {
132 | element.style.transition = 'background-color 2s ease';
133 | element.style.backgroundColor = 'transparent';
134 | });
135 | });
136 | }
137 |
--------------------------------------------------------------------------------
/react-progressive-hydration/app/server.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOMServer from 'react-dom/server';
3 | import App from './components/app.js';
4 |
5 | export default async function ssr() {
6 | return ReactDOMServer.renderToNodeStream( );
7 | }
8 |
--------------------------------------------------------------------------------
/react-progressive-hydration/app/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 80px 0 0;
4 | font-family: avenir next, avenir, sans-serif;
5 | background: #282a37;
6 | }
7 |
8 | .header {
9 | position: fixed;
10 | left: 0;
11 | top: 0;
12 | width: 100%;
13 | height: 80px;
14 | display: flex;
15 | box-sizing: border-box;
16 | align-items: center;
17 | justify-content: space-between;
18 | background: #282a37;
19 | box-shadow: 0 0 5px rgba(0,0,0,0.7);
20 | padding: 0 20px;
21 | }
22 |
23 | .intro {
24 | display: flex;
25 | flex-direction: column;
26 | align-items: center;
27 | padding-bottom: 30px;
28 | }
29 |
30 | .intro p {
31 | color: #fff;
32 | font-size: 20px;
33 | padding: 0 50px;
34 | }
35 |
36 | .hero {
37 | height: 60vh;
38 | width: 100%;
39 | background-image: url('/assets/hydrate.jpg');
40 | background-size: cover;
41 | background-position: center;
42 | margin-bottom: 50px;
43 | }
44 |
45 | h1 {
46 | font-size: 38px;
47 | font-weight: normal;
48 | color: #fff;
49 | }
50 |
51 | button {
52 | background: #fff;
53 | padding: 10px;
54 | background: #494c64;
55 | border: 1px solid #181a27;
56 | color: #fff;
57 | font-size: 24px;
58 | font-weight: bold;
59 | width: 2em;
60 | text-align: center;
61 | border-radius: 5px;
62 | cursor: pointer;
63 | }
64 |
65 | .list-group-item {
66 | background: #282a37;
67 | border-bottom: 3px solid #42444f;
68 | display: flex;
69 | align-items: center;
70 | margin-bottom: 10px;
71 | padding: 20px 0;
72 | }
73 |
74 | .list-group-item .name {
75 | color: #fff;
76 | font-size: 20px;
77 | font-weight: 700;
78 | margin-bottom: 2px;
79 | margin-top: 0;
80 | }
81 |
82 | .list-group-item .location {
83 | color: #f1fb8f;
84 | font-size: 16px;
85 | font-weight: 400;
86 | margin: 0;
87 | }
88 |
89 | .list-group-item .avatar {
90 | display: flex;
91 | align-items: center;
92 | justify-content: center;
93 | margin-right: 12px;
94 | }
95 |
96 | .list-group-item .avatar img {
97 | width: 60px;
98 | border-radius: 30px;
99 | border: 1px solid #f0f0f0;
100 | margin-left: 20px;
101 | }
102 |
103 | @media only screen and (max-width: 600px) {
104 | body {
105 | padding-top: 50px;
106 | }
107 |
108 | .header {
109 | height: 50px;
110 | }
111 |
112 | h1 {
113 | font-size: 18px;
114 | }
115 |
116 | .icon {
117 | display: none;
118 | }
119 |
120 | button {
121 | font-size: 14px;
122 | padding: 5px;
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/react-progressive-hydration/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | ['@babel/preset-env', {
4 | useBuiltIns: 'usage',
5 | corejs: 3,
6 | modules: false,
7 | loose: true
8 | }],
9 | '@babel/preset-react'
10 | ],
11 | plugins: [
12 | '@babel/syntax-dynamic-import'
13 | ]
14 | };
15 |
--------------------------------------------------------------------------------
/react-progressive-hydration/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-progressive-hydration",
3 | "version": "0.0.1",
4 | "main": "server.js",
5 | "scripts": {
6 | "dev": "webpack --hot --watch --info-verbosity none & node -r esm server",
7 | "build": "webpack",
8 | "start": "webpack && node -r esm server"
9 | },
10 | "dependencies": {
11 | "@babel/plugin-syntax-dynamic-import": "^7.2.0",
12 | "clean-terminal-webpack-plugin": "^2.0.2",
13 | "esm": "^3.2.22",
14 | "express": "^4.16.4",
15 | "node-fetch": "^2.3.0",
16 | "react": "^16.8.6",
17 | "react-dom": "^16.8.6",
18 | "regenerator-runtime": "^0.13.2",
19 | "size-plugin": "^1.2.0",
20 | "webpack-merge": "^4.2.1",
21 | "webpackbar": "^3.2.0"
22 | },
23 | "devDependencies": {
24 | "@babel/core": "^7.4.4",
25 | "@babel/preset-env": "^7.4.4",
26 | "@babel/preset-react": "^7.0.0",
27 | "babel-loader": "^8.0.5",
28 | "core-js": "^3.0.1",
29 | "webpack": "^4.30.0",
30 | "webpack-cli": "^3.3.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/react-progressive-hydration/server.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import fetch from 'node-fetch';
3 | import express from 'express';
4 | import ssr from './build/ssr/main.js';
5 | import DATA from './data.json';
6 |
7 | global.fetch = function (url, opts) {
8 | if (url[0] == '/') {
9 | let { address, port } = listener.address();
10 | if (address == '::') address = 'localhost';
11 | url = `http://${address}:${port}${url}`;
12 | }
13 | return fetch(url, opts);
14 | };
15 |
16 | const app = express();
17 |
18 | /** API Proxy */
19 | app.get('/api/users', (req, res) => {
20 | res.json(DATA.map(user => ({
21 | id: user.login.uuid,
22 | username: user.login.username,
23 | name: user.name.first + ' ' + user.name.last
24 | })));
25 | });
26 |
27 | /** SSR */
28 | app.get('/', async (request, response) => {
29 | try {
30 | const stream = await ssr({
31 | url: request.url
32 | });
33 | // Wait until data starts flowing to send a 200 OK,
34 | // so errors don't trigger "headers already sent".
35 | stream.on('data', function handleData() {
36 | stream.off('data', handleData);
37 | response.writeHead(200, {
38 | 'content-type': 'text/html',
39 | 'content-transfer-encoding': 'chunked',
40 | 'x-content-type-options': 'nosniff'
41 | });
42 | response.write(``);
43 | response.write(` `);
44 | response.write(``);
45 | response.flushHeaders();
46 | });
47 | await new Promise((resolve, reject) => {
48 | stream.on('error', err => {
49 | stream.unpipe(response);
50 | reject(err);
51 | });
52 | stream.on('end', () => {
53 | response.write('
');
54 | resolve();
55 | });
56 | stream.pipe(response);
57 | });
58 | }
59 | catch (err) {
60 | // @see https://twitter.com/_developit/status/1123041336054177792
61 | response.writeHead(500, {
62 | 'content-type': 'text/pain'
63 | });
64 | response.end(String(err && err.stack || err));
65 | return;
66 | }
67 | });
68 |
69 | app.use('/client.js', (req, res) => {
70 | res.redirect('/build/client.js');
71 | });
72 |
73 | app.get('/favicon.ico', (req, res) => res.end());
74 |
75 | app.use(express.static(path.resolve(__dirname, 'app')));
76 | app.use('/build', express.static(path.resolve(__dirname, 'build')));
77 |
78 | const listener = app.listen(process.env.PORT || 2048, () => {
79 | console.log('Your app is listening on port ' + listener.address().port);
80 | });
81 |
--------------------------------------------------------------------------------
/react-progressive-hydration/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const path = require('path');
3 | const merge = require('webpack-merge');
4 | const WebpackBar = require('webpackbar');
5 | const SizePlugin = require('size-plugin');
6 | const CleanTerminalPlugin = require('clean-terminal-webpack-plugin');
7 |
8 | const baseConfig = {
9 | context: path.resolve(__dirname, 'app'),
10 | devtool: 'cheap-source-map',
11 | mode: 'production',
12 | stats: {
13 | all: false,
14 | warnings: true,
15 | errors: true,
16 | errorDetails: true
17 | },
18 | output: {
19 | filename: 'main.js',
20 | chunkFilename: '[name].[contenthash].js'
21 | },
22 | module: {
23 | rules: [
24 | {
25 | test: /\.jsx?$/,
26 | exclude: /node_modules/,
27 | loader: 'babel-loader',
28 | options: {
29 | generatorOpts: {
30 | retainLines: true,
31 | compact: true,
32 | shouldPrintComment: c => /^#__PURE__$/.test(c)
33 | }
34 | }
35 | }
36 | ]
37 | },
38 | watchOptions: {
39 | ignored: /node_modules/
40 | }
41 | };
42 |
43 | module.exports = (_, env) => [
44 | merge(baseConfig, {
45 | name: 'server',
46 | target: 'node',
47 | entry: './server',
48 | optimization: {
49 | minimize: false
50 | },
51 | output: {
52 | path: path.resolve(__dirname, 'build', 'ssr'),
53 | libraryExport: 'default',
54 | libraryTarget: 'commonjs2'
55 | },
56 | plugins: [
57 | new webpack.DefinePlugin({
58 | 'typeof window': '"undefined"',
59 | 'typeof document': '"undefined"'
60 | }),
61 | new WebpackBar({ name: 'server' })
62 | ]
63 | }),
64 | merge(baseConfig, {
65 | name: 'client',
66 | entry: './client',
67 | output: {
68 | filename: 'client.js',
69 | path: path.resolve(__dirname, 'build'),
70 | publicPath: '/build/'
71 | },
72 | plugins: [
73 | new webpack.DefinePlugin({
74 | 'typeof window': '"object"',
75 | 'typeof document': '"object"'
76 | }),
77 | new CleanTerminalPlugin({ onlyInWatchMode: true }),
78 | new WebpackBar({ name: 'client' }),
79 | new SizePlugin()
80 | ].filter(Boolean)
81 | })
82 | ];
83 |
--------------------------------------------------------------------------------
/react-ssr-data/app/cached-fetch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | export const CACHE = {};
18 |
19 | let restored = false;
20 | function restore() {
21 | restored = true;
22 | const c = typeof document !== 'undefined' && document.querySelector('script[type="text/props"]');
23 | if (c) {
24 | const entries = JSON.parse(c.textContent);
25 | for (let i in entries) {
26 | (CACHE[i] = Promise.resolve(entries[i])).value = entries[i];
27 | }
28 | }
29 | }
30 |
31 | export function getCache(url) {
32 | if (typeof window !== 'undefined' && !restored) restore();
33 | return CACHE[url] && CACHE[url].value;
34 | }
35 |
36 | export default function cachedFetch(url) {
37 | if (typeof window !== 'undefined' && !restored) restore();
38 | let req = CACHE[url];
39 | if (!req) {
40 | req = CACHE[url] = fetch(url).then(r => r.json()).then(value => req.value = value);
41 | }
42 | req.use = withValue;
43 | return req;
44 | }
45 |
46 | function withValue(successCallback, errorCallback) {
47 | if ('value' in this) {
48 | successCallback(this.value);
49 | }
50 | else {
51 | this.then(successCallback, errorCallback);
52 | }
53 | }
54 |
55 | export function collect() {
56 | const keys = Object.keys(CACHE);
57 | return Promise.all(keys.map(c => CACHE[c]))
58 | .then(() => new Promise(r => setTimeout(r, 10)))
59 | .then(() => {
60 | if (Object.keys(CACHE).join() !== keys.join()) {
61 | return collect();
62 | }
63 | const entries = {};
64 | for (let i in CACHE) {
65 | entries[i] = CACHE[i].value;
66 | }
67 | return entries;
68 | });
69 | }
70 |
--------------------------------------------------------------------------------
/react-ssr-data/app/client.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | import React from 'react';
18 | import ReactDOM from 'react-dom';
19 | import JssProvider from 'react-jss/lib/JssProvider';
20 | import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider';
21 | import createGenerateClassName from '@material-ui/core/styles/createGenerateClassName';
22 | import App from './index';
23 | import { collect } from './cached-fetch';
24 |
25 | const generateClassName = createGenerateClassName();
26 |
27 | ReactDOM.hydrate(
28 |
29 |
30 |
31 |
32 | ,
33 | window.approot
34 | );
35 |
36 | collect().then(() => {
37 | requestAnimationFrame(() => {
38 | performance.mark('hydrated');
39 | performance.measure('hydrated', 'navigationStart', 'hydrated');
40 | console.log(`Hydrated: ${performance.getEntriesByName('hydrated')[0].duration | 0}ms`);
41 | });
42 | });
43 |
--------------------------------------------------------------------------------
/react-ssr-data/app/comments.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | import React from 'react';
18 | import cachedFetch from './cached-fetch';
19 |
20 | export default class Comments extends React.Component {
21 | componentWillMount() {
22 | this.update(this.props);
23 | }
24 |
25 | componentWillReceiveProps(nextProps) {
26 | this.update(nextProps);
27 | }
28 |
29 | update(props) {
30 | const url = `/api/2.2/questions/${props.question}/comments?order=desc&sort=creation&site=stackoverflow&filter=!6JW86p(KK2A)N`;
31 | cachedFetch(url).use(data => {
32 | this.setState({ data });
33 | });
34 | }
35 |
36 | render() {
37 | const { data } = this.state || {};
38 |
39 | return (
40 |
41 | {data && data.items.map(item => (
42 |
43 |
44 |
45 |
46 | {item.owner.display_name}
47 |
48 | {new Date(item.creation_date).toLocaleDateString()}
49 |
50 | ))}
51 |
52 | );
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/react-ssr-data/app/header.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import AppBar from '@material-ui/core/AppBar';
3 | import Toolbar from '@material-ui/core/Toolbar';
4 | import Typography from '@material-ui/core/Typography';
5 | import IconButton from '@material-ui/core/IconButton';
6 | import Button from '@material-ui/core/Button';
7 |
8 | export default function Header() {
9 | return (
10 |
11 |
12 |
13 | 🍔
14 |
15 |
16 |
17 | Stack Overthrow
18 |
19 |
20 |
21 |
22 | Deep
23 | Shallow
24 |
25 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/react-ssr-data/app/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | import React from 'react';
18 | import Header from './header';
19 | import Questions from './questions';
20 |
21 | export default function App({ url }) {
22 | return (
23 |
24 |
25 |
26 | SSR:
27 | Deep
28 | Shallow
29 |
30 |
31 |
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/react-ssr-data/app/questions.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | import React from 'react';
18 | import Comments from './comments';
19 | import cachedFetch from './cached-fetch';
20 |
21 | export default class Questions extends React.Component {
22 | componentWillMount() {
23 | this.update(this.props);
24 | }
25 |
26 | componentDidMount() {
27 | requestAnimationFrame(() => {
28 | performance.mark('interactive');
29 | performance.measure('interactive', 'navigationStart', 'interactive');
30 | console.log(`Interactive: ${performance.getEntriesByName('interactive')[0].duration | 0}ms`);
31 | });
32 | }
33 |
34 | componentWillReceiveProps(nextProps) {
35 | this.update(nextProps);
36 | }
37 |
38 | update(props) {
39 | const url = `/api/2.2/questions?order=desc&sort=activity&tagged=${[].concat(props.tags || []).map(encodeURIComponent).join(',')}&site=stackoverflow`;
40 | cachedFetch(url).use(data => {
41 | this.setState({ data });
42 | });
43 | }
44 |
45 | render() {
46 | const { data } = this.state || {};
47 | const renders = (this.renders = (this.renders || 0) + 1);
48 |
49 | return (
50 |
51 |
52 | Rendered on the {typeof window == 'undefined' ? 'server' : 'client'} ({renders} times)
53 |
54 |
55 |
56 | {data && data.items.map((item, index) => (
57 |
58 |
59 |
60 |
61 | {item.owner.display_name}
62 |
63 | {index < 5 && }
64 |
65 | ))}
66 |
67 |
68 | );
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/react-ssr-data/app/server.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | import React from 'react';
18 | import ReactDOMServer from 'react-dom/server';
19 | import { SheetsRegistry } from 'jss';
20 | import JssProvider from 'react-jss/lib/JssProvider';
21 | import { CACHE, collect } from './cached-fetch.js';
22 | import App from './index.js';
23 | import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider';
24 | import createGenerateClassName from '@material-ui/core/styles/createGenerateClassName';
25 |
26 | // 1: only render the first level of component data depenencies
27 | // 2: render the 1st and 2nd (derivative data)
28 | // etc
29 | const MAX_DEPTH = 2;
30 |
31 | function attempt(App, props, maxDepth = MAX_DEPTH, successHintCallback, depth = 0) {
32 | ReactDOMServer.renderToString( );
33 | return collect().then(cache => {
34 | let html = ReactDOMServer.renderToString( );
35 | if (successHintCallback) {
36 | successHintCallback(html);
37 | }
38 | if (++depth < maxDepth && Object.keys(CACHE).length > Object.keys(cache).length) {
39 | return attempt(App, props, maxDepth, null, depth);
40 | }
41 | return cache;
42 | });
43 | }
44 |
45 | export default function ssr(props, maxDepth, successHintCallback) {
46 | const sheetsRegistry = new SheetsRegistry();
47 | const sheetsManager = new Map();
48 | const ServerApp = (props) => {
49 | const generateClassName = createGenerateClassName();
50 | sheetsRegistry.reset();
51 | sheetsManager.clear();
52 | return (
53 |
54 |
55 |
56 |
57 |
58 | );
59 | }
60 |
61 | return attempt(ServerApp, props, maxDepth, successHintCallback).then(cache => {
62 | let html = ReactDOMServer.renderToString( );
63 | if (Object.keys(cache).length > 0) {
64 | html += ``;
65 | }
66 | html = `` + html;
67 | return html;
68 | });
69 | }
70 |
--------------------------------------------------------------------------------
/react-ssr-data/app/style.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | * {
18 | box-sizing: border-box;
19 | }
20 |
21 | html,
22 | body {
23 | margin: 0;
24 | }
25 |
26 | body {
27 | font-family: system-ui, arial, sans-serif;
28 | }
29 |
30 | nav {
31 | display: inline-flex;
32 | background: #eee;
33 | padding: 3px;
34 | align-items: center;
35 | }
36 |
37 | nav a {
38 | padding: 2px;
39 | }
40 |
41 | h1 {
42 | font-size: 120%;
43 | font-style: italic;
44 | color: #373fff;
45 | }
46 |
47 | article {
48 | padding: 10px;
49 | }
50 |
51 | article h4 {
52 | margin: 0;
53 | font-weight: normal;
54 | }
55 |
56 | article h4 a {
57 | color: #373fff;
58 | text-decoration: none;
59 | }
60 |
61 | .author {
62 | display: flex;
63 | margin: 0;
64 | flex-direction: row;
65 | align-items: center;
66 | font-weight: normal;
67 | }
68 |
69 | .author img {
70 | width: 20px;
71 | height: 20px;
72 | border-radius: 50%;
73 | margin: 2px 5px 2px 0;
74 | }
75 |
76 | .comments {
77 | margin: 10px;
78 | font-size: 80%;
79 | }
80 |
--------------------------------------------------------------------------------
/react-ssr-data/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-ssr-data",
3 | "version": "0.0.1",
4 | "main": "server.js",
5 | "scripts": {
6 | "start": "node -r esm server"
7 | },
8 | "dependencies": {
9 | "@babel/plugin-syntax-dynamic-import": "^7.2.0",
10 | "@material-ui/core": "^3.9.3",
11 | "@babel/preset-react": "^7.0.0",
12 | "@babel/preset-env": "^7.4.4",
13 | "@babel/core": "^7.4.4",
14 | "buble": "^0.19.7",
15 | "compression": "^1.7.4",
16 | "esm": "^3.2.22",
17 | "express": "^4.16.4",
18 | "jss": "^9.8.7",
19 | "react-jss": "^8.6.1",
20 | "node-fetch": "^2.3.0",
21 | "react": "^16.8.6",
22 | "react-dom": "^16.8.6",
23 | "rollup": "^1.11.3",
24 | "rollup-plugin-babel": "^4.3.2",
25 | "rollup-plugin-buble": "^0.19.6",
26 | "rollup-plugin-commonjs": "^9.3.1",
27 | "rollup-plugin-node-resolve": "^4.2.3",
28 | "rollup-plugin-replace": "^2.2.0"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/react-ssr-data/server/bundler.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | import { rollup } from 'rollup';
18 | import buble from 'rollup-plugin-buble';
19 | // import babel from 'rollup-plugin-babel';
20 | import replace from 'rollup-plugin-replace';
21 | import nodeResolve from 'rollup-plugin-node-resolve';
22 | import commonjs from 'rollup-plugin-commonjs';
23 |
24 | export function bundle({ entry, cache, format = 'es', nodeModules = true } = {}) {
25 | return rollup({
26 | input: entry,
27 | plugins: [
28 | buble({
29 | exclude: '**/node_modules/**',
30 | transforms: {
31 | asyncAwait: false,
32 | classes: false
33 | }
34 | }),
35 | replace({
36 | 'process.env.NODE_ENV': JSON.stringify('production')
37 | }),
38 | nodeModules && nodeResolve({}),
39 | nodeModules && commonjs({})
40 | ].filter(Boolean),
41 | cache
42 | }).then(result => {
43 | cache = result.cache;
44 | return result.generate({
45 | format,
46 | compact: true,
47 | sourceMap: false
48 | });
49 | }).then(({ output }) => {
50 | const code = output.filter(o => o.isEntry)[0].code;
51 | return { code, cache };
52 | });
53 | }
54 |
--------------------------------------------------------------------------------
/react-ssr-data/server/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | import path from 'path';
18 | import vm from 'vm';
19 | import { bundle } from './bundler';
20 | import fetch from 'node-fetch';
21 | import express from 'express';
22 | import compression from 'compression';
23 |
24 |
25 | const STACK_EXCHANGE_KEY = process.env.STACK_EXCHANGE_KEY;
26 | if (!STACK_EXCHANGE_KEY) {
27 | console.error(`
28 | Error: No Stack Exchange key provided.
29 | Register at https://stackapps.com/apps/oauth/register,
30 | then provide the "Key" value when running:
31 | STACK_EXCHANGE_KEY=abc123 npm start
32 | `);
33 | }
34 |
35 | // Fetch used during SSR that allows requesting from the Express server
36 | function fetchWithLoopback(url, opts) {
37 | if (url[0] == '/') {
38 | let { address, port } = listener.address();
39 | if (address == '::') address = 'localhost';
40 | url = `http://${address}:${port}${url}`;
41 | }
42 | return fetch(url, opts);
43 | }
44 |
45 |
46 | const MIMES = {
47 | js: 'application/javascript',
48 | mjs: 'application/javascript',
49 | css: 'text/css',
50 | html: 'text/html'
51 | };
52 |
53 | const CACHES = new Map();
54 |
55 | const app = express();
56 |
57 | app.use(compression());
58 |
59 | /** SSR */
60 | app.get('/', async (request, response) => {
61 | const file = path.resolve(__dirname, '..', 'app', 'server.js');
62 | const { code, cache } = await bundle({
63 | entry: file,
64 | cache: CACHES.get(file),
65 | format: 'cjs'
66 | })
67 | CACHES.set(file, cache);
68 | const mod = { exports: {} };
69 | try {
70 | vm.runInNewContext(code, {
71 | require,
72 | module: mod,
73 | exports: mod.exports,
74 | setTimeout,
75 | clearTimeout,
76 | fetch: fetchWithLoopback
77 | });
78 | } catch (e) {
79 | console.log('Error running server bundle: ', e);
80 | }
81 | let html;
82 | let sent = false;
83 | const ready = () => {
84 | if (sent) return;
85 | sent = true;
86 | response.writeHead(200);
87 | response.write(
88 | `
89 |
90 |
91 |
92 | `
93 | );
94 | };
95 | try {
96 | const render = mod.exports && mod.exports.default || mod.exports;
97 | html = await render({
98 | url: request.url
99 | }, request.query.depth, ready);
100 | } catch (e) { console.log(e); }
101 | ready();
102 | response.end(`${html}
`);
103 | });
104 |
105 | app.use('/', (req, res, next) => {
106 | const url = req.url.replace(/[^/]+\/\.\.(\/|$)/g, '$1');
107 | const file = path.resolve(__dirname, '..', 'app', url.substring(1));
108 | const ext = (file.match(/\.([a-z0-9]+)$/) || [])[1];
109 |
110 | // only process JS files:
111 | if (ext !== 'js' && ext !== 'mjs') return next();
112 |
113 | const start = Date.now();
114 | const cache = CACHES.get(file);
115 | bundle({ entry: file, cache }).then(({ code, cache }) => {
116 | CACHES.set(file, cache);
117 | res.writeHead(200, {
118 | 'content-type': MIMES[ext],
119 | 'x-bundle-time': Date.now() - start
120 | });
121 | res.end(code);
122 | });
123 | });
124 |
125 | app.use(express.static(path.resolve(__dirname, '..', 'app')));
126 |
127 | app.get('/favicon.ico', (req, res) => res.end());
128 |
129 | /** API Proxy */
130 | app.use('/api', (req, res, next) => {
131 | const url = new URL(req.url, 'https://api.stackexchange.com');
132 | const params = new URLSearchParams(url.search);
133 | params.set('key', STACK_EXCHANGE_KEY);
134 | url.search = params;
135 | const headers = {};
136 | for (let i in req.headers) if (i != 'host' && i != 'cookie') headers[i] = req.headers[i];
137 | fetch(url.href, {
138 | method: req.method,
139 | body: req.body,
140 | headers
141 | }).then(r => {
142 | res.writeHead(r.status, res.headers);
143 | r.body.pipe(res);
144 | }).catch(next);
145 | });
146 |
147 | const listener = app.listen(process.env.PORT || 2048, () => {
148 | console.log('Your app is listening on port ' + listener.address().port);
149 | });
150 |
--------------------------------------------------------------------------------
/react-streaming-ssr/app/client.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './components/app';
4 |
5 | ReactDOM.hydrate( , window.approot);
6 |
--------------------------------------------------------------------------------
/react-streaming-ssr/app/components/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Stream from './stream';
3 | import Header from './header';
4 |
5 | const Suspense = typeof window==='undefined' ? p => p.children : React.Suspense;
6 |
7 | export default function App () {
8 | return (
9 |
10 |
11 | loading
}>
12 | {new Array(100).fill().map(() => )}
13 |
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/react-streaming-ssr/app/components/header.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default function Header() {
4 | return (
5 |
8 | );
9 | }
--------------------------------------------------------------------------------
/react-streaming-ssr/app/components/stream.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | let r;
4 |
5 | function getData() {
6 | if (typeof window==='undefined') {
7 | // during SSR, load data from a file synchronously:
8 | return __non_webpack_require__('../../data.json').map(user => ({
9 | id: user.login.uuid,
10 | username: user.login.username,
11 | name: user.name.first + ' ' + user.name.last
12 | }));
13 | }
14 | else {
15 | // at runtime, request via the API:
16 | r = r || fetch('/api/users').then(r => r.json());
17 | if ('value' in r) return r.value;
18 | // throw a Promise to re-render once available:
19 | throw (r.then(v => r.value = v));
20 | }
21 | }
22 |
23 | export default function Stream() {
24 | const items = getData();
25 |
26 | return (
27 |
28 | {items.map(profile =>
29 |
30 | )}
31 |
32 | );
33 | }
34 |
35 | function Profile({ profile }) {
36 | return (
37 |
38 |
{profile.name}
39 | {profile.username}
40 |
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/react-streaming-ssr/app/server.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOMServer from 'react-dom/server';
3 | import App from './components/app';
4 |
5 | export default async function ssr({ streaming, ...props }) {
6 | if (streaming) {
7 | return ReactDOMServer.renderToNodeStream( );
8 | }
9 | else {
10 | return ReactDOMServer.renderToString( );
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/react-streaming-ssr/app/style.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | margin: 0;
3 | font: 16px/1.3 system-ui,sans-serif;
4 | }
5 |
6 | .header {
7 | background: #eee;
8 | }
9 |
10 | h1 {
11 | font-size: 150%;
12 | color: #555;
13 | }
14 |
15 | .profile {
16 | background: #eee;
17 | padding: 5px;
18 | margin: 5px;
19 | }
20 | .profile h4 {
21 | margin: 0;
22 | }
23 | .profile h5 {
24 | margin: 5px 0 0;
25 | }
26 |
--------------------------------------------------------------------------------
/react-streaming-ssr/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | ['@babel/preset-env', {
4 | useBuiltIns: 'usage',
5 | corejs: 3,
6 | modules: false,
7 | loose: true
8 | }],
9 | '@babel/preset-react'
10 | ]
11 | };
12 |
--------------------------------------------------------------------------------
/react-streaming-ssr/data.json:
--------------------------------------------------------------------------------
1 | [{"gender":"male","name":{"title":"mr","first":"peter","last":"holt"},"location":{"street":"9374 karen dr","city":"cary","state":"alabama","postcode":25967,"coordinates":{"latitude":"6.4163","longitude":"-168.3884"},"timezone":{"offset":"-1:00","description":"Azores, Cape Verde Islands"}},"email":"peter.holt@example.com","login":{"uuid":"c66e6202-b956-4f77-a15e-9c0730df7763","username":"goldentiger659","password":"alatam","salt":"RJvA9BBy","md5":"63a2930a91585b5855e2b3f65e459315","sha1":"f0fe6c968d3466736d1151a07371835e2e6316ee","sha256":"cd518367ab4e6f1c4b5e144fd3d344583cc6db7af57c9ba85ed031f476f3eb40"},"dob":{"date":"1987-05-05T00:15:09Z","age":31},"registered":{"date":"2002-04-29T02:01:28Z","age":16},"phone":"(108)-944-3293","cell":"(203)-300-9236","id":{"name":"SSN","value":"807-74-4308"},"picture":{"large":"https://randomuser.me/api/portraits/men/45.jpg","medium":"https://randomuser.me/api/portraits/med/men/45.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/45.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"savannah","last":"rose"},"location":{"street":"6841 stevens creek blvd","city":"davenport","state":"west virginia","postcode":92609,"coordinates":{"latitude":"89.6220","longitude":"-63.8521"},"timezone":{"offset":"+5:30","description":"Bombay, Calcutta, Madras, New Delhi"}},"email":"savannah.rose@example.com","login":{"uuid":"405601f3-4ad1-4bb7-b60e-2ddc3bac3fe1","username":"orangesnake155","password":"trident","salt":"eSNAj7EX","md5":"70b8682060eea1753ba06a0d96df9f23","sha1":"f261eea6e7dedf248d2d2eff45328e075caabc04","sha256":"97064ca954dad86b7258f8d7e3630a57d14a2a99a1bbc3d6a5730cf75a166b60"},"dob":{"date":"1964-07-30T10:37:37Z","age":54},"registered":{"date":"2018-06-02T11:19:03Z","age":0},"phone":"(562)-728-0376","cell":"(723)-309-0741","id":{"name":"SSN","value":"657-25-1770"},"picture":{"large":"https://randomuser.me/api/portraits/women/79.jpg","medium":"https://randomuser.me/api/portraits/med/women/79.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/79.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"leslie","last":"austin"},"location":{"street":"3409 hickory creek dr","city":"columbus","state":"new mexico","postcode":40281,"coordinates":{"latitude":"39.2661","longitude":"50.8485"},"timezone":{"offset":"+6:00","description":"Almaty, Dhaka, Colombo"}},"email":"leslie.austin@example.com","login":{"uuid":"62f7ce8d-06fd-49a3-b4c1-5c9c3550e0b7","username":"browngorilla470","password":"keller","salt":"AjZbXG3O","md5":"6efe8715d9510f4c5c809098437fab83","sha1":"0884dc38fa5c2ae7e6946e5fe0525a48718aa16c","sha256":"4790e400a08085ce655476523db6561a2f3fd681b9a027b0ea9b7f379f24218d"},"dob":{"date":"1968-10-04T17:01:24Z","age":50},"registered":{"date":"2014-06-10T06:34:30Z","age":4},"phone":"(920)-031-4235","cell":"(682)-375-5244","id":{"name":"SSN","value":"073-47-3416"},"picture":{"large":"https://randomuser.me/api/portraits/men/66.jpg","medium":"https://randomuser.me/api/portraits/med/men/66.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/66.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"carmen","last":"rodriquez"},"location":{"street":"5716 hogan st","city":"santa clara","state":"michigan","postcode":11032,"coordinates":{"latitude":"-61.0681","longitude":"37.2308"},"timezone":{"offset":"-10:00","description":"Hawaii"}},"email":"carmen.rodriquez@example.com","login":{"uuid":"9b381cb0-b390-4c55-b956-2d0c8ea83667","username":"lazyzebra943","password":"defiant","salt":"3y3e1kLW","md5":"f2776213eae1e9d4894fd2145bae7038","sha1":"5b3f13857b7fb132c2ee0e59465a60e16bd42a5d","sha256":"ebf38fa2ff3f9905f33caeb96b9294a0de440eecc8bf53f8dee5f91527b5d2a8"},"dob":{"date":"1990-02-04T06:26:52Z","age":29},"registered":{"date":"2010-01-13T03:53:52Z","age":9},"phone":"(591)-942-9269","cell":"(917)-090-2547","id":{"name":"SSN","value":"408-71-1708"},"picture":{"large":"https://randomuser.me/api/portraits/women/81.jpg","medium":"https://randomuser.me/api/portraits/med/women/81.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/81.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"miriam","last":"willis"},"location":{"street":"5097 e little york rd","city":"tucson","state":"california","postcode":17396,"coordinates":{"latitude":"45.4474","longitude":"57.8593"},"timezone":{"offset":"+4:30","description":"Kabul"}},"email":"miriam.willis@example.com","login":{"uuid":"e4005264-58ad-444c-8846-60c57c672a6b","username":"tinybear794","password":"thegreat","salt":"fNkJRBsw","md5":"59f1962b55c365c40d6a24bf3421676f","sha1":"74939949ee19cd635deea1a159566d1cea39f59e","sha256":"df4b30ba836306f1ed87a65c0bd608d51cfe2c0deb305b49065c24f853ae5190"},"dob":{"date":"1984-07-02T10:17:03Z","age":34},"registered":{"date":"2006-07-28T07:49:14Z","age":12},"phone":"(650)-339-9027","cell":"(919)-235-1560","id":{"name":"SSN","value":"964-66-6924"},"picture":{"large":"https://randomuser.me/api/portraits/women/49.jpg","medium":"https://randomuser.me/api/portraits/med/women/49.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/49.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"elijah","last":"sims"},"location":{"street":"6107 locust rd","city":"fargo","state":"colorado","postcode":47703,"coordinates":{"latitude":"-62.6944","longitude":"101.2222"},"timezone":{"offset":"-6:00","description":"Central Time (US & Canada), Mexico City"}},"email":"elijah.sims@example.com","login":{"uuid":"f196c60e-6e1d-429c-87fe-d7d8f2f74e49","username":"brownladybug752","password":"konyor","salt":"g517B5lj","md5":"d2fa68d5124c58d0765860cd2a00e987","sha1":"fe9e74ae41477741ff2e163c355d49d41cf66107","sha256":"946bd0b767a1f499e4f6c3c45092d127f6ac610be12aa93b0b96a7dd9b68cab7"},"dob":{"date":"1974-10-11T21:02:45Z","age":44},"registered":{"date":"2011-04-06T17:28:50Z","age":8},"phone":"(367)-722-5688","cell":"(922)-906-7127","id":{"name":"SSN","value":"696-86-1229"},"picture":{"large":"https://randomuser.me/api/portraits/men/76.jpg","medium":"https://randomuser.me/api/portraits/med/men/76.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/76.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"darrell","last":"gomez"},"location":{"street":"4325 mcgowen st","city":"temecula","state":"wisconsin","postcode":56984,"coordinates":{"latitude":"81.2396","longitude":"168.5563"},"timezone":{"offset":"+6:00","description":"Almaty, Dhaka, Colombo"}},"email":"darrell.gomez@example.com","login":{"uuid":"2b0f0487-c70d-4b22-b1d0-fbfaa83e111a","username":"beautifulduck810","password":"catfish","salt":"EiVqOJId","md5":"1bdea1228e307e282ec4720860b97637","sha1":"360971031712db52ec9216cca5a93d983ccad4d5","sha256":"3b93d231d5b30276f70d09a6a90065dfeeadb810516f1d3649aeac4ee3251568"},"dob":{"date":"1977-11-05T22:55:55Z","age":41},"registered":{"date":"2015-10-20T09:35:11Z","age":3},"phone":"(770)-279-2459","cell":"(268)-155-7648","id":{"name":"SSN","value":"335-67-8375"},"picture":{"large":"https://randomuser.me/api/portraits/men/31.jpg","medium":"https://randomuser.me/api/portraits/med/men/31.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/31.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"keith","last":"mccoy"},"location":{"street":"3296 locust rd","city":"san antonio","state":"rhode island","postcode":91846,"coordinates":{"latitude":"-59.9173","longitude":"28.1810"},"timezone":{"offset":"-10:00","description":"Hawaii"}},"email":"keith.mccoy@example.com","login":{"uuid":"b745ee0c-c48a-4805-9ff0-3be2f34929a0","username":"angryfrog294","password":"123abc","salt":"FWtJwoN2","md5":"5a654cf05e636228adaf7bba1c6c8bba","sha1":"a14894ab7018c84c1e0732a69b90d212b2605046","sha256":"ae38aff230a2cbf43843e078929d5d4de18e5c1cd2444a1d16f30bcb8409edd4"},"dob":{"date":"1986-01-12T13:28:30Z","age":33},"registered":{"date":"2006-07-31T10:32:14Z","age":12},"phone":"(605)-340-2238","cell":"(158)-236-0717","id":{"name":"SSN","value":"360-43-7632"},"picture":{"large":"https://randomuser.me/api/portraits/men/85.jpg","medium":"https://randomuser.me/api/portraits/med/men/85.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/85.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"marc","last":"kuhn"},"location":{"street":"982 blossom hill rd","city":"el monte","state":"virginia","postcode":74394,"coordinates":{"latitude":"73.7895","longitude":"58.1127"},"timezone":{"offset":"-3:00","description":"Brazil, Buenos Aires, Georgetown"}},"email":"marc.kuhn@example.com","login":{"uuid":"79aaf377-14d3-4974-961e-df7e32837b98","username":"whiteswan859","password":"felicia","salt":"eB9PIigi","md5":"971b0d7daf881cb325f667f351c10432","sha1":"88da4746d657b6cdd72751f481adbe2928f8a119","sha256":"091b0d0daf6c78130a12a1ad014b0daea1c0a2cc01328a222d07ade0e79b4923"},"dob":{"date":"1950-07-25T03:51:32Z","age":68},"registered":{"date":"2008-07-23T19:46:45Z","age":10},"phone":"(984)-721-7219","cell":"(199)-218-9513","id":{"name":"SSN","value":"003-43-7449"},"picture":{"large":"https://randomuser.me/api/portraits/men/34.jpg","medium":"https://randomuser.me/api/portraits/med/men/34.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/34.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"wilma","last":"adams"},"location":{"street":"73 harrison ct","city":"round rock","state":"new hampshire","postcode":17693,"coordinates":{"latitude":"47.9294","longitude":"-46.8024"},"timezone":{"offset":"-12:00","description":"Eniwetok, Kwajalein"}},"email":"wilma.adams@example.com","login":{"uuid":"9bb3389d-df33-4f19-b23c-afaca143fa33","username":"silverpeacock175","password":"grateful","salt":"DdQKc0zQ","md5":"977b496290e29a6a56d0a4b936720e6d","sha1":"3773859005a1fab69c5f8b9740c2a675d2adc60c","sha256":"70f6c9f2177304ada9dd74400c04fdf9edca4c448ae71ad4fb8d3e16a086e85b"},"dob":{"date":"1994-01-12T22:34:29Z","age":25},"registered":{"date":"2008-03-30T19:49:54Z","age":11},"phone":"(336)-695-6705","cell":"(911)-456-6233","id":{"name":"SSN","value":"887-56-8945"},"picture":{"large":"https://randomuser.me/api/portraits/women/4.jpg","medium":"https://randomuser.me/api/portraits/med/women/4.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/4.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"edgar","last":"long"},"location":{"street":"8711 w sherman dr","city":"sterling heights","state":"michigan","postcode":98939,"coordinates":{"latitude":"-34.3057","longitude":"98.8124"},"timezone":{"offset":"+7:00","description":"Bangkok, Hanoi, Jakarta"}},"email":"edgar.long@example.com","login":{"uuid":"67ef872c-4a98-4030-bcad-5cc03cf478f4","username":"silverfrog889","password":"13579","salt":"pmynnp0u","md5":"76fe84d68bf970f6f06885d6415bb42f","sha1":"9ba24a078bdbcd21b74e901720798d9477a01e62","sha256":"ec8656a5a8d6e54f7e45fcf750ec430182ed9282584064c94b8431527b8114ad"},"dob":{"date":"1985-07-15T18:32:09Z","age":33},"registered":{"date":"2015-10-05T17:09:54Z","age":3},"phone":"(437)-611-8407","cell":"(299)-020-2007","id":{"name":"SSN","value":"139-41-5825"},"picture":{"large":"https://randomuser.me/api/portraits/men/4.jpg","medium":"https://randomuser.me/api/portraits/med/men/4.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/4.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"beverly","last":"black"},"location":{"street":"8015 spring st","city":"st. petersburg","state":"illinois","postcode":58164,"coordinates":{"latitude":"20.7613","longitude":"109.1629"},"timezone":{"offset":"-8:00","description":"Pacific Time (US & Canada)"}},"email":"beverly.black@example.com","login":{"uuid":"288bb6d5-68ab-4d6b-8819-9157cce8c495","username":"angrybear341","password":"wingman","salt":"TxwU9LyO","md5":"363d73b4bf5b0140465cf8d5dd68b60c","sha1":"d282dd9947a72eafb21a0ae764f62f67263b1354","sha256":"617543863a3720e47368efc76ab1ee7b3fec0929683fb9190973dece2664771c"},"dob":{"date":"1996-11-17T19:43:38Z","age":22},"registered":{"date":"2009-02-17T03:50:13Z","age":10},"phone":"(641)-662-5953","cell":"(830)-190-4572","id":{"name":"SSN","value":"250-69-6519"},"picture":{"large":"https://randomuser.me/api/portraits/women/5.jpg","medium":"https://randomuser.me/api/portraits/med/women/5.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/5.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"gerald","last":"harper"},"location":{"street":"7570 saddle dr","city":"flint","state":"nevada","postcode":50080,"coordinates":{"latitude":"-49.2296","longitude":"48.3310"},"timezone":{"offset":"-11:00","description":"Midway Island, Samoa"}},"email":"gerald.harper@example.com","login":{"uuid":"d0053c4d-a085-4704-86d3-8e36a1b2c491","username":"heavymeercat536","password":"private1","salt":"PDBEL0bS","md5":"b6e4978049cde483dd553eef67b2c102","sha1":"c5101ae7c0817202bd06830d34d50be11a2a3884","sha256":"db4b794a43f247aded33be28d3d34e3fe45ee801277ed957360dc1a626b54649"},"dob":{"date":"1975-03-15T12:57:49Z","age":44},"registered":{"date":"2013-11-22T20:59:21Z","age":5},"phone":"(000)-422-5923","cell":"(101)-958-6481","id":{"name":"SSN","value":"234-86-7953"},"picture":{"large":"https://randomuser.me/api/portraits/men/91.jpg","medium":"https://randomuser.me/api/portraits/med/men/91.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/91.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"ben","last":"berry"},"location":{"street":"6958 dogwood ave","city":"albuquerque","state":"ohio","postcode":84185,"coordinates":{"latitude":"-2.4741","longitude":"-42.9490"},"timezone":{"offset":"-10:00","description":"Hawaii"}},"email":"ben.berry@example.com","login":{"uuid":"bb5494a8-5104-4eb1-bfa8-2125fdd165ed","username":"silverzebra929","password":"weed","salt":"VF403mUX","md5":"bc16e09bbd75e192d42aba50c7174fc7","sha1":"12589b673b94b823eb8fc4b532378a4c697be673","sha256":"c224e02035c360323ed1244450dd4a1b225a78cc5118f73d930fa1b576c873cc"},"dob":{"date":"1945-09-20T05:17:48Z","age":73},"registered":{"date":"2017-08-08T15:12:08Z","age":1},"phone":"(483)-089-0315","cell":"(880)-170-8621","id":{"name":"SSN","value":"228-74-3700"},"picture":{"large":"https://randomuser.me/api/portraits/men/58.jpg","medium":"https://randomuser.me/api/portraits/med/men/58.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/58.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"marlene","last":"ellis"},"location":{"street":"9762 wycliff ave","city":"aubrey","state":"vermont","postcode":48109,"coordinates":{"latitude":"-14.0429","longitude":"102.9738"},"timezone":{"offset":"-3:30","description":"Newfoundland"}},"email":"marlene.ellis@example.com","login":{"uuid":"32c32e1f-f32e-4f91-8005-75b66f9af030","username":"tinymeercat398","password":"1015","salt":"shQAsjgV","md5":"89151278e316260216e351fe4fe34aca","sha1":"5a5ac4887357f02494b15dc6f26df54f257e18fa","sha256":"87a4ac31cdde18e3b6060f0d20ffcfc02cfbd642ff8c98b1413b595f39064757"},"dob":{"date":"1976-07-21T05:02:41Z","age":42},"registered":{"date":"2015-03-10T21:35:34Z","age":4},"phone":"(708)-290-7589","cell":"(483)-046-9067","id":{"name":"SSN","value":"262-85-8871"},"picture":{"large":"https://randomuser.me/api/portraits/women/83.jpg","medium":"https://randomuser.me/api/portraits/med/women/83.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/83.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"bruce","last":"shaw"},"location":{"street":"191 bruce st","city":"fremont","state":"vermont","postcode":91624,"coordinates":{"latitude":"-88.6971","longitude":"-54.5769"},"timezone":{"offset":"+3:30","description":"Tehran"}},"email":"bruce.shaw@example.com","login":{"uuid":"c9170a90-f6a6-4bb1-a505-599e89b08f23","username":"crazypeacock436","password":"catcher","salt":"w4xZz1Lu","md5":"d1a9d16067934f1f3b935a154e47eae9","sha1":"241d5956cececea5e3b7a8bebafcf82c5f06afa4","sha256":"1ad2e62e5898a1044e5d74d0c0417d0b815e061c71ea14f607d0631e9222add5"},"dob":{"date":"1980-02-19T08:26:03Z","age":39},"registered":{"date":"2013-05-05T17:14:35Z","age":5},"phone":"(405)-993-3336","cell":"(432)-941-1398","id":{"name":"SSN","value":"724-33-2629"},"picture":{"large":"https://randomuser.me/api/portraits/men/8.jpg","medium":"https://randomuser.me/api/portraits/med/men/8.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/8.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"luke","last":"ward"},"location":{"street":"4990 mockingbird hill","city":"fullerton","state":"kentucky","postcode":19987,"coordinates":{"latitude":"-2.3947","longitude":"32.8776"},"timezone":{"offset":"-6:00","description":"Central Time (US & Canada), Mexico City"}},"email":"luke.ward@example.com","login":{"uuid":"a9455deb-8aee-469d-a48c-ded6f336333f","username":"smallmeercat663","password":"bowman","salt":"Pqa6MFiL","md5":"8109a5a6ebd26d3f33cbcbfe13be3cae","sha1":"87d752c3c5ff32132aabb322b591f793f0c01d6e","sha256":"ef16f63a0c3ca40c4caba77f1b971f6031d0da56d7acb81258dc9548969cb86c"},"dob":{"date":"1959-11-22T18:24:54Z","age":59},"registered":{"date":"2013-11-11T07:31:19Z","age":5},"phone":"(996)-371-1796","cell":"(994)-889-9230","id":{"name":"SSN","value":"229-21-9698"},"picture":{"large":"https://randomuser.me/api/portraits/men/90.jpg","medium":"https://randomuser.me/api/portraits/med/men/90.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/90.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"ray","last":"hughes"},"location":{"street":"7606 frances ct","city":"santa clara","state":"mississippi","postcode":25869,"coordinates":{"latitude":"-31.1970","longitude":"-173.1455"},"timezone":{"offset":"+6:00","description":"Almaty, Dhaka, Colombo"}},"email":"ray.hughes@example.com","login":{"uuid":"c5ecd075-c912-4d70-83ee-041410b25f72","username":"bluesnake207","password":"5555555","salt":"uuyoGNp9","md5":"177567c5dfca0ddd04d1016ab4c05a02","sha1":"04024789e00990d8fe54ecaebfa54250b6b1a25a","sha256":"a11a876e5c74a404d2b6bf676bd1463ccb6c5e4c265fc028665864366090edbc"},"dob":{"date":"1975-07-24T09:13:46Z","age":43},"registered":{"date":"2010-08-08T05:55:53Z","age":8},"phone":"(995)-461-8871","cell":"(258)-092-5172","id":{"name":"SSN","value":"595-86-5705"},"picture":{"large":"https://randomuser.me/api/portraits/men/8.jpg","medium":"https://randomuser.me/api/portraits/med/men/8.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/8.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"jerome","last":"may"},"location":{"street":"6409 hamilton ave","city":"moscow","state":"massachusetts","postcode":37875,"coordinates":{"latitude":"17.4409","longitude":"116.0623"},"timezone":{"offset":"+2:00","description":"Kaliningrad, South Africa"}},"email":"jerome.may@example.com","login":{"uuid":"390811a2-ccd4-48b6-9bf9-6af004f60a72","username":"silverleopard846","password":"qweasd","salt":"h9hCFk97","md5":"a866486950e1d3f7d95d0b45518f3499","sha1":"ac9ce1488c4172bc0f01c290e9ea4f997e3d7dd9","sha256":"465d2077491ed2f5873623392f90b7470bdba48cd9769bab03cb0da0fa9765dc"},"dob":{"date":"1982-03-26T21:57:17Z","age":37},"registered":{"date":"2017-04-14T04:15:55Z","age":2},"phone":"(621)-202-9377","cell":"(309)-672-6089","id":{"name":"SSN","value":"893-00-6285"},"picture":{"large":"https://randomuser.me/api/portraits/men/91.jpg","medium":"https://randomuser.me/api/portraits/med/men/91.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/91.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"lewis","last":"hopkins"},"location":{"street":"4610 harrison ct","city":"flowermound","state":"georgia","postcode":11452,"coordinates":{"latitude":"27.3190","longitude":"50.8528"},"timezone":{"offset":"-3:30","description":"Newfoundland"}},"email":"lewis.hopkins@example.com","login":{"uuid":"38e96d50-1e17-49c3-b80a-ea82f35650cb","username":"angrygoose456","password":"13131313","salt":"9vd5rX8i","md5":"85a6567e82d78fddd5eb75e67f7134b8","sha1":"8675f5e5d61dd6e9a80ab92df55b44ea4150b5d7","sha256":"ae1b5c91c25d40042a525a591ed4cbba349599581bf1b5f9e8eaede92d8df5de"},"dob":{"date":"1978-06-07T22:30:22Z","age":40},"registered":{"date":"2002-10-06T04:17:12Z","age":16},"phone":"(019)-924-0620","cell":"(786)-465-8423","id":{"name":"SSN","value":"982-16-9481"},"picture":{"large":"https://randomuser.me/api/portraits/men/31.jpg","medium":"https://randomuser.me/api/portraits/med/men/31.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/31.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"bobbie","last":"ruiz"},"location":{"street":"7728 paddock way","city":"allentown","state":"maine","postcode":16964,"coordinates":{"latitude":"-33.8008","longitude":"17.2275"},"timezone":{"offset":"0:00","description":"Western Europe Time, London, Lisbon, Casablanca"}},"email":"bobbie.ruiz@example.com","login":{"uuid":"7a7779f0-bb79-479b-a000-7438e35211e8","username":"blueladybug787","password":"suan","salt":"Qm91hLPc","md5":"5c687bb4b8adc5eaa6ea36ccb953dc2c","sha1":"d702eb1c63c62775a26016e56a35067b856aae1d","sha256":"4f7dbbd1baf00f7eaa026ef54e2dac3e0ad0360ed89adbd95d338f76006a6c52"},"dob":{"date":"1952-12-23T03:25:35Z","age":66},"registered":{"date":"2017-10-31T01:40:10Z","age":1},"phone":"(868)-159-2612","cell":"(446)-770-6026","id":{"name":"SSN","value":"578-00-9941"},"picture":{"large":"https://randomuser.me/api/portraits/women/46.jpg","medium":"https://randomuser.me/api/portraits/med/women/46.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/46.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"nelson","last":"mendoza"},"location":{"street":"4868 westheimer rd","city":"lakeland","state":"alaska","postcode":63143,"coordinates":{"latitude":"59.4194","longitude":"66.5721"},"timezone":{"offset":"+5:45","description":"Kathmandu"}},"email":"nelson.mendoza@example.com","login":{"uuid":"7d2357da-cf95-4c01-91b2-0adc8efd3ccf","username":"yellowdog139","password":"spawn","salt":"FY7EGsFa","md5":"7224dce24cde3e606ad6e385493c8874","sha1":"ae1e0c209c33b21818c9ae0eb3ebcc884e4408a2","sha256":"c2a900a522a608ed44af81d82d1d63a4948eb61cef486682aebc8ef3d3d00dd0"},"dob":{"date":"1958-12-12T14:29:52Z","age":60},"registered":{"date":"2015-04-16T02:20:05Z","age":4},"phone":"(622)-681-5992","cell":"(058)-615-1214","id":{"name":"SSN","value":"081-90-3345"},"picture":{"large":"https://randomuser.me/api/portraits/men/82.jpg","medium":"https://randomuser.me/api/portraits/med/men/82.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/82.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"bobby","last":"may"},"location":{"street":"5422 thornridge cir","city":"irving","state":"tennessee","postcode":89367,"coordinates":{"latitude":"46.7608","longitude":"170.6006"},"timezone":{"offset":"+5:45","description":"Kathmandu"}},"email":"bobby.may@example.com","login":{"uuid":"e0f97d60-df05-428e-902b-0d93334dc76b","username":"purplepanda950","password":"quantum","salt":"tDMtGS8s","md5":"acc08b50992a105120a092bf6b0140b0","sha1":"5aa279a66d28162231b0c6e2467f344e7baca0cb","sha256":"fddb9d6e216ca5d153d7da992d79f19703332e8bcfc5174ca1fca20529dda92c"},"dob":{"date":"1978-07-20T08:38:51Z","age":40},"registered":{"date":"2003-01-30T08:20:13Z","age":16},"phone":"(245)-758-2144","cell":"(799)-089-2664","id":{"name":"SSN","value":"402-91-7241"},"picture":{"large":"https://randomuser.me/api/portraits/men/35.jpg","medium":"https://randomuser.me/api/portraits/med/men/35.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/35.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"mark","last":"fletcher"},"location":{"street":"2878 prospect rd","city":"lexington","state":"wyoming","postcode":24488,"coordinates":{"latitude":"-77.8018","longitude":"-173.4006"},"timezone":{"offset":"+9:00","description":"Tokyo, Seoul, Osaka, Sapporo, Yakutsk"}},"email":"mark.fletcher@example.com","login":{"uuid":"18a3d5ff-0e64-41a6-821c-0d959cdc0d3f","username":"greenlion201","password":"kuan","salt":"pm7Uw0y5","md5":"12d5bf5285dda3c0f3f106ba2ff3254d","sha1":"3b67512178920482c7c357e0ca5822f3eff72f4f","sha256":"c8314bce7d58c9dd4d1369d6deb857b243b6ad78903e5afd356db469ea93d707"},"dob":{"date":"1977-10-01T20:42:06Z","age":41},"registered":{"date":"2008-09-08T20:51:40Z","age":10},"phone":"(084)-806-5827","cell":"(429)-758-8067","id":{"name":"SSN","value":"682-52-5154"},"picture":{"large":"https://randomuser.me/api/portraits/men/35.jpg","medium":"https://randomuser.me/api/portraits/med/men/35.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/35.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"abigail","last":"watts"},"location":{"street":"1171 ranchview dr","city":"carrollton","state":"idaho","postcode":43969,"coordinates":{"latitude":"-82.7245","longitude":"100.1341"},"timezone":{"offset":"-10:00","description":"Hawaii"}},"email":"abigail.watts@example.com","login":{"uuid":"9cf6d517-af1a-4b4a-8e8d-dc2931d9015e","username":"brownladybug391","password":"daddy1","salt":"lY2dgVPw","md5":"3de4fae71b20a7924606b41ad4f9eb18","sha1":"e00ab8f4812b3da50d9ab67756367e967b003adc","sha256":"003512a783997c138142d1944e6695186a0e586c31854bbe492b39c24eb4d9e5"},"dob":{"date":"1957-07-19T04:26:36Z","age":61},"registered":{"date":"2009-08-10T20:12:46Z","age":9},"phone":"(674)-995-7388","cell":"(287)-706-2561","id":{"name":"SSN","value":"462-80-9067"},"picture":{"large":"https://randomuser.me/api/portraits/women/41.jpg","medium":"https://randomuser.me/api/portraits/med/women/41.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/41.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"sherry","last":"howell"},"location":{"street":"9080 hickory creek dr","city":"las cruces","state":"washington","postcode":84890,"coordinates":{"latitude":"73.2481","longitude":"-47.7862"},"timezone":{"offset":"+11:00","description":"Magadan, Solomon Islands, New Caledonia"}},"email":"sherry.howell@example.com","login":{"uuid":"e6d6d953-4c5a-4a17-98ff-6555a743f732","username":"crazyelephant764","password":"marion","salt":"1yMCfpR3","md5":"f1fbf1ec91ba29d66c7ae07ef56aa446","sha1":"73cf12e764a69318cb3139b6a8262264ca3d323f","sha256":"092910c73c4bcde23f3523cc774f7e683d0d76365d6ebb400fb5ccd8986222d4"},"dob":{"date":"1992-06-04T05:44:14Z","age":26},"registered":{"date":"2015-09-18T11:51:23Z","age":3},"phone":"(778)-295-2581","cell":"(583)-000-3171","id":{"name":"SSN","value":"570-24-3064"},"picture":{"large":"https://randomuser.me/api/portraits/women/38.jpg","medium":"https://randomuser.me/api/portraits/med/women/38.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/38.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"freddie","last":"mills"},"location":{"street":"6579 w dallas st","city":"saint paul","state":"wisconsin","postcode":74378,"coordinates":{"latitude":"-20.9859","longitude":"172.4377"},"timezone":{"offset":"-3:00","description":"Brazil, Buenos Aires, Georgetown"}},"email":"freddie.mills@example.com","login":{"uuid":"dc46554a-4e16-4ae3-b855-1a40e98292c9","username":"orangeduck840","password":"brains","salt":"wSSbTGJ6","md5":"92f3270b8877b24d402e6a6896dfa59b","sha1":"363ed1479f4709fbbc852810474c5b438058a6a2","sha256":"1bc1b5c47fa791e66aca634bc721c6da590e581bbc2ed32dd4dd68fa93e3aac7"},"dob":{"date":"1965-06-12T13:15:04Z","age":53},"registered":{"date":"2014-05-08T00:05:16Z","age":4},"phone":"(045)-870-0319","cell":"(406)-380-9043","id":{"name":"SSN","value":"903-94-6832"},"picture":{"large":"https://randomuser.me/api/portraits/men/26.jpg","medium":"https://randomuser.me/api/portraits/med/men/26.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/26.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"brandy","last":"berry"},"location":{"street":"3634 e sandy lake rd","city":"roanoke","state":"idaho","postcode":51924,"coordinates":{"latitude":"22.6824","longitude":"-76.1231"},"timezone":{"offset":"-9:00","description":"Alaska"}},"email":"brandy.berry@example.com","login":{"uuid":"beffa6c2-2bfa-4fe7-9def-46044f31fafd","username":"smallelephant161","password":"bradley","salt":"B23ZGSVz","md5":"806419497601a7de31fda1d90d59c2fe","sha1":"c3a9499ba373f997d85c4ff30d914672efb5ffef","sha256":"38efe12e066eeb7da3631927e232236d7f15dcc453235ecea51f41abf9e75311"},"dob":{"date":"1948-06-04T07:40:46Z","age":70},"registered":{"date":"2010-09-23T17:07:18Z","age":8},"phone":"(985)-920-6268","cell":"(924)-150-6816","id":{"name":"SSN","value":"384-61-2269"},"picture":{"large":"https://randomuser.me/api/portraits/women/50.jpg","medium":"https://randomuser.me/api/portraits/med/women/50.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/50.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"aaron","last":"kim"},"location":{"street":"9916 mcgowen st","city":"forney","state":"arizona","postcode":35464,"coordinates":{"latitude":"67.1760","longitude":"-117.6479"},"timezone":{"offset":"+3:00","description":"Baghdad, Riyadh, Moscow, St. Petersburg"}},"email":"aaron.kim@example.com","login":{"uuid":"c6cc4c72-5563-48a3-b02d-1981fe87b3ce","username":"tinybear700","password":"basset","salt":"1zfCFFPv","md5":"1f0fa7a976e6168f3539b3a2e34375b1","sha1":"855081fc1bf5a6be3cec36e691686b47cbf6da81","sha256":"a89f9b218492098f39d08e3604bbb5868b6ce8de73a5d5c46bc899d9e7fa3879"},"dob":{"date":"1967-04-09T03:52:07Z","age":52},"registered":{"date":"2016-11-25T22:09:59Z","age":2},"phone":"(083)-795-2826","cell":"(132)-235-7191","id":{"name":"SSN","value":"549-73-7734"},"picture":{"large":"https://randomuser.me/api/portraits/men/59.jpg","medium":"https://randomuser.me/api/portraits/med/men/59.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/59.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"bella","last":"williams"},"location":{"street":"5824 spring st","city":"denton","state":"mississippi","postcode":71325,"coordinates":{"latitude":"51.0574","longitude":"-117.0416"},"timezone":{"offset":"0:00","description":"Western Europe Time, London, Lisbon, Casablanca"}},"email":"bella.williams@example.com","login":{"uuid":"38e0f392-b48e-48e9-8c19-a0798a59641f","username":"yellowmouse549","password":"1977","salt":"lqRfzCxr","md5":"3db53dc3ae139251aa5b340471889563","sha1":"44e1f845c5336260296a4a1b26a4d2812ffa9828","sha256":"c7144a528dc7fdaff22a468dfbbd60235533e2203e4e92d9fb45919a54b6b6c1"},"dob":{"date":"1951-08-13T12:34:51Z","age":67},"registered":{"date":"2008-06-15T01:53:05Z","age":10},"phone":"(241)-237-5991","cell":"(443)-602-2121","id":{"name":"SSN","value":"278-22-9872"},"picture":{"large":"https://randomuser.me/api/portraits/women/69.jpg","medium":"https://randomuser.me/api/portraits/med/women/69.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/69.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"diane","last":"armstrong"},"location":{"street":"9373 w campbell ave","city":"orlando","state":"idaho","postcode":80158,"coordinates":{"latitude":"-68.4166","longitude":"-13.4061"},"timezone":{"offset":"+2:00","description":"Kaliningrad, South Africa"}},"email":"diane.armstrong@example.com","login":{"uuid":"82ffbc8d-bee9-4324-84f5-cb60f9b4a1df","username":"organicfrog944","password":"spider","salt":"fjxue2e8","md5":"6af496679920436df7ce227b50e037e4","sha1":"7c339fe1c9345b2869bb0ea4809245f659711ac0","sha256":"cf9832e468761a60b69d7a453436f7202917f23dfcf1277c5a767b77af6ec268"},"dob":{"date":"1995-11-04T05:20:44Z","age":23},"registered":{"date":"2010-01-02T03:07:20Z","age":9},"phone":"(772)-060-7024","cell":"(834)-426-7552","id":{"name":"SSN","value":"607-74-2012"},"picture":{"large":"https://randomuser.me/api/portraits/women/6.jpg","medium":"https://randomuser.me/api/portraits/med/women/6.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/6.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"allan","last":"howell"},"location":{"street":"3076 rolling green rd","city":"scottsdale","state":"michigan","postcode":37787,"coordinates":{"latitude":"55.8431","longitude":"174.5044"},"timezone":{"offset":"-8:00","description":"Pacific Time (US & Canada)"}},"email":"allan.howell@example.com","login":{"uuid":"600a3e98-6a65-4755-a0f5-0e4cf20056a0","username":"heavymouse995","password":"scottie","salt":"6RtOBpVp","md5":"560799bb4b5ca8da862c39761ef444f1","sha1":"a12d164f0b6820f77fbb8ba9c3505c97c0d220bc","sha256":"08c6109177cab9adec16c43b26218b9c030526ba31200046c6c90b97457152eb"},"dob":{"date":"1966-03-18T12:57:31Z","age":53},"registered":{"date":"2014-02-01T00:02:58Z","age":5},"phone":"(793)-818-9821","cell":"(274)-414-7710","id":{"name":"SSN","value":"329-75-0155"},"picture":{"large":"https://randomuser.me/api/portraits/men/75.jpg","medium":"https://randomuser.me/api/portraits/med/men/75.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/75.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"jason","last":"ortiz"},"location":{"street":"1978 poplar dr","city":"aubrey","state":"south dakota","postcode":70261,"coordinates":{"latitude":"-32.6180","longitude":"-174.8620"},"timezone":{"offset":"+1:00","description":"Brussels, Copenhagen, Madrid, Paris"}},"email":"jason.ortiz@example.com","login":{"uuid":"1fe37193-0be9-46a9-9736-ee32af7d2d91","username":"tinyrabbit790","password":"singer","salt":"jTTujKo3","md5":"64386037c3b4150c94e1edf261fc32fb","sha1":"2a277e17e498ec3fb9a81c358ede1ab31559afcf","sha256":"567f8b7a5a11f781976c47e93a542e7800148a0ea54652c20ff4633f7d79562a"},"dob":{"date":"1964-12-30T23:30:20Z","age":54},"registered":{"date":"2014-08-30T13:14:58Z","age":4},"phone":"(002)-559-0584","cell":"(567)-324-9020","id":{"name":"SSN","value":"882-93-5989"},"picture":{"large":"https://randomuser.me/api/portraits/men/12.jpg","medium":"https://randomuser.me/api/portraits/med/men/12.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/12.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"maureen","last":"stevens"},"location":{"street":"4772 locust rd","city":"frisco","state":"new york","postcode":22764,"coordinates":{"latitude":"53.8822","longitude":"91.2887"},"timezone":{"offset":"-4:00","description":"Atlantic Time (Canada), Caracas, La Paz"}},"email":"maureen.stevens@example.com","login":{"uuid":"7c9051a3-fd19-4a0d-b7c2-f7dae18f4923","username":"purplefrog802","password":"nitram","salt":"2mVcthTr","md5":"9688a952045f6bb02a7cc94e053c930b","sha1":"73417c10958d2266c249dd2bed1f2fc82ae7883a","sha256":"4aeaa2119662a69a84656f1528adb0684eabfd3355e364737c331f7fad75189f"},"dob":{"date":"1979-05-18T20:25:40Z","age":39},"registered":{"date":"2003-05-09T11:56:45Z","age":15},"phone":"(171)-664-9338","cell":"(392)-664-5537","id":{"name":"SSN","value":"137-99-6392"},"picture":{"large":"https://randomuser.me/api/portraits/women/31.jpg","medium":"https://randomuser.me/api/portraits/med/women/31.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/31.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"darren","last":"barnett"},"location":{"street":"2672 edwards rd","city":"fountain valley","state":"georgia","postcode":95189,"coordinates":{"latitude":"-11.3664","longitude":"-19.6364"},"timezone":{"offset":"+8:00","description":"Beijing, Perth, Singapore, Hong Kong"}},"email":"darren.barnett@example.com","login":{"uuid":"abb0904a-8bd0-40ee-a2b2-b9c7f7098df7","username":"heavygorilla149","password":"joseph1","salt":"olBH4Vzm","md5":"6a2cea073985a4200cf4a3512c9e0981","sha1":"4ad14d29f41571c5f00fda3534f35f92df1d9976","sha256":"47a684681222d1b7f0c80ae005e0c75c1d16e5faf417eb0c080e613580fb2ca1"},"dob":{"date":"1996-12-14T05:52:06Z","age":22},"registered":{"date":"2015-03-02T02:33:31Z","age":4},"phone":"(029)-427-0625","cell":"(548)-192-3993","id":{"name":"SSN","value":"738-72-9381"},"picture":{"large":"https://randomuser.me/api/portraits/men/96.jpg","medium":"https://randomuser.me/api/portraits/med/men/96.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/96.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"carl","last":"kelly"},"location":{"street":"983 spring st","city":"daly city","state":"georgia","postcode":56722,"coordinates":{"latitude":"5.4433","longitude":"-73.0138"},"timezone":{"offset":"-10:00","description":"Hawaii"}},"email":"carl.kelly@example.com","login":{"uuid":"80df204c-da44-4ac2-8ef4-18da3834161e","username":"brownmeercat719","password":"whistler","salt":"lVqoN3a0","md5":"c737d4e38efe566c5d44fb0ddd01159c","sha1":"94c164f01d60eac0517969493bc4200f8cd1f12a","sha256":"38a2079a051f75ef64f8d9e8556298aed7594eef5a9102a2827ef61d1cee8389"},"dob":{"date":"1982-02-17T09:30:05Z","age":37},"registered":{"date":"2013-09-04T14:50:07Z","age":5},"phone":"(842)-909-9009","cell":"(202)-265-1998","id":{"name":"SSN","value":"671-07-3250"},"picture":{"large":"https://randomuser.me/api/portraits/men/71.jpg","medium":"https://randomuser.me/api/portraits/med/men/71.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/71.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"beverly","last":"lopez"},"location":{"street":"2456 white oak dr","city":"lowell","state":"arkansas","postcode":59068,"coordinates":{"latitude":"-67.6255","longitude":"179.9283"},"timezone":{"offset":"-6:00","description":"Central Time (US & Canada), Mexico City"}},"email":"beverly.lopez@example.com","login":{"uuid":"05678a31-9c8d-47de-8794-8bf4babfa054","username":"heavybird141","password":"banner","salt":"q4l5Vh66","md5":"e2ed8be6667de69dcb3178c78a9435cc","sha1":"451f04b33234a0dd0cb227e623b913841c167890","sha256":"04e98a94c2a35e7c49d3a15732cdec48b62924b4789312a396165fc443587c09"},"dob":{"date":"1981-09-30T17:48:40Z","age":37},"registered":{"date":"2018-06-02T08:02:39Z","age":0},"phone":"(286)-714-0708","cell":"(798)-909-3588","id":{"name":"SSN","value":"388-81-4481"},"picture":{"large":"https://randomuser.me/api/portraits/women/7.jpg","medium":"https://randomuser.me/api/portraits/med/women/7.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/7.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"michael","last":"palmer"},"location":{"street":"7916 first street","city":"denver","state":"utah","postcode":78705,"coordinates":{"latitude":"-7.6616","longitude":"13.8621"},"timezone":{"offset":"+2:00","description":"Kaliningrad, South Africa"}},"email":"michael.palmer@example.com","login":{"uuid":"b8d3167c-ef0c-4f4a-a760-4e2b47372a4e","username":"happypeacock769","password":"funny","salt":"kXwKakrL","md5":"f31a364e12b63222b61ffb8d9f6bc7f0","sha1":"47b2e4a3b1cf593b8b04ba781b5207e52c1981c0","sha256":"04e0f305c190c9be1df5693e743ceb5b51fbc29e6cd0302a3b655274cd0977bd"},"dob":{"date":"1997-05-18T00:32:58Z","age":21},"registered":{"date":"2006-05-09T03:06:07Z","age":12},"phone":"(302)-224-6185","cell":"(062)-434-2786","id":{"name":"SSN","value":"722-43-0444"},"picture":{"large":"https://randomuser.me/api/portraits/men/70.jpg","medium":"https://randomuser.me/api/portraits/med/men/70.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/70.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"mae","last":"carter"},"location":{"street":"8763 robinson rd","city":"denver","state":"oklahoma","postcode":12009,"coordinates":{"latitude":"-38.2053","longitude":"59.3094"},"timezone":{"offset":"-3:00","description":"Brazil, Buenos Aires, Georgetown"}},"email":"mae.carter@example.com","login":{"uuid":"7f243fc5-f6e8-4691-a650-e6d0a8d3c63e","username":"organicgorilla953","password":"greedy","salt":"PGZRLOXC","md5":"a890199755590aeb40c1bdd821a479f0","sha1":"37bc0c4b0067454f6dac01cf7f9833b5cc6e8818","sha256":"3640d2362b84abcf0e67682e46516b52fb72acca71976ec995f30333a926fd2d"},"dob":{"date":"1960-09-14T12:46:52Z","age":58},"registered":{"date":"2014-11-07T04:28:23Z","age":4},"phone":"(827)-833-8800","cell":"(093)-370-9644","id":{"name":"SSN","value":"835-24-5960"},"picture":{"large":"https://randomuser.me/api/portraits/women/0.jpg","medium":"https://randomuser.me/api/portraits/med/women/0.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/0.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"jim","last":"walker"},"location":{"street":"7277 prospect rd","city":"mesa","state":"kentucky","postcode":55021,"coordinates":{"latitude":"42.3610","longitude":"27.4020"},"timezone":{"offset":"-3:00","description":"Brazil, Buenos Aires, Georgetown"}},"email":"jim.walker@example.com","login":{"uuid":"ed0ac9d4-8481-4861-90f5-11a2362dd01c","username":"bluepeacock336","password":"claude","salt":"v7cCJJOB","md5":"1eebd7509ba176b179a1e968a10fe14c","sha1":"06cfc4e290db97eba5bd69c5c20ab2bed027c682","sha256":"ab3abb068cc8a0b034116e329f5fb4d9981d280ddfc060ae2932d22943c5e316"},"dob":{"date":"1968-04-08T18:00:03Z","age":51},"registered":{"date":"2009-12-23T11:50:25Z","age":9},"phone":"(058)-028-2456","cell":"(714)-876-2623","id":{"name":"SSN","value":"437-88-6298"},"picture":{"large":"https://randomuser.me/api/portraits/men/43.jpg","medium":"https://randomuser.me/api/portraits/med/men/43.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/43.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"valerie","last":"barnes"},"location":{"street":"2909 w sherman dr","city":"great falls","state":"missouri","postcode":37714,"coordinates":{"latitude":"29.8175","longitude":"-50.6947"},"timezone":{"offset":"-2:00","description":"Mid-Atlantic"}},"email":"valerie.barnes@example.com","login":{"uuid":"43753769-c6ef-49c5-9d4e-cc1939a26a3d","username":"angrypanda815","password":"curious","salt":"mF6CAIxq","md5":"c5d69cc770574488e714b87f5591605a","sha1":"db6dbee8490b7daf0b348d2e4d87838616272efd","sha256":"d0c0dd04991494e44d2198f63bc99bcd30486bff5d92ee06c1682beb85f5aa4e"},"dob":{"date":"1995-03-17T14:13:23Z","age":24},"registered":{"date":"2005-06-23T01:10:28Z","age":13},"phone":"(148)-185-6231","cell":"(953)-271-3083","id":{"name":"SSN","value":"784-59-8449"},"picture":{"large":"https://randomuser.me/api/portraits/women/20.jpg","medium":"https://randomuser.me/api/portraits/med/women/20.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/20.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"danielle","last":"walker"},"location":{"street":"3355 marsh ln","city":"overland park","state":"tennessee","postcode":14811,"coordinates":{"latitude":"-80.6561","longitude":"179.6205"},"timezone":{"offset":"-4:00","description":"Atlantic Time (Canada), Caracas, La Paz"}},"email":"danielle.walker@example.com","login":{"uuid":"1ab0ad6e-fe57-4edd-a971-4be944bed6cc","username":"tinydog965","password":"coventry","salt":"1foIgf4X","md5":"dcfa7a920fb901fe0fd0130ccb40396d","sha1":"f48f8c7174545224cdcff39a0957ed3e9968bb4e","sha256":"8d47a1e268e7d601ec20a95156f4170229ec435b1f3e167bda0664980b32511a"},"dob":{"date":"1983-10-19T19:21:55Z","age":35},"registered":{"date":"2004-04-23T01:34:21Z","age":15},"phone":"(740)-120-9030","cell":"(202)-891-3964","id":{"name":"SSN","value":"360-68-1365"},"picture":{"large":"https://randomuser.me/api/portraits/women/69.jpg","medium":"https://randomuser.me/api/portraits/med/women/69.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/69.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"roy","last":"murray"},"location":{"street":"7351 spring st","city":"providence","state":"new jersey","postcode":11776,"coordinates":{"latitude":"58.8516","longitude":"-96.4576"},"timezone":{"offset":"+10:00","description":"Eastern Australia, Guam, Vladivostok"}},"email":"roy.murray@example.com","login":{"uuid":"f938c18d-5010-452c-a8b0-47509667595a","username":"beautifulkoala511","password":"hellas","salt":"s40bbTqb","md5":"29940af4e3eb6ff2dfa2b328b499b184","sha1":"a9e13ad4bea000e7e459db228f9ff5040ceea572","sha256":"2952f377a6c0a09fd9605d6336af36517c0c16cfd39d0284d40686854b2238bd"},"dob":{"date":"1995-09-15T12:15:27Z","age":23},"registered":{"date":"2016-12-23T14:30:27Z","age":2},"phone":"(854)-545-0786","cell":"(417)-031-2096","id":{"name":"SSN","value":"042-59-1284"},"picture":{"large":"https://randomuser.me/api/portraits/men/10.jpg","medium":"https://randomuser.me/api/portraits/med/men/10.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/10.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"alex","last":"mendoza"},"location":{"street":"8218 brown terrace","city":"torrance","state":"georgia","postcode":39683,"coordinates":{"latitude":"71.9585","longitude":"97.0828"},"timezone":{"offset":"-7:00","description":"Mountain Time (US & Canada)"}},"email":"alex.mendoza@example.com","login":{"uuid":"fb5bb0b8-9e28-43d6-b406-9ec0042e7195","username":"heavypeacock450","password":"1017","salt":"B3uuNnWk","md5":"d1715704fe002031e9cfa9a3ecdd9f87","sha1":"dc52e866b249e4503eb7fefbafd1931f6147cb4a","sha256":"8046cbeb2289cf5bec01d6b58c1b64c8145d3a756b905e957f4e446fa30aaea4"},"dob":{"date":"1954-04-14T09:30:03Z","age":65},"registered":{"date":"2006-07-21T15:07:24Z","age":12},"phone":"(282)-163-7774","cell":"(783)-916-4975","id":{"name":"SSN","value":"804-26-6037"},"picture":{"large":"https://randomuser.me/api/portraits/men/87.jpg","medium":"https://randomuser.me/api/portraits/med/men/87.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/87.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"kitty","last":"hawkins"},"location":{"street":"1026 spring hill rd","city":"hamsburg","state":"ohio","postcode":59353,"coordinates":{"latitude":"60.3015","longitude":"-157.1048"},"timezone":{"offset":"+5:00","description":"Ekaterinburg, Islamabad, Karachi, Tashkent"}},"email":"kitty.hawkins@example.com","login":{"uuid":"e075f05f-6ac4-4439-a0f1-53b377ded8bc","username":"bigfrog720","password":"beech","salt":"vBBaQxhH","md5":"79c24e1c9029b5a094d9716a0b3cfa3c","sha1":"b7d1d6716fb9a0533890af590bd8d22775ddb61d","sha256":"cea26b2d5a47830f9572cf3169409ebf30bb26ecd035a626bb75a6de9bcff4a0"},"dob":{"date":"1985-10-18T05:19:08Z","age":33},"registered":{"date":"2015-03-16T05:57:06Z","age":4},"phone":"(133)-268-7418","cell":"(940)-192-7306","id":{"name":"SSN","value":"149-12-3771"},"picture":{"large":"https://randomuser.me/api/portraits/women/49.jpg","medium":"https://randomuser.me/api/portraits/med/women/49.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/49.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"steve","last":"miles"},"location":{"street":"8139 hillcrest rd","city":"garland","state":"kentucky","postcode":88084,"coordinates":{"latitude":"-15.7563","longitude":"-119.4557"},"timezone":{"offset":"+5:00","description":"Ekaterinburg, Islamabad, Karachi, Tashkent"}},"email":"steve.miles@example.com","login":{"uuid":"c31188fd-8e40-4a49-ae47-1819d2a6d6a2","username":"silverpeacock527","password":"ozzy","salt":"eAqX27eU","md5":"2a5b3a641883a916a259eeebcd1ae27c","sha1":"b15247aff01e052a24b61e507737aca2b6a7dce1","sha256":"6422c41acc81bcc94d0eb26f0147665a3fd6682a619477fa49dd59709f5c2ce2"},"dob":{"date":"1995-11-27T12:27:03Z","age":23},"registered":{"date":"2011-08-18T03:40:43Z","age":7},"phone":"(461)-196-8291","cell":"(859)-179-4381","id":{"name":"SSN","value":"822-22-7217"},"picture":{"large":"https://randomuser.me/api/portraits/men/12.jpg","medium":"https://randomuser.me/api/portraits/med/men/12.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/12.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"rita","last":"hicks"},"location":{"street":"4578 poplar dr","city":"ennis","state":"vermont","postcode":72386,"coordinates":{"latitude":"-39.3297","longitude":"-74.8630"},"timezone":{"offset":"-3:30","description":"Newfoundland"}},"email":"rita.hicks@example.com","login":{"uuid":"aeb5078f-7504-4d61-b88a-51e0a6e90d5b","username":"silverdog604","password":"beatrice","salt":"hrSk0YQB","md5":"5ba7215403f90815bd4bb3996517b469","sha1":"196bbfcd874a8df4127c46d649cac7699027b736","sha256":"2164d2e2dad089c525151ff8438434519bcf6f31d4a595be86e451211a4f13ef"},"dob":{"date":"1961-07-11T12:56:56Z","age":57},"registered":{"date":"2017-05-29T13:01:06Z","age":1},"phone":"(802)-624-6684","cell":"(924)-521-3802","id":{"name":"SSN","value":"137-84-9243"},"picture":{"large":"https://randomuser.me/api/portraits/women/60.jpg","medium":"https://randomuser.me/api/portraits/med/women/60.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/60.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"rebecca","last":"taylor"},"location":{"street":"5110 rolling green rd","city":"fort worth","state":"wisconsin","postcode":60136,"coordinates":{"latitude":"87.2094","longitude":"22.5912"},"timezone":{"offset":"-3:30","description":"Newfoundland"}},"email":"rebecca.taylor@example.com","login":{"uuid":"4c3b2544-58b2-4f18-bfb6-bb565a1f879c","username":"whitelion755","password":"someone","salt":"nHxAfSb3","md5":"38d3aca63ec594bdd86342579de31f5f","sha1":"64ad12c4244fe083dc532884b5d4bd7dcf4fedae","sha256":"1682bc63a2545416ceeb67f1b2cab0c5ac0805978bcd922bf627e80113f09ea2"},"dob":{"date":"1974-08-04T20:03:04Z","age":44},"registered":{"date":"2016-10-16T21:31:38Z","age":2},"phone":"(123)-326-0644","cell":"(280)-305-7898","id":{"name":"SSN","value":"493-99-6223"},"picture":{"large":"https://randomuser.me/api/portraits/women/27.jpg","medium":"https://randomuser.me/api/portraits/med/women/27.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/27.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"craig","last":"reyes"},"location":{"street":"7240 w pecan st","city":"akron","state":"north dakota","postcode":19878,"coordinates":{"latitude":"-48.2340","longitude":"-7.7906"},"timezone":{"offset":"-11:00","description":"Midway Island, Samoa"}},"email":"craig.reyes@example.com","login":{"uuid":"a24b1676-40fa-4726-b472-35c8ff3765a0","username":"tinytiger931","password":"audi","salt":"cf3drYrH","md5":"bd73951bc2aa5331222d1a1950cfc402","sha1":"f4840be094302f4fd7b4494259064b4cff933353","sha256":"708bd8c3e5491198d2a473108582a1561691cabc2fbe68d48317a8c497d21463"},"dob":{"date":"1957-08-07T03:08:36Z","age":61},"registered":{"date":"2015-02-10T01:12:16Z","age":4},"phone":"(615)-972-1681","cell":"(356)-948-5014","id":{"name":"SSN","value":"254-53-5350"},"picture":{"large":"https://randomuser.me/api/portraits/men/47.jpg","medium":"https://randomuser.me/api/portraits/med/men/47.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/47.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"chris","last":"campbell"},"location":{"street":"6768 lovers ln","city":"garden grove","state":"kansas","postcode":72395,"coordinates":{"latitude":"-48.8872","longitude":"-75.7497"},"timezone":{"offset":"+5:45","description":"Kathmandu"}},"email":"chris.campbell@example.com","login":{"uuid":"2413ce33-feb3-4bc4-808e-ea3c12651d1f","username":"lazykoala930","password":"dollars","salt":"MTFhykCT","md5":"9af56453cad9c158374d422128fd34e0","sha1":"33012c947d49fb083900088c9949d0a83a65706a","sha256":"3d5f5de9dea8666d7a92aeed288c40d02cf73cc25786ffb78b4c4f78c77ff0fd"},"dob":{"date":"1978-03-26T03:54:33Z","age":41},"registered":{"date":"2014-06-27T20:26:56Z","age":4},"phone":"(936)-036-7306","cell":"(900)-727-9606","id":{"name":"SSN","value":"145-57-2909"},"picture":{"large":"https://randomuser.me/api/portraits/men/60.jpg","medium":"https://randomuser.me/api/portraits/med/men/60.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/60.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"jorge","last":"prescott"},"location":{"street":"3928 dogwood ave","city":"roseburg","state":"missouri","postcode":64330,"coordinates":{"latitude":"61.4796","longitude":"25.4434"},"timezone":{"offset":"+5:30","description":"Bombay, Calcutta, Madras, New Delhi"}},"email":"jorge.prescott@example.com","login":{"uuid":"5ff71bc3-0a0b-4047-9477-39b893a0cb63","username":"brownkoala590","password":"alice","salt":"ZBVJ357r","md5":"ff13f604c728dd85a5048f01a83848a6","sha1":"74bd40d4f5ea86b12e11317823e487d5d6da65db","sha256":"c540549c104ba4382b1531e5929b09bfb820b9b980a2a47de81c4483cd11c315"},"dob":{"date":"1965-12-28T18:57:30Z","age":53},"registered":{"date":"2012-01-09T19:57:56Z","age":7},"phone":"(144)-510-9320","cell":"(629)-552-4746","id":{"name":"SSN","value":"955-61-1288"},"picture":{"large":"https://randomuser.me/api/portraits/men/28.jpg","medium":"https://randomuser.me/api/portraits/med/men/28.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/28.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"dolores","last":"gutierrez"},"location":{"street":"5732 plum st","city":"eureka","state":"alabama","postcode":35398,"coordinates":{"latitude":"-78.6889","longitude":"-125.2944"},"timezone":{"offset":"-3:00","description":"Brazil, Buenos Aires, Georgetown"}},"email":"dolores.gutierrez@example.com","login":{"uuid":"4110624b-d64e-4b4a-b3c3-c79f6bcbf4c2","username":"orangelion433","password":"escape","salt":"LC7f9Zgf","md5":"0937ac9da2e0b0cdc94d8326d61d8f59","sha1":"1784386785234971f14c819836fe111dc5aeb4de","sha256":"90f0e8f7a6625de0bb9b8ac53e7a9c877db3b6deac662593f4bf6f4330003ebb"},"dob":{"date":"1993-12-04T04:57:52Z","age":25},"registered":{"date":"2012-08-04T19:36:47Z","age":6},"phone":"(916)-141-9151","cell":"(040)-557-5859","id":{"name":"SSN","value":"441-65-9376"},"picture":{"large":"https://randomuser.me/api/portraits/women/73.jpg","medium":"https://randomuser.me/api/portraits/med/women/73.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/73.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"vernon","last":"long"},"location":{"street":"8594 bruce st","city":"south valley","state":"virginia","postcode":12188,"coordinates":{"latitude":"62.4243","longitude":"158.7174"},"timezone":{"offset":"+10:00","description":"Eastern Australia, Guam, Vladivostok"}},"email":"vernon.long@example.com","login":{"uuid":"e314c771-7cc2-4153-bb90-389d57a73a0d","username":"heavyfrog750","password":"driven","salt":"iKRXrvGw","md5":"40f18164648fd88c0fef6d708e35d72e","sha1":"73f8d3b6cb68e358617d24fbca234f88609e9691","sha256":"8eeb08160817d492c492bd92860fa9566de99ef4a2b6e81841a57cb60c4002c3"},"dob":{"date":"1945-01-17T21:44:49Z","age":74},"registered":{"date":"2002-04-06T12:36:47Z","age":17},"phone":"(194)-901-0405","cell":"(076)-112-4863","id":{"name":"SSN","value":"177-40-5644"},"picture":{"large":"https://randomuser.me/api/portraits/men/2.jpg","medium":"https://randomuser.me/api/portraits/med/men/2.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/2.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"dolores","last":"steeves "},"location":{"street":"8743 karen dr","city":"columbia","state":"texas","postcode":85198,"coordinates":{"latitude":"30.5231","longitude":"-127.3210"},"timezone":{"offset":"+2:00","description":"Kaliningrad, South Africa"}},"email":"dolores.steeves@example.com","login":{"uuid":"bb5293ed-ecc6-4c11-8399-f09e78ab537e","username":"angrydog384","password":"ryan","salt":"GBxBrC5U","md5":"72e2f8a32a0a377057890199756000aa","sha1":"209444a8e8013cabbeb956200df6adbe87a14bf8","sha256":"92b908946810e0528a93be65d5b098e33a739e44937e3a2e9fa73587513c7654"},"dob":{"date":"1981-01-20T10:51:42Z","age":38},"registered":{"date":"2005-07-25T13:27:50Z","age":13},"phone":"(457)-594-0206","cell":"(937)-925-5690","id":{"name":"SSN","value":"507-04-7749"},"picture":{"large":"https://randomuser.me/api/portraits/women/69.jpg","medium":"https://randomuser.me/api/portraits/med/women/69.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/69.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"crystal","last":"banks"},"location":{"street":"4041 paddock way","city":"tempe","state":"minnesota","postcode":70442,"coordinates":{"latitude":"-84.2015","longitude":"-95.7270"},"timezone":{"offset":"+2:00","description":"Kaliningrad, South Africa"}},"email":"crystal.banks@example.com","login":{"uuid":"0cd3f58f-de7e-4ada-8775-a2d3c042b4a9","username":"lazymeercat610","password":"goalie","salt":"m6n62C4J","md5":"109c2c77c2b36954f697f0609fe08f1c","sha1":"5f13212e1bb4ec54e48bf21963b1cb774e71c022","sha256":"a19b3b87c13d44c3c2c6c6498cc89ffe9b0582ea9b60ffb2065025df7b7dbed5"},"dob":{"date":"1994-09-09T20:04:25Z","age":24},"registered":{"date":"2008-04-09T08:56:05Z","age":11},"phone":"(651)-128-5818","cell":"(025)-205-2215","id":{"name":"SSN","value":"016-86-8235"},"picture":{"large":"https://randomuser.me/api/portraits/women/11.jpg","medium":"https://randomuser.me/api/portraits/med/women/11.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/11.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"morris","last":"herrera"},"location":{"street":"4015 hamilton ave","city":"garden grove","state":"kentucky","postcode":42993,"coordinates":{"latitude":"-32.7126","longitude":"101.1901"},"timezone":{"offset":"-5:00","description":"Eastern Time (US & Canada), Bogota, Lima"}},"email":"morris.herrera@example.com","login":{"uuid":"a152b3a9-7f45-4d5f-8a96-896b25beea5f","username":"redswan702","password":"starter","salt":"kFYSsfLh","md5":"83a2f9f83a312c11bca004834c1ceb40","sha1":"223ddce61709e4a178cb33780abcccba898111ad","sha256":"983d821fe0306ab4f6924df232a82149f531c76766b1bc7302d7de6f116df6a0"},"dob":{"date":"1995-02-16T04:40:02Z","age":24},"registered":{"date":"2003-11-13T17:35:33Z","age":15},"phone":"(857)-535-3022","cell":"(551)-720-3432","id":{"name":"SSN","value":"024-12-1412"},"picture":{"large":"https://randomuser.me/api/portraits/men/42.jpg","medium":"https://randomuser.me/api/portraits/med/men/42.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/42.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"jessie","last":"cruz"},"location":{"street":"9532 oak lawn ave","city":"topeka","state":"wyoming","postcode":43809,"coordinates":{"latitude":"-50.5502","longitude":"-89.1523"},"timezone":{"offset":"+5:30","description":"Bombay, Calcutta, Madras, New Delhi"}},"email":"jessie.cruz@example.com","login":{"uuid":"330d4353-f337-48ec-a377-60fcf03e73c0","username":"bluebutterfly747","password":"zxczxc","salt":"U8NPS9qU","md5":"b063e2b8ec4cd14b2f3decee0ef1af0a","sha1":"bf9533af8fea28f03dc00e50472f852dbe996d41","sha256":"5e2d03ca28b97ff3017a52c3427a85a43f5a912cab1ce460cce848a8de52f5c7"},"dob":{"date":"1963-02-15T01:32:03Z","age":56},"registered":{"date":"2004-02-05T21:43:57Z","age":15},"phone":"(090)-568-3080","cell":"(567)-803-1577","id":{"name":"SSN","value":"251-91-1015"},"picture":{"large":"https://randomuser.me/api/portraits/women/17.jpg","medium":"https://randomuser.me/api/portraits/med/women/17.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/17.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"myrtle","last":"george"},"location":{"street":"4932 karen dr","city":"surprise","state":"colorado","postcode":36143,"coordinates":{"latitude":"18.2095","longitude":"-100.8707"},"timezone":{"offset":"+3:00","description":"Baghdad, Riyadh, Moscow, St. Petersburg"}},"email":"myrtle.george@example.com","login":{"uuid":"886d1f35-ef6b-46db-8f6c-3652711c3282","username":"orangeostrich213","password":"unique","salt":"9jsJl0HU","md5":"6f439761976bcc16e7e1fb963de1ae82","sha1":"e95390681a76629f39ca491c98290c84f0c8a769","sha256":"8083e3f8eac793d13e7b904fab220cda6d1f4313ad107f76edf7293509fb86c8"},"dob":{"date":"1952-02-22T16:05:46Z","age":67},"registered":{"date":"2010-03-02T11:31:10Z","age":9},"phone":"(238)-502-2160","cell":"(278)-059-8327","id":{"name":"SSN","value":"475-74-3451"},"picture":{"large":"https://randomuser.me/api/portraits/women/16.jpg","medium":"https://randomuser.me/api/portraits/med/women/16.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/16.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"debra","last":"torres"},"location":{"street":"7637 miller ave","city":"newport news","state":"colorado","postcode":68281,"coordinates":{"latitude":"47.2858","longitude":"-86.0491"},"timezone":{"offset":"-5:00","description":"Eastern Time (US & Canada), Bogota, Lima"}},"email":"debra.torres@example.com","login":{"uuid":"3ae0ff49-bbbb-4d63-b1fe-00f3033982ef","username":"tinyzebra727","password":"fettish","salt":"4iph4hWP","md5":"e8bbe480febabdb8c47ebfa7fb73b4df","sha1":"2184860d1983e3502135c7101e055e67e0211937","sha256":"5cfc0cb26a7269da16b0cab7b5c14bb70327253e959e1a524f5043038ce5012d"},"dob":{"date":"1991-03-11T04:31:26Z","age":28},"registered":{"date":"2002-05-10T08:15:02Z","age":16},"phone":"(873)-285-0167","cell":"(491)-808-3556","id":{"name":"SSN","value":"039-80-4515"},"picture":{"large":"https://randomuser.me/api/portraits/women/50.jpg","medium":"https://randomuser.me/api/portraits/med/women/50.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/50.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"henry","last":"payne"},"location":{"street":"8737 photinia ave","city":"st. petersburg","state":"alaska","postcode":79584,"coordinates":{"latitude":"65.5640","longitude":"45.5420"},"timezone":{"offset":"+4:00","description":"Abu Dhabi, Muscat, Baku, Tbilisi"}},"email":"henry.payne@example.com","login":{"uuid":"b31b6381-1d18-4533-b818-4e3ec2ee1710","username":"organicwolf332","password":"radical","salt":"w9Y6ezTS","md5":"6aa4b5c92ae7557f37dfdd1480cde250","sha1":"197fbb81a7cf5dade6052ebb486315cbc3dfe43f","sha256":"c15eddc8653fb4f8f1eaac24015a6197a53a7d1c5a315db43ece75d9ac2b4b54"},"dob":{"date":"1981-07-17T17:26:20Z","age":37},"registered":{"date":"2016-04-28T07:03:30Z","age":2},"phone":"(996)-978-8391","cell":"(399)-698-9209","id":{"name":"SSN","value":"074-33-5426"},"picture":{"large":"https://randomuser.me/api/portraits/men/53.jpg","medium":"https://randomuser.me/api/portraits/med/men/53.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/53.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"arthur","last":"kennedy"},"location":{"street":"9464 james st","city":"midland","state":"maryland","postcode":61618,"coordinates":{"latitude":"36.4132","longitude":"179.0677"},"timezone":{"offset":"+5:45","description":"Kathmandu"}},"email":"arthur.kennedy@example.com","login":{"uuid":"13e9c260-b1dc-4edf-9e59-dd5dde376e2f","username":"sadkoala392","password":"wrestle","salt":"B7ut4401","md5":"5e269793384966c0b6dfd459e97fa1a9","sha1":"210b543b4cd402b9ceffe1744088dfca55e8a179","sha256":"f2aa9d8e9b811dbaa5fef0af4942ec40cb07fc2bda907d754c5725f5816177b2"},"dob":{"date":"1983-07-17T15:57:07Z","age":35},"registered":{"date":"2015-08-05T01:01:54Z","age":3},"phone":"(201)-521-8334","cell":"(662)-023-8003","id":{"name":"SSN","value":"945-06-9068"},"picture":{"large":"https://randomuser.me/api/portraits/men/24.jpg","medium":"https://randomuser.me/api/portraits/med/men/24.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/24.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"bernice","last":"gonzales"},"location":{"street":"8390 wheeler ridge dr","city":"fontana","state":"new mexico","postcode":48019,"coordinates":{"latitude":"-1.0599","longitude":"71.3712"},"timezone":{"offset":"+1:00","description":"Brussels, Copenhagen, Madrid, Paris"}},"email":"bernice.gonzales@example.com","login":{"uuid":"a8c43dc2-c590-4249-a6cb-f4b404347a1c","username":"bigfish331","password":"broncos","salt":"E2MVDLpR","md5":"781c65f2e02aaca7c156909e39a0168a","sha1":"1afcfac29eaf87687e22321a986c67a3d364ff80","sha256":"4ba12f0d1840b9c0281cbbfb7a9241127e14c52aa91ffb76a49c302c9efd029e"},"dob":{"date":"1966-01-20T23:43:17Z","age":53},"registered":{"date":"2012-09-18T08:18:47Z","age":6},"phone":"(438)-731-8499","cell":"(977)-951-3274","id":{"name":"SSN","value":"929-33-5540"},"picture":{"large":"https://randomuser.me/api/portraits/women/91.jpg","medium":"https://randomuser.me/api/portraits/med/women/91.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/91.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"devon","last":"white"},"location":{"street":"4399 rolling green rd","city":"norwalk","state":"north dakota","postcode":10112,"coordinates":{"latitude":"10.2347","longitude":"-148.7100"},"timezone":{"offset":"0:00","description":"Western Europe Time, London, Lisbon, Casablanca"}},"email":"devon.white@example.com","login":{"uuid":"a46674be-ab44-4760-b67c-aa2e5eb3b0a8","username":"blackladybug635","password":"splinter","salt":"KTNRj4KX","md5":"0c692acb82d21d3cc040623abe13b5d5","sha1":"b73dbc822afcef234583c56d0bce4ca0bcc72807","sha256":"3fa772fa5ae3861ca0c88acad78f5208364f35c44b21b71ee6965221772aac20"},"dob":{"date":"1979-09-03T05:31:51Z","age":39},"registered":{"date":"2008-11-28T00:02:18Z","age":10},"phone":"(949)-462-7457","cell":"(525)-729-3234","id":{"name":"SSN","value":"698-11-5701"},"picture":{"large":"https://randomuser.me/api/portraits/men/48.jpg","medium":"https://randomuser.me/api/portraits/med/men/48.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/48.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"eva","last":"harper"},"location":{"street":"6214 pecan acres ln","city":"tulsa","state":"oklahoma","postcode":91949,"coordinates":{"latitude":"59.7290","longitude":"71.9876"},"timezone":{"offset":"+3:30","description":"Tehran"}},"email":"eva.harper@example.com","login":{"uuid":"9ac7696f-4c0d-43cd-a6dd-011f56b0ea77","username":"angryladybug572","password":"fredrick","salt":"XSArbdd7","md5":"9abc4c922d674f0473d310d944f22f28","sha1":"6bfd7ffe6cccdaf25018b4e53b0df879cea54fad","sha256":"bff2434b2ffca0014bd1fd4f469e9f6ec4eec4d521cafdacea51b16debfa00bc"},"dob":{"date":"1948-05-23T02:35:06Z","age":70},"registered":{"date":"2015-02-09T15:25:42Z","age":4},"phone":"(707)-239-7548","cell":"(688)-207-5770","id":{"name":"SSN","value":"295-48-2023"},"picture":{"large":"https://randomuser.me/api/portraits/women/13.jpg","medium":"https://randomuser.me/api/portraits/med/women/13.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/13.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"kristina","last":"harper"},"location":{"street":"5916 hickory creek dr","city":"dumas","state":"oklahoma","postcode":12575,"coordinates":{"latitude":"56.9548","longitude":"-40.6041"},"timezone":{"offset":"+5:00","description":"Ekaterinburg, Islamabad, Karachi, Tashkent"}},"email":"kristina.harper@example.com","login":{"uuid":"8478fb0e-68e5-4ba8-985f-0799a733b477","username":"orangelion922","password":"charisma","salt":"daW7BEA9","md5":"5b7497b5960f9bdca1857a20183d09b6","sha1":"f8378e9f496c667c9d9b83010937a59138342536","sha256":"24c27e889d71b2f8a023bdf68355e9d962b0b1b7e6ea82f6dd26b102c27a8f30"},"dob":{"date":"1955-08-15T21:18:19Z","age":63},"registered":{"date":"2004-01-24T06:50:12Z","age":15},"phone":"(804)-896-6900","cell":"(678)-942-5665","id":{"name":"SSN","value":"693-31-4248"},"picture":{"large":"https://randomuser.me/api/portraits/women/58.jpg","medium":"https://randomuser.me/api/portraits/med/women/58.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/58.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"cameron","last":"sims"},"location":{"street":"6552 n stelling rd","city":"chesapeake","state":"illinois","postcode":45731,"coordinates":{"latitude":"-11.8027","longitude":"-145.2008"},"timezone":{"offset":"+5:30","description":"Bombay, Calcutta, Madras, New Delhi"}},"email":"cameron.sims@example.com","login":{"uuid":"8d04d369-9c16-4dca-bb35-65ccdb4eedff","username":"sadelephant511","password":"priest","salt":"cC06kLEB","md5":"af02ccf8e08dd3c64b098a65bf901088","sha1":"e0d7275c51ce67686aa06dd382a9780b2112cd2a","sha256":"e91aa1bb2ab7343305aae4efa74e1049b0c467b0b8dc1522bba5d6f5d8ed69af"},"dob":{"date":"1964-02-20T04:04:16Z","age":55},"registered":{"date":"2004-04-16T18:18:13Z","age":15},"phone":"(474)-208-4422","cell":"(552)-786-9933","id":{"name":"SSN","value":"601-78-0018"},"picture":{"large":"https://randomuser.me/api/portraits/men/43.jpg","medium":"https://randomuser.me/api/portraits/med/men/43.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/43.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"zack","last":"ortiz"},"location":{"street":"7662 northaven rd","city":"fairfield","state":"north dakota","postcode":85366,"coordinates":{"latitude":"-82.6019","longitude":"148.9652"},"timezone":{"offset":"-11:00","description":"Midway Island, Samoa"}},"email":"zack.ortiz@example.com","login":{"uuid":"64e67438-e768-4644-8bcf-3317d2d89451","username":"yellowpeacock782","password":"565656","salt":"wgEOOsDN","md5":"3962ef0792551876787bde60e4725e42","sha1":"eccaea7730eccbee5e18c3f39565b409927477b9","sha256":"95362e76a3e1995893ebcd056ef61d687c65ff7d4ff25075f532e99c9639d778"},"dob":{"date":"1948-09-02T15:19:38Z","age":70},"registered":{"date":"2012-12-11T00:18:28Z","age":6},"phone":"(822)-451-2476","cell":"(248)-403-3070","id":{"name":"SSN","value":"276-55-9363"},"picture":{"large":"https://randomuser.me/api/portraits/men/24.jpg","medium":"https://randomuser.me/api/portraits/med/men/24.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/24.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"jessica","last":"hanson"},"location":{"street":"8246 hamilton ave","city":"midland","state":"alaska","postcode":35981,"coordinates":{"latitude":"87.3806","longitude":"7.6299"},"timezone":{"offset":"+2:00","description":"Kaliningrad, South Africa"}},"email":"jessica.hanson@example.com","login":{"uuid":"53c350c5-bd79-4ed7-bff9-3e7457ad0d13","username":"crazyostrich483","password":"onetime","salt":"4mT3wAhu","md5":"c627c829505f0b904fb4b433bc2472ce","sha1":"98651b4d2b24b9e64b6e9f046b9bf1a4bd8c8382","sha256":"9e2d3ada11ac06977969dabffd88579807606edf53c45ce491dff0a7c3d28a8c"},"dob":{"date":"1946-02-02T13:43:03Z","age":73},"registered":{"date":"2018-05-05T18:48:05Z","age":0},"phone":"(456)-608-0870","cell":"(488)-225-6148","id":{"name":"SSN","value":"227-67-9485"},"picture":{"large":"https://randomuser.me/api/portraits/women/6.jpg","medium":"https://randomuser.me/api/portraits/med/women/6.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/6.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"addison","last":"lee"},"location":{"street":"3792 photinia ave","city":"toledo","state":"utah","postcode":29344,"coordinates":{"latitude":"11.5126","longitude":"-141.4481"},"timezone":{"offset":"+4:00","description":"Abu Dhabi, Muscat, Baku, Tbilisi"}},"email":"addison.lee@example.com","login":{"uuid":"1ec4e2fb-2bc6-4013-8f16-0303df25eb76","username":"purplebird236","password":"sigmar","salt":"FBJH37Hx","md5":"feab48367cd39674492f63954352892c","sha1":"1913b76612c86fea3816e521a8857d794080d5d8","sha256":"802b1f34de7add1b9790c8e08e56e64b00c54ad690c99785302c595e4546bb31"},"dob":{"date":"1956-12-06T06:51:42Z","age":62},"registered":{"date":"2006-01-20T13:57:36Z","age":13},"phone":"(220)-540-6622","cell":"(580)-832-3294","id":{"name":"SSN","value":"966-00-3893"},"picture":{"large":"https://randomuser.me/api/portraits/women/6.jpg","medium":"https://randomuser.me/api/portraits/med/women/6.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/6.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"evan","last":"foster"},"location":{"street":"2800 hunters creek dr","city":"ontario","state":"kentucky","postcode":93099,"coordinates":{"latitude":"34.0501","longitude":"-162.4310"},"timezone":{"offset":"+3:00","description":"Baghdad, Riyadh, Moscow, St. Petersburg"}},"email":"evan.foster@example.com","login":{"uuid":"9d25a966-dafb-4cb9-84ef-00b406067fe1","username":"beautifulelephant783","password":"twelve","salt":"eyPixgO6","md5":"40442ad1b36d7e57fce9d93f3f04f9ca","sha1":"97dca6636ef3598a6ca97409cea5ea5b3c35a923","sha256":"b1184623d047c3033352576042825e2c5b2ed89c501ce684ff8ad1b027c4d987"},"dob":{"date":"1981-12-10T04:18:54Z","age":37},"registered":{"date":"2008-11-23T23:32:34Z","age":10},"phone":"(065)-242-7510","cell":"(682)-890-2764","id":{"name":"SSN","value":"790-02-6818"},"picture":{"large":"https://randomuser.me/api/portraits/men/17.jpg","medium":"https://randomuser.me/api/portraits/med/men/17.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/17.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"don","last":"rhodes"},"location":{"street":"7681 northaven rd","city":"cedar hill","state":"virginia","postcode":73339,"coordinates":{"latitude":"71.5527","longitude":"7.4463"},"timezone":{"offset":"+5:00","description":"Ekaterinburg, Islamabad, Karachi, Tashkent"}},"email":"don.rhodes@example.com","login":{"uuid":"68790bea-71b0-4524-9fa0-648f14d72509","username":"whiteduck869","password":"1004","salt":"y2HnqrmY","md5":"9b9043c60fddeae5d4b3d733920ba37d","sha1":"38e9a57249863006076aef8f28520525fa67b715","sha256":"026b0c44a2d2f6d520fa7860547e91650d9b168eccbfac155078bbca2acbc689"},"dob":{"date":"1962-04-28T23:19:08Z","age":56},"registered":{"date":"2014-01-30T23:01:18Z","age":5},"phone":"(313)-640-3773","cell":"(040)-543-6152","id":{"name":"SSN","value":"864-30-0506"},"picture":{"large":"https://randomuser.me/api/portraits/men/75.jpg","medium":"https://randomuser.me/api/portraits/med/men/75.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/75.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"sebastian","last":"mason"},"location":{"street":"3064 groveland terrace","city":"anchorage","state":"new hampshire","postcode":77679,"coordinates":{"latitude":"-59.9759","longitude":"115.8526"},"timezone":{"offset":"+3:30","description":"Tehran"}},"email":"sebastian.mason@example.com","login":{"uuid":"0e357e55-a3c2-407c-a24d-3e4295bcc6ce","username":"brownbutterfly930","password":"photos","salt":"OPNc9Jpd","md5":"7f8cc921b5b478622b84d8d95c3e69f9","sha1":"82b9ca3aebb95d2cabc436b383a70fda9a0b91af","sha256":"a9983f0310f583c893e98dac91e7df9f0992f072508d5a83217fa6144b96c55f"},"dob":{"date":"1962-12-30T15:29:42Z","age":56},"registered":{"date":"2008-11-19T03:29:34Z","age":10},"phone":"(582)-890-5031","cell":"(963)-113-0474","id":{"name":"SSN","value":"386-04-2874"},"picture":{"large":"https://randomuser.me/api/portraits/men/65.jpg","medium":"https://randomuser.me/api/portraits/med/men/65.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/65.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"camila","last":"byrd"},"location":{"street":"5800 first street","city":"san mateo","state":"mississippi","postcode":75240,"coordinates":{"latitude":"-28.1919","longitude":"150.1525"},"timezone":{"offset":"-3:00","description":"Brazil, Buenos Aires, Georgetown"}},"email":"camila.byrd@example.com","login":{"uuid":"2a7eb9d0-739a-404c-9886-2a1c6a85760a","username":"greenmeercat522","password":"tarpon","salt":"x5zHGIJn","md5":"9d850bca3f281de20ba4f12376930074","sha1":"6bc0d7100b9ec1acf26e765836da776f259f7363","sha256":"65441e727dffd9356894904ceecb22640fdc1f639281418d03191e3af4a477bf"},"dob":{"date":"1981-11-27T11:43:21Z","age":37},"registered":{"date":"2008-10-27T03:14:01Z","age":10},"phone":"(089)-699-4859","cell":"(431)-445-2837","id":{"name":"SSN","value":"346-99-7093"},"picture":{"large":"https://randomuser.me/api/portraits/women/13.jpg","medium":"https://randomuser.me/api/portraits/med/women/13.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/13.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"tonya","last":"ferguson"},"location":{"street":"4968 pecan acres ln","city":"aurora","state":"tennessee","postcode":51192,"coordinates":{"latitude":"-22.4996","longitude":"-136.9871"},"timezone":{"offset":"+7:00","description":"Bangkok, Hanoi, Jakarta"}},"email":"tonya.ferguson@example.com","login":{"uuid":"8214bcc8-2653-4adc-a1df-712f4c60927f","username":"ticklishpanda780","password":"7007","salt":"Jejq8rTu","md5":"b0200148c3e4c545d361a05a8282236d","sha1":"037b7876d2289776f8fe2d47f1a6b8bc05d34b88","sha256":"cb62822c6cc8f949ccb2f513d493d82d2c86ff55caa940ac62db51e7f6fa5898"},"dob":{"date":"1973-09-05T06:29:17Z","age":45},"registered":{"date":"2015-11-12T18:43:07Z","age":3},"phone":"(498)-763-0538","cell":"(338)-142-4044","id":{"name":"SSN","value":"132-16-6150"},"picture":{"large":"https://randomuser.me/api/portraits/women/5.jpg","medium":"https://randomuser.me/api/portraits/med/women/5.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/5.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"april","last":"thompson"},"location":{"street":"3908 e pecan st","city":"st. petersburg","state":"kentucky","postcode":46526,"coordinates":{"latitude":"-57.3343","longitude":"-99.2269"},"timezone":{"offset":"+3:30","description":"Tehran"}},"email":"april.thompson@example.com","login":{"uuid":"5bb272e9-bd55-45d1-a4cd-f1bacb7f927a","username":"silverpanda799","password":"zhun","salt":"VbgVxhUA","md5":"d461e88dd5ac9ecc17f2e3a3293f9d71","sha1":"e174b71c27bc140f7f7c7ca3f4dd577555387d1b","sha256":"0a6d30be481d7182f45046c3a648c762a09bb877bf678ca76b6a8af59a1b6434"},"dob":{"date":"1976-07-25T04:52:08Z","age":42},"registered":{"date":"2016-07-18T21:10:31Z","age":2},"phone":"(358)-059-9621","cell":"(619)-659-2122","id":{"name":"SSN","value":"759-44-3845"},"picture":{"large":"https://randomuser.me/api/portraits/women/47.jpg","medium":"https://randomuser.me/api/portraits/med/women/47.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/47.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"liam","last":"garrett"},"location":{"street":"1188 depaul dr","city":"amarillo","state":"nebraska","postcode":11263,"coordinates":{"latitude":"-56.6704","longitude":"-118.5758"},"timezone":{"offset":"-3:30","description":"Newfoundland"}},"email":"liam.garrett@example.com","login":{"uuid":"e9e4e1e9-f2cf-475d-ad43-34c32bcbc685","username":"yellowelephant520","password":"sandro","salt":"jEm0vZee","md5":"a8792b6be951755656d0b9f6477db9dd","sha1":"d91768aea2eaa1e0d4856e4f6ef00e672a190470","sha256":"3b345815541fbc41c6f018cf0a705910b430a47f0ccc3e7d595ac0c3772a2149"},"dob":{"date":"1978-09-26T13:35:09Z","age":40},"registered":{"date":"2015-12-25T19:49:05Z","age":3},"phone":"(238)-162-6519","cell":"(261)-803-0984","id":{"name":"SSN","value":"880-46-7734"},"picture":{"large":"https://randomuser.me/api/portraits/men/45.jpg","medium":"https://randomuser.me/api/portraits/med/men/45.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/45.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"kylie","last":"ford"},"location":{"street":"6804 e north st","city":"seymour","state":"idaho","postcode":90747,"coordinates":{"latitude":"-7.5989","longitude":"53.5045"},"timezone":{"offset":"+7:00","description":"Bangkok, Hanoi, Jakarta"}},"email":"kylie.ford@example.com","login":{"uuid":"4eb24b2f-db71-4c28-9e9c-14a46aae7f47","username":"goldenelephant277","password":"ministry","salt":"jgI25mGQ","md5":"fc758a508d301e7aced3160d3f797b52","sha1":"1f42922292ef9a77b9d77c4676c55f55bd57feb2","sha256":"242d999f994d78002f9e55b8d4718af5acb00a0b3d9bb3ea547d67d61dcdf6a0"},"dob":{"date":"1977-07-30T13:18:27Z","age":41},"registered":{"date":"2004-10-31T08:49:20Z","age":14},"phone":"(267)-318-7862","cell":"(166)-947-7543","id":{"name":"SSN","value":"701-11-3013"},"picture":{"large":"https://randomuser.me/api/portraits/women/44.jpg","medium":"https://randomuser.me/api/portraits/med/women/44.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/44.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"enrique","last":"cunningham"},"location":{"street":"5721 hunters creek dr","city":"eugene","state":"kentucky","postcode":15752,"coordinates":{"latitude":"5.0565","longitude":"-79.6488"},"timezone":{"offset":"-9:00","description":"Alaska"}},"email":"enrique.cunningham@example.com","login":{"uuid":"25e1325c-d7f3-4759-9ce8-48b5f838661b","username":"silvermeercat770","password":"goddess","salt":"vzGkIEBR","md5":"4bfe99e9280df8ac5db63639b0af6253","sha1":"5b9fa245a131951792a9fff789fc997362945efe","sha256":"ff50e870cfe50ec1fbbd15a5666e949b3d00f2473cbf452f2c36e21dda0a2ad8"},"dob":{"date":"1961-01-08T00:08:15Z","age":58},"registered":{"date":"2004-01-01T16:57:59Z","age":15},"phone":"(224)-747-2667","cell":"(597)-633-6101","id":{"name":"SSN","value":"581-48-3586"},"picture":{"large":"https://randomuser.me/api/portraits/men/41.jpg","medium":"https://randomuser.me/api/portraits/med/men/41.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/41.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"sylvia","last":"holland"},"location":{"street":"2390 dane st","city":"newport news","state":"hawaii","postcode":57474,"coordinates":{"latitude":"-86.1899","longitude":"137.6799"},"timezone":{"offset":"+3:30","description":"Tehran"}},"email":"sylvia.holland@example.com","login":{"uuid":"df8b9e41-4563-490a-b73d-0509befe7e5f","username":"sadpeacock795","password":"playboy","salt":"qYUJhRmE","md5":"7e0aae60e671b69325d46a141bc729d7","sha1":"3648528f6e5f69d04e36a55e39318ac1dee7eb10","sha256":"1d86dd922de5d32743b7aba59dbfb4e05219c087ed5e035a709aaf045f15cb93"},"dob":{"date":"1954-03-26T10:23:29Z","age":65},"registered":{"date":"2012-12-29T06:01:50Z","age":6},"phone":"(952)-906-0587","cell":"(877)-336-8852","id":{"name":"SSN","value":"993-59-9618"},"picture":{"large":"https://randomuser.me/api/portraits/women/51.jpg","medium":"https://randomuser.me/api/portraits/med/women/51.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/51.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"jack","last":"black"},"location":{"street":"9498 spring st","city":"north las vegas","state":"idaho","postcode":17405,"coordinates":{"latitude":"80.9668","longitude":"58.6859"},"timezone":{"offset":"-3:30","description":"Newfoundland"}},"email":"jack.black@example.com","login":{"uuid":"335903b1-be0a-4101-904d-481eee3c7928","username":"silverwolf598","password":"freddy","salt":"aGLtbMBx","md5":"7c4d0d7d2a4ee035b17d0bced3138691","sha1":"39f2cad161b98b2f45f2f877ffb632f1626a86c1","sha256":"0fcd677dc346fda4dc00d54cd7da4681e291d7e6aef2e6b58f1f546779a5a239"},"dob":{"date":"1950-02-21T01:35:42Z","age":69},"registered":{"date":"2004-11-07T18:02:15Z","age":14},"phone":"(398)-633-7538","cell":"(295)-320-1145","id":{"name":"SSN","value":"444-59-0663"},"picture":{"large":"https://randomuser.me/api/portraits/men/6.jpg","medium":"https://randomuser.me/api/portraits/med/men/6.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/6.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"floyd","last":"dixon"},"location":{"street":"4899 pecan acres ln","city":"surprise","state":"texas","postcode":36466,"coordinates":{"latitude":"77.0289","longitude":"98.1101"},"timezone":{"offset":"+7:00","description":"Bangkok, Hanoi, Jakarta"}},"email":"floyd.dixon@example.com","login":{"uuid":"32ad269a-f7e8-4027-b869-594804521ca7","username":"heavyelephant927","password":"neutron","salt":"hEQq9lf5","md5":"51fe5d13a0863acf5bfc915810827b87","sha1":"e830038d634870858a82b4b42d010b81e0981641","sha256":"f15b3246bc112867987a3553cc97f377ed13cf0a3d48c4cc2c39b098392adce7"},"dob":{"date":"1973-07-27T15:27:45Z","age":45},"registered":{"date":"2007-06-09T02:29:30Z","age":11},"phone":"(160)-547-7636","cell":"(249)-638-2665","id":{"name":"SSN","value":"271-72-9680"},"picture":{"large":"https://randomuser.me/api/portraits/men/69.jpg","medium":"https://randomuser.me/api/portraits/med/men/69.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/69.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"chad","last":"morales"},"location":{"street":"7182 mcclellan rd","city":"north valley","state":"north dakota","postcode":21523,"coordinates":{"latitude":"-25.9784","longitude":"-67.0159"},"timezone":{"offset":"+3:30","description":"Tehran"}},"email":"chad.morales@example.com","login":{"uuid":"b9b82627-b487-4eac-9f5b-059c609f10c4","username":"purpleladybug948","password":"lucky1","salt":"LZPVq30d","md5":"b05008cac3ef6d2cf348b3e8e8c08408","sha1":"7aacb8a31017e55e5923c2b8c0925d1d6cd55108","sha256":"25971b2be6384b8dcc42ffa37ce9c373fb4719008b88180bed5cf6fc7796889e"},"dob":{"date":"1996-10-28T04:33:26Z","age":22},"registered":{"date":"2013-09-20T00:04:00Z","age":5},"phone":"(096)-272-2736","cell":"(385)-003-5095","id":{"name":"SSN","value":"820-08-0757"},"picture":{"large":"https://randomuser.me/api/portraits/men/37.jpg","medium":"https://randomuser.me/api/portraits/med/men/37.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/37.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"miguel","last":"morales"},"location":{"street":"8838 oak ridge ln","city":"bozeman","state":"colorado","postcode":69526,"coordinates":{"latitude":"52.6514","longitude":"153.2916"},"timezone":{"offset":"-6:00","description":"Central Time (US & Canada), Mexico City"}},"email":"miguel.morales@example.com","login":{"uuid":"9092799c-3f0f-4448-bb62-c79d7c9eef41","username":"brownfrog708","password":"sailor","salt":"5EvJL9Pr","md5":"232c8dea4fca54396c042a8a65804c27","sha1":"e7a6d5efb22eaf28427e6972fd631c05e357ca39","sha256":"dbf964871fc16f4c0c91edc80e5a29dfd9c66aefd534d018b7ee4a493062b121"},"dob":{"date":"1954-11-15T22:58:07Z","age":64},"registered":{"date":"2009-01-09T17:41:52Z","age":10},"phone":"(575)-819-6303","cell":"(687)-187-9075","id":{"name":"SSN","value":"924-66-9340"},"picture":{"large":"https://randomuser.me/api/portraits/men/53.jpg","medium":"https://randomuser.me/api/portraits/med/men/53.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/53.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"rodney","last":"thompson"},"location":{"street":"6582 mockingbird ln","city":"orange","state":"delaware","postcode":17114,"coordinates":{"latitude":"-44.3533","longitude":"-18.6104"},"timezone":{"offset":"+1:00","description":"Brussels, Copenhagen, Madrid, Paris"}},"email":"rodney.thompson@example.com","login":{"uuid":"86943678-20e4-4319-be89-47b7bf89b214","username":"smallostrich115","password":"pizzas","salt":"1wtCCfQh","md5":"4af73ab82f819147a2024c6ae5a8d85a","sha1":"0977604a02252fd7120dc9db628d3a013a348171","sha256":"d01a14f2ebab8e934db88dc2dade891a25501b3e3738f67760afb554f914024c"},"dob":{"date":"1986-06-23T05:09:20Z","age":32},"registered":{"date":"2003-09-10T10:44:28Z","age":15},"phone":"(825)-131-0901","cell":"(084)-354-3866","id":{"name":"SSN","value":"737-23-0158"},"picture":{"large":"https://randomuser.me/api/portraits/men/96.jpg","medium":"https://randomuser.me/api/portraits/med/men/96.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/96.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"dawn","last":"bowman"},"location":{"street":"3689 college st","city":"aurora","state":"pennsylvania","postcode":90038,"coordinates":{"latitude":"65.8304","longitude":"133.0385"},"timezone":{"offset":"+4:30","description":"Kabul"}},"email":"dawn.bowman@example.com","login":{"uuid":"8e45359a-4049-47f1-bd11-5885eacf2a27","username":"greenostrich363","password":"herbert","salt":"hstJifCC","md5":"8944fc55a69254f84fc12f5ca11d43cb","sha1":"aa72feb34c0aacebbcf0e41a9f0680b4e5916252","sha256":"312041e468e976cbd8872287cc4015244cca308ef94ad6aecfe1ecffa72262ce"},"dob":{"date":"1963-07-21T02:35:34Z","age":55},"registered":{"date":"2009-09-01T11:32:09Z","age":9},"phone":"(246)-489-4965","cell":"(363)-649-8499","id":{"name":"SSN","value":"695-58-4679"},"picture":{"large":"https://randomuser.me/api/portraits/women/20.jpg","medium":"https://randomuser.me/api/portraits/med/women/20.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/20.jpg"},"nat":"US"},{"gender":"female","name":{"title":"ms","first":"martha","last":"payne"},"location":{"street":"6464 smokey ln","city":"everett","state":"florida","postcode":81596,"coordinates":{"latitude":"-70.8708","longitude":"151.8925"},"timezone":{"offset":"-5:00","description":"Eastern Time (US & Canada), Bogota, Lima"}},"email":"martha.payne@example.com","login":{"uuid":"29307098-c8d8-4f77-9a8e-5c9c3f8fd1de","username":"goldenbutterfly521","password":"spurs","salt":"91WJSevi","md5":"e8332f4a8f97f9c9c58b423cf12a18a1","sha1":"694987dcdbe93482c8d829f6c7fd0112cdafc853","sha256":"4c8fb06192da3429c27fdcad967dc36eeda6ccd1ff920787a6b66979539256ef"},"dob":{"date":"1997-01-22T08:45:04Z","age":22},"registered":{"date":"2007-02-18T09:15:16Z","age":12},"phone":"(961)-721-4288","cell":"(203)-752-3080","id":{"name":"SSN","value":"660-13-3585"},"picture":{"large":"https://randomuser.me/api/portraits/women/12.jpg","medium":"https://randomuser.me/api/portraits/med/women/12.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/12.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"vanessa","last":"foster"},"location":{"street":"5242 valley view ln","city":"flowermound","state":"tennessee","postcode":13558,"coordinates":{"latitude":"-85.6240","longitude":"-131.0245"},"timezone":{"offset":"-7:00","description":"Mountain Time (US & Canada)"}},"email":"vanessa.foster@example.com","login":{"uuid":"9bc45854-75b0-4002-b7f1-207081c92147","username":"goldenfish245","password":"goodbye","salt":"rGDJdSdC","md5":"eb0fe1df0a4f568524f01e07720d97ae","sha1":"f8ebe8f696e7b1ac84153734e3463a773649dec4","sha256":"057148219aa40967fc53c10d2c777acc62fb7a01a9a0faf855383a84afd32a26"},"dob":{"date":"1946-02-03T01:37:36Z","age":73},"registered":{"date":"2014-10-30T00:27:30Z","age":4},"phone":"(333)-737-3434","cell":"(273)-210-7504","id":{"name":"SSN","value":"446-57-6375"},"picture":{"large":"https://randomuser.me/api/portraits/women/46.jpg","medium":"https://randomuser.me/api/portraits/med/women/46.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/46.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"carrie","last":"jackson"},"location":{"street":"1271 depaul dr","city":"irving","state":"missouri","postcode":25869,"coordinates":{"latitude":"67.9532","longitude":"36.4129"},"timezone":{"offset":"+7:00","description":"Bangkok, Hanoi, Jakarta"}},"email":"carrie.jackson@example.com","login":{"uuid":"51bc608a-668c-44df-8d63-dd866747ebc0","username":"redostrich116","password":"big1","salt":"NinaLzHv","md5":"6b73f24b67a1ff6d292749ecc502201c","sha1":"d3f87c45e97c9caf73deff71777b2bb9490e4137","sha256":"ae66c90e79829d77586e6d311536189d16e5b468654b89117f4aa8884d643591"},"dob":{"date":"1987-10-26T17:49:57Z","age":31},"registered":{"date":"2009-09-25T20:19:24Z","age":9},"phone":"(645)-827-0581","cell":"(396)-798-4186","id":{"name":"SSN","value":"022-10-5733"},"picture":{"large":"https://randomuser.me/api/portraits/women/2.jpg","medium":"https://randomuser.me/api/portraits/med/women/2.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/2.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"shawn","last":"alvarez"},"location":{"street":"1528 wycliff ave","city":"sunnyvale","state":"colorado","postcode":79015,"coordinates":{"latitude":"-61.7165","longitude":"-66.1029"},"timezone":{"offset":"+5:00","description":"Ekaterinburg, Islamabad, Karachi, Tashkent"}},"email":"shawn.alvarez@example.com","login":{"uuid":"b3b78b9e-6031-4bf5-bf39-8af090c17cc7","username":"heavyfrog857","password":"deville","salt":"DUZNI09N","md5":"57113c879b9131ede5e5951597e96acb","sha1":"be6fed8602d1558635dd7dbc6b0d4d69e2e2321a","sha256":"eb64a400a16f6b3ae1faee72e95d6fd8bda6c5c23ec28cfbe658d98c6c66981f"},"dob":{"date":"1968-04-17T22:06:24Z","age":51},"registered":{"date":"2008-05-11T07:17:35Z","age":10},"phone":"(771)-035-3479","cell":"(455)-696-0665","id":{"name":"SSN","value":"754-53-0298"},"picture":{"large":"https://randomuser.me/api/portraits/men/81.jpg","medium":"https://randomuser.me/api/portraits/med/men/81.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/81.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"patsy","last":"smith"},"location":{"street":"7754 w campbell ave","city":"wilmington","state":"illinois","postcode":96838,"coordinates":{"latitude":"79.6094","longitude":"76.3306"},"timezone":{"offset":"+3:30","description":"Tehran"}},"email":"patsy.smith@example.com","login":{"uuid":"9306869e-7a3e-43ed-be96-799f5198213e","username":"bluefrog375","password":"chester1","salt":"ExfF8UBc","md5":"deafa4c572a916c9d636bee3bbb73b1b","sha1":"2d356d85f67985949dd1f073267404866d71abcc","sha256":"2afc6e1c73a8362188f9d5a27658b808373cbacaca30960aa4a0a1e54f8cb466"},"dob":{"date":"1991-09-26T13:40:41Z","age":27},"registered":{"date":"2003-02-12T18:16:14Z","age":16},"phone":"(067)-963-6902","cell":"(886)-454-4615","id":{"name":"SSN","value":"804-72-4306"},"picture":{"large":"https://randomuser.me/api/portraits/women/9.jpg","medium":"https://randomuser.me/api/portraits/med/women/9.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/9.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"lorraine","last":"terry"},"location":{"street":"9056 ash dr","city":"albuquerque","state":"vermont","postcode":76042,"coordinates":{"latitude":"7.6486","longitude":"113.1965"},"timezone":{"offset":"+2:00","description":"Kaliningrad, South Africa"}},"email":"lorraine.terry@example.com","login":{"uuid":"2c048319-3318-402a-9be3-6976b6465555","username":"brownladybug896","password":"bigpimp","salt":"r41AsBpv","md5":"2963b37e506afafab6ad6117edc176c8","sha1":"28667b5bcc8305208d392b1c1dd857450a527d04","sha256":"36b6b4a8d451fceb0ff7ba9a370cded707a4c61c2510e8e14fd5c62221246ccf"},"dob":{"date":"1966-11-11T12:11:41Z","age":52},"registered":{"date":"2007-07-31T21:26:38Z","age":11},"phone":"(468)-306-2488","cell":"(015)-720-8710","id":{"name":"SSN","value":"885-48-7809"},"picture":{"large":"https://randomuser.me/api/portraits/women/75.jpg","medium":"https://randomuser.me/api/portraits/med/women/75.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/75.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"gloria","last":"wallace"},"location":{"street":"7695 w pecan st","city":"celina","state":"ohio","postcode":67498,"coordinates":{"latitude":"-60.7723","longitude":"1.6216"},"timezone":{"offset":"+9:30","description":"Adelaide, Darwin"}},"email":"gloria.wallace@example.com","login":{"uuid":"db4191da-daf1-46d8-8858-5144892c3067","username":"ticklishtiger307","password":"womam","salt":"fQzObGLY","md5":"49505e9a2a8f5219d8c6b9337b93ed9e","sha1":"5645d868b1b612bfcd8a261c382da0d618af3ca3","sha256":"5560db3b4ae1ee09eb56eaa54e98a731be62b383bced905421aa982bbd381f4c"},"dob":{"date":"1980-10-27T21:11:30Z","age":38},"registered":{"date":"2015-12-04T15:48:34Z","age":3},"phone":"(724)-327-8888","cell":"(080)-735-1689","id":{"name":"SSN","value":"041-88-2425"},"picture":{"large":"https://randomuser.me/api/portraits/women/45.jpg","medium":"https://randomuser.me/api/portraits/med/women/45.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/45.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"catherine","last":"fields"},"location":{"street":"294 photinia ave","city":"elgin","state":"utah","postcode":26988,"coordinates":{"latitude":"-18.2063","longitude":"-107.2226"},"timezone":{"offset":"+9:30","description":"Adelaide, Darwin"}},"email":"catherine.fields@example.com","login":{"uuid":"14624272-3ca7-429b-b9ef-6bfaabf4bf31","username":"beautifulcat607","password":"woody1","salt":"wVh1PacX","md5":"9321ff4cd17a5857756b97309a572f58","sha1":"6b74f3586a732379a4fc5b02cf8890f8352cacd4","sha256":"56e2f112f7607cc712049198db61373bf74d66756a7e2ac156095ec68ff06268"},"dob":{"date":"1951-08-09T04:24:31Z","age":67},"registered":{"date":"2005-06-29T03:43:32Z","age":13},"phone":"(390)-302-8656","cell":"(775)-893-9360","id":{"name":"SSN","value":"609-53-5915"},"picture":{"large":"https://randomuser.me/api/portraits/women/42.jpg","medium":"https://randomuser.me/api/portraits/med/women/42.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/42.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"clayton","last":"jennings"},"location":{"street":"6613 poplar dr","city":"richmond","state":"maine","postcode":54278,"coordinates":{"latitude":"39.4658","longitude":"-54.1005"},"timezone":{"offset":"+5:45","description":"Kathmandu"}},"email":"clayton.jennings@example.com","login":{"uuid":"121f08ae-60d0-48ab-9062-8cc481f22138","username":"greengorilla490","password":"beacon","salt":"nc3v8f5Z","md5":"9d4f1f6c192d354926ca319fcf636eac","sha1":"961cc24a840603bec0d11a38b2ba58e90ebf58ed","sha256":"769512b7f7d15a76191aee236dfe62721ce8692446c4768eaf064442f98c0478"},"dob":{"date":"1945-06-29T00:02:51Z","age":73},"registered":{"date":"2002-12-01T08:15:46Z","age":16},"phone":"(996)-440-1799","cell":"(716)-673-5511","id":{"name":"SSN","value":"532-49-8770"},"picture":{"large":"https://randomuser.me/api/portraits/men/67.jpg","medium":"https://randomuser.me/api/portraits/med/men/67.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/67.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"felicia","last":"jacobs"},"location":{"street":"5172 lovers ln","city":"red oak","state":"connecticut","postcode":64087,"coordinates":{"latitude":"-15.7886","longitude":"152.6629"},"timezone":{"offset":"-8:00","description":"Pacific Time (US & Canada)"}},"email":"felicia.jacobs@example.com","login":{"uuid":"b46876d1-4f24-493f-8ce8-b227236e8043","username":"bluedog678","password":"enterprise","salt":"qtYZfujh","md5":"7e402d1444e5247774282bc08ab68688","sha1":"173aea89ac2410498251335676e8dff9df18229c","sha256":"d646f2f76dc94aa9d87a75bd012b52b1feff9de632c1f0f0b8b281d62a986a27"},"dob":{"date":"1958-08-01T02:07:53Z","age":60},"registered":{"date":"2015-02-27T07:24:13Z","age":4},"phone":"(453)-690-3782","cell":"(934)-523-1402","id":{"name":"SSN","value":"167-84-9919"},"picture":{"large":"https://randomuser.me/api/portraits/women/93.jpg","medium":"https://randomuser.me/api/portraits/med/women/93.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/93.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"constance","last":"dean"},"location":{"street":"2192 edwards rd","city":"norman","state":"iowa","postcode":22649,"coordinates":{"latitude":"-65.7143","longitude":"45.8298"},"timezone":{"offset":"+11:00","description":"Magadan, Solomon Islands, New Caledonia"}},"email":"constance.dean@example.com","login":{"uuid":"14cd18fe-44b7-4c8c-a568-1984e24c891a","username":"whitedog470","password":"jimbob","salt":"vbiPXNn2","md5":"e2933576b3c2572c7a547f3c9d06ace3","sha1":"09ba3c9d1f6d3dca74d92dcf7058bfd003d25309","sha256":"28b592eaada0365d9a3db4f0a7f3e0c4f2a56e83e9a3dc8013de246e2c697c0f"},"dob":{"date":"1988-05-16T04:05:57Z","age":30},"registered":{"date":"2014-09-29T13:40:55Z","age":4},"phone":"(660)-015-4337","cell":"(207)-899-3879","id":{"name":"SSN","value":"754-17-5512"},"picture":{"large":"https://randomuser.me/api/portraits/women/77.jpg","medium":"https://randomuser.me/api/portraits/med/women/77.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/77.jpg"},"nat":"US"},{"gender":"female","name":{"title":"mrs","first":"vicki","last":"henry"},"location":{"street":"8742 oak ridge ln","city":"tulsa","state":"new hampshire","postcode":71142,"coordinates":{"latitude":"70.2570","longitude":"-128.8698"},"timezone":{"offset":"-8:00","description":"Pacific Time (US & Canada)"}},"email":"vicki.henry@example.com","login":{"uuid":"31e2ca5e-fbe0-48ec-93e9-11ab7f2d1e58","username":"yellowpanda793","password":"volume","salt":"3uZ9q5Hh","md5":"8e67a654aaabb4da8497d9fba884d4c0","sha1":"5f51b7ce8702eb93e27290fe708a4f0816ecb213","sha256":"d05628531bc26fe1199fbb03630a08e69723cef7599010c007d9d20b8c79255b"},"dob":{"date":"1994-09-22T00:24:34Z","age":24},"registered":{"date":"2002-03-26T16:45:46Z","age":17},"phone":"(179)-468-9058","cell":"(657)-877-0983","id":{"name":"SSN","value":"674-80-4537"},"picture":{"large":"https://randomuser.me/api/portraits/women/54.jpg","medium":"https://randomuser.me/api/portraits/med/women/54.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/54.jpg"},"nat":"US"},{"gender":"female","name":{"title":"miss","first":"kristin","last":"carlson"},"location":{"street":"1504 parker rd","city":"carlsbad","state":"north carolina","postcode":60018,"coordinates":{"latitude":"2.5504","longitude":"65.9229"},"timezone":{"offset":"-1:00","description":"Azores, Cape Verde Islands"}},"email":"kristin.carlson@example.com","login":{"uuid":"14fd1792-8d26-4a9d-9d0c-5fce16bbb9e4","username":"tinypeacock988","password":"brandy1","salt":"x4GL9Kev","md5":"e8cda04f2c5600ccb737bf1b7d58a85d","sha1":"413e0a59bfcc5e750be716ab3bf463324740f4ca","sha256":"77e079a61370cd823f45529f65c0e302152819a0ba803109c1344c10b58dc49e"},"dob":{"date":"1962-02-27T19:31:34Z","age":57},"registered":{"date":"2007-01-31T07:27:02Z","age":12},"phone":"(818)-172-3287","cell":"(052)-669-1939","id":{"name":"SSN","value":"494-54-3548"},"picture":{"large":"https://randomuser.me/api/portraits/women/43.jpg","medium":"https://randomuser.me/api/portraits/med/women/43.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/43.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"wyatt","last":"murray"},"location":{"street":"3043 hogan st","city":"aurora","state":"illinois","postcode":23280,"coordinates":{"latitude":"35.7134","longitude":"132.6444"},"timezone":{"offset":"+6:00","description":"Almaty, Dhaka, Colombo"}},"email":"wyatt.murray@example.com","login":{"uuid":"8eeaebde-6f26-4ff9-adf3-1e0c746973a1","username":"orangefrog793","password":"roberta","salt":"ynTdC9QP","md5":"7c4c83dbb744890df3310f02cd5363a4","sha1":"a7fddd293ac2fef16217499a8777b45e321b2947","sha256":"556878bd997ac5cdd217e42d2a688df12f9326c4ba6444168a05a2a936a6079d"},"dob":{"date":"1975-08-21T20:49:31Z","age":43},"registered":{"date":"2017-11-03T12:33:34Z","age":1},"phone":"(364)-323-9339","cell":"(084)-074-1653","id":{"name":"SSN","value":"780-45-6704"},"picture":{"large":"https://randomuser.me/api/portraits/men/38.jpg","medium":"https://randomuser.me/api/portraits/med/men/38.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/38.jpg"},"nat":"US"},{"gender":"male","name":{"title":"mr","first":"rick","last":"holmes"},"location":{"street":"1505 bollinger rd","city":"wichita falls","state":"south carolina","postcode":81891,"coordinates":{"latitude":"-36.9263","longitude":"-154.5656"},"timezone":{"offset":"+3:30","description":"Tehran"}},"email":"rick.holmes@example.com","login":{"uuid":"7cf68697-f55e-4efd-bb75-bd3402842d55","username":"yellowbutterfly878","password":"word","salt":"pze1BVAR","md5":"e3934a946ddd4eb459469f7acf1c279c","sha1":"b61ab0628ef17d0df3e777061a1b1e2128b2625e","sha256":"9db55c32ec4b8fe121cb43de56332d06417869f5cd265adac9900da4e44582f3"},"dob":{"date":"1981-03-17T05:04:45Z","age":38},"registered":{"date":"2008-06-07T13:44:14Z","age":10},"phone":"(975)-418-4393","cell":"(196)-586-4600","id":{"name":"SSN","value":"806-23-0588"},"picture":{"large":"https://randomuser.me/api/portraits/men/96.jpg","medium":"https://randomuser.me/api/portraits/med/men/96.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/96.jpg"},"nat":"US"}]
--------------------------------------------------------------------------------
/react-streaming-ssr/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-streaming-ssr",
3 | "version": "0.0.1",
4 | "main": "server.js",
5 | "scripts": {
6 | "dev": "webpack --hot --watch --info-verbosity none & node -r esm server",
7 | "build": "webpack",
8 | "start": "webpack && node -r esm server"
9 | },
10 | "dependencies": {
11 | "@babel/plugin-syntax-dynamic-import": "^7.2.0",
12 | "clean-terminal-webpack-plugin": "^2.0.2",
13 | "esm": "^3.2.22",
14 | "express": "^4.16.4",
15 | "node-fetch": "^2.3.0",
16 | "react": "^16.8.6",
17 | "react-dom": "^16.8.6",
18 | "regenerator-runtime": "^0.13.2",
19 | "size-plugin": "^1.2.0",
20 | "webpack-merge": "^4.2.1",
21 | "webpackbar": "^3.2.0"
22 | },
23 | "devDependencies": {
24 | "@babel/core": "^7.4.4",
25 | "@babel/preset-env": "^7.4.4",
26 | "@babel/preset-react": "^7.0.0",
27 | "babel-loader": "^8.0.5",
28 | "core-js": "^3.0.1",
29 | "webpack": "^4.30.0",
30 | "webpack-cli": "^3.3.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/react-streaming-ssr/server.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import fetch from 'node-fetch';
3 | import express from 'express';
4 | import ssr from './build/ssr/main.js';
5 | import DATA from './data.json';
6 |
7 | global.fetch = function (url, opts) {
8 | if (url[0] == '/') {
9 | let { address, port } = listener.address();
10 | if (address == '::') address = 'localhost';
11 | url = `http://${address}:${port}${url}`;
12 | }
13 | return fetch(url, opts);
14 | };
15 |
16 | const app = express();
17 |
18 | app.get('/favicon.ico', (req, res) => res.end());
19 |
20 | app.use('/client.js', (req, res) => res.redirect('/build/client.js'));
21 |
22 | // Simulate slow network using an artificial delay for page & resource requests:
23 | const DELAY = 500;
24 | app.use((req, res, next) => {
25 | setTimeout(() => {
26 | next();
27 | }, DELAY);
28 | });
29 |
30 | /** API Proxy */
31 | app.get('/api/users', (req, res) => {
32 | res.json(DATA.map(user => ({
33 | id: user.login.uuid,
34 | username: user.login.username,
35 | name: user.name.first + ' ' + user.name.last
36 | })));
37 | });
38 | app.get('/api/users/:user', (req, res) => {
39 | const user = DATA.filter(user => user.login.uuid === req.params.user || user.login.username === req.params.user)[0];
40 | if (user) res.json(user);
41 | else res.status(404).json({ error: 'user not found' });
42 | });
43 |
44 | const BEFORE = `
45 |
46 |
47 |
48 | `.replace(/\n\s*/g, '');
49 |
50 | /** SSR */
51 | app.get('/', async (request, response) => {
52 | try {
53 | const renderComplete = ssr({
54 | url: request.url,
55 | streaming: false
56 | });
57 | response.useChunkedEncodingByDefault = true;
58 | response.writeHead(200, {
59 | 'content-type': 'text/html',
60 | 'content-transfer-encoding': 'chunked',
61 | 'x-content-type-options': 'nosniff'
62 | });
63 | response.write(BEFORE);
64 | response.flushHeaders();
65 | const html = await renderComplete;
66 | response.write(html);
67 | response.write('
');
68 | response.end();
69 | }
70 | catch (err) {
71 | if (!response.headersSent) {
72 | response.writeHead(500, {
73 | // @see https://twitter.com/_developit/status/1123041336054177792
74 | 'content-type': 'text/pain'
75 | });
76 | }
77 | response.end(String(err && err.stack || err));
78 | }
79 | });
80 |
81 | app.get('/streaming', async (request, response) => {
82 | try {
83 | const stream = await ssr({
84 | url: request.url
85 | });
86 | // Wait until data starts flowing to send a 200 OK,
87 | // so errors don't trigger "headers already sent".
88 | const start = Date.now();
89 | stream.on('data', function handleData() {
90 | console.log('Render Start: ', Date.now() - start);
91 | stream.off('data', handleData);
92 | response.useChunkedEncodingByDefault = true;
93 | response.writeHead(200, {
94 | 'content-type': 'text/html',
95 | 'content-transfer-encoding': 'chunked',
96 | 'x-content-type-options': 'nosniff'
97 | });
98 | response.write(BEFORE);
99 | response.flushHeaders();
100 | });
101 | await new Promise((resolve, reject) => {
102 | stream.on('error', err => {
103 | stream.unpipe(response);
104 | reject(err);
105 | });
106 | stream.on('end', () => {
107 | console.log('Render End: ', Date.now() - start);
108 | response.write('