├── Procfile ├── src ├── marko.json ├── layouts │ └── default │ │ ├── browser.json │ │ ├── style.less │ │ └── index.marko ├── components │ ├── app-overlay │ │ ├── marko-tag.json │ │ ├── index.marko │ │ ├── style.less │ │ └── component.js │ ├── app │ │ ├── style.less │ │ ├── component.js │ │ └── index.marko │ ├── app-notification │ │ ├── index.marko │ │ ├── component.js │ │ └── style.less │ ├── app-tabs │ │ ├── marko-tag.json │ │ ├── style.less │ │ └── index.marko │ ├── app-markdown │ │ ├── marko-tag.json │ │ └── code-generator.js │ ├── app-sections │ │ ├── marko-tag.json │ │ ├── style.less │ │ └── index.marko │ ├── app-checkbox │ │ ├── marko-tag.json │ │ ├── images │ │ │ ├── unchecked.svg │ │ │ └── checked.svg │ │ ├── style.less │ │ └── index.marko │ ├── app-state-select │ │ ├── CA.png │ │ ├── CO.png │ │ └── index.marko │ ├── app-progress-bar │ │ ├── marko-tag.json │ │ ├── index.marko │ │ ├── style.less │ │ └── component.js │ ├── app-map │ │ ├── marko-tag.json │ │ ├── browser.json │ │ └── index.marko │ ├── app-fetch-data │ │ ├── style.less │ │ ├── index.marko │ │ └── loading.svg │ ├── app-notifications │ │ ├── index.marko │ │ └── component.js │ ├── app-button │ │ ├── marko-tag.json │ │ ├── style.less │ │ └── index.marko │ └── app-number-spinner │ │ ├── index.marko │ │ └── style.css ├── services │ ├── package.json │ ├── users-browser.js │ ├── routes.js │ ├── users.js │ └── mock-users-data.json ├── global-style │ ├── browser.json │ ├── variables.less │ └── style.less └── pages │ └── home │ ├── browser.json │ ├── index.js │ └── template.marko ├── .browser-refresh-ignore ├── README.md ├── .gitignore ├── .jshintrc ├── package.json └── server.js /Procfile: -------------------------------------------------------------------------------- 1 | web: node server.js -------------------------------------------------------------------------------- /src/marko.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags-dir": "./components" 3 | } -------------------------------------------------------------------------------- /.browser-refresh-ignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /static 3 | *.marko.js 4 | .* -------------------------------------------------------------------------------- /src/layouts/default/browser.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | "./style.less" 4 | ] 5 | } -------------------------------------------------------------------------------- /src/components/app-overlay/marko-tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "@width": "integer", 3 | "@visible": "boolean" 4 | } -------------------------------------------------------------------------------- /src/components/app/style.less: -------------------------------------------------------------------------------- 1 | .render-target { 2 | padding-top: 1em; 3 | padding-bottom: 1em; 4 | } -------------------------------------------------------------------------------- /src/components/app-notification/index.marko: -------------------------------------------------------------------------------- 1 |
2 | $!{data.message} 3 |
-------------------------------------------------------------------------------- /src/components/app-tabs/marko-tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "@tabs []": { 3 | "@label": "string" 4 | } 5 | } -------------------------------------------------------------------------------- /src/services/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "browser": { 3 | "./users.js": "./users-browser.js" 4 | } 5 | } -------------------------------------------------------------------------------- /src/components/app-markdown/marko-tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "body": "static-text", 3 | "preserve-whitespace": true 4 | } -------------------------------------------------------------------------------- /src/components/app-sections/marko-tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "@sections
[]": { 3 | "@title": "string" 4 | } 5 | } -------------------------------------------------------------------------------- /src/layouts/default/style.less: -------------------------------------------------------------------------------- 1 | .container { 2 | margin-left: auto; 3 | margin-right: auto; 4 | width: 800px; 5 | } -------------------------------------------------------------------------------- /src/global-style/browser.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | "less-import: variables.less", 4 | "style.less" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/components/app-checkbox/marko-tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "@label": "string", 3 | "@data": "expression", 4 | "@checked": "boolean", 5 | "@class": "string" 6 | } -------------------------------------------------------------------------------- /src/components/app-state-select/CA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marko-js-samples/ui-components-playground-lasso-express/HEAD/src/components/app-state-select/CA.png -------------------------------------------------------------------------------- /src/components/app-state-select/CO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marko-js-samples/ui-components-playground-lasso-express/HEAD/src/components/app-state-select/CO.png -------------------------------------------------------------------------------- /src/components/app-progress-bar/marko-tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "@steps []": { 3 | "@name": "string", 4 | "@label": "string", 5 | "@active": "boolean" 6 | } 7 | } -------------------------------------------------------------------------------- /src/components/app-map/marko-tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "@height": "string", 3 | "@width": "string", 4 | "@static": "boolean", 5 | "@class": "string", 6 | "@lat": "number", 7 | "@lng": "number" 8 | } 9 | -------------------------------------------------------------------------------- /src/pages/home/browser.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | "~/src/layouts/default/browser.json", 4 | "~/src/global-style/browser.json", 5 | "require: ~/src/components/app" 6 | ] 7 | } -------------------------------------------------------------------------------- /src/pages/home/index.js: -------------------------------------------------------------------------------- 1 | var template = require('./template.marko'); 2 | 3 | module.exports = function(req, res) { 4 | res.setHeader('Content-Type', 'text/html; charset=utf-8'); 5 | res.marko(template, {}); 6 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Marko UI Components Playground 2 | ================================== 3 | 4 | ```bash 5 | git clone https://github.com/marko-js-samples/ui-components-playground.git 6 | cd ui-components-playground 7 | npm install 8 | node server.js 9 | ``` 10 | -------------------------------------------------------------------------------- /src/pages/home/template.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <@title> 5 | Marko UI Components Playground 6 | 7 | <@body> 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/services/users-browser.js: -------------------------------------------------------------------------------- 1 | require('whatwg-fetch'); 2 | 3 | exports.getUsers = function(options) { 4 | return fetch('/services/users?pageIndex=' + (options.pageIndex || 0)) 5 | .then(function(response) { 6 | return response.json(); 7 | }); 8 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.seed 2 | *.log 3 | *.csv 4 | *.dat 5 | *.out 6 | *.pid 7 | *.gz 8 | *.marko.js 9 | *.sublime-workspace 10 | *.sublime-project 11 | *.original 12 | 13 | /lib-cov 14 | /pids 15 | /logs 16 | /results 17 | /static 18 | /build 19 | /.cache 20 | /node_modules 21 | 22 | npm-debug.log 23 | .DS_Store -------------------------------------------------------------------------------- /src/components/app-fetch-data/style.less: -------------------------------------------------------------------------------- 1 | .app-fetch-data .loading { 2 | background-image: url('./loading.svg'); 3 | width: 64px; 4 | height: 64px; 5 | display: inline-block; 6 | vertical-align: middle; 7 | } 8 | 9 | .app-fetch-data .table-container { 10 | max-height: 400px; 11 | overflow: auto; 12 | } -------------------------------------------------------------------------------- /src/components/app-map/browser.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | { 4 | "type": "js", 5 | "url": "https://maps.googleapis.com/maps/api/js" 6 | }, 7 | { 8 | "type": "css", 9 | "url": "https://fonts.googleapis.com/css?family=Open+Sans:300,400,700" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /src/components/app-notifications/index.marko: -------------------------------------------------------------------------------- 1 | style.less { 2 | .app-notifications { 3 | position: fixed; 4 | top: 0px; 5 | width: 500px; 6 | left: 50%; 7 | margin-left: -250px; 8 | } 9 | } 10 | 11 |
12 | 13 | 14 | 15 |
-------------------------------------------------------------------------------- /src/components/app-sections/style.less: -------------------------------------------------------------------------------- 1 | .app-sections { 2 | 3 | } 4 | .tableOfContents { 5 | position: fixed; 6 | right: 15px; 7 | top: 15px; 8 | background-color: #f7f7f9; 9 | box-shadow: 4px 4px 4px rgba(0,0,0,0.2); 10 | padding: 1em; 11 | } 12 | 13 | .app-sections .section { 14 | margin-top: 40px; 15 | } 16 | 17 | .app-sections .section > h2 { 18 | border-bottom: 1px solid #c0c0c0; 19 | margin-bottom: 0.5em; 20 | } -------------------------------------------------------------------------------- /src/global-style/variables.less: -------------------------------------------------------------------------------- 1 | @medium-color: #2980b9; 2 | @light-color: lighten(@medium-color, 35%); 3 | @dark-color: darken(@medium-color, 25%); 4 | 5 | @link-color: @medium-color; 6 | 7 | @font-color: #333; 8 | @font-family: "HelveticaNeue-Light","Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,sans-serif; 9 | 10 | @button-bg: @medium-color; 11 | @button-fg: #fff; 12 | 13 | @button-secondary-bg: #999999; 14 | @button-secondary-fg: #fff; 15 | 16 | -------------------------------------------------------------------------------- /src/components/app-button/marko-tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "@label": "string", 3 | "@href": "string", 4 | "@variant": { 5 | "type": "string", 6 | "enum": [ 7 | "primary", 8 | "secondary" 9 | ] 10 | }, 11 | "@size": { 12 | "type": "string", 13 | "enum": [ 14 | "small", 15 | "normal", 16 | "large" 17 | ] 18 | }, 19 | "@class": { 20 | "type": "string", 21 | "description": "Additional CSS class names" 22 | }, 23 | "@*": "string" 24 | } -------------------------------------------------------------------------------- /src/components/app-markdown/code-generator.js: -------------------------------------------------------------------------------- 1 | var marked = require('marked'); 2 | 3 | function removeIndentation(str) { 4 | var indentMatches = /\s*\n(\s+)/.exec(str); 5 | if (indentMatches) { 6 | var indent = indentMatches[1]; 7 | str = str.replace(new RegExp('^' + indent, 'mg'), ''); 8 | } 9 | return str; 10 | } 11 | 12 | module.exports = function(el, codegen) { 13 | var bodyText = removeIndentation(el.bodyText); 14 | var builder = codegen.builder; 15 | var html = marked(bodyText); 16 | return builder.html(builder.literal(html)); 17 | }; -------------------------------------------------------------------------------- /src/components/app-notification/component.js: -------------------------------------------------------------------------------- 1 | require('./style.less'); 2 | 3 | module.exports = { 4 | onInput: function(input) { 5 | this.state = { 6 | timeout: input.timeout, 7 | message: input.message 8 | }; 9 | }, 10 | 11 | onMount: function() { 12 | var el = this.el; 13 | setTimeout(function() { 14 | el.style.opacity = 1; 15 | el.style.maxHeight = '60px'; 16 | }, 10); 17 | }, 18 | 19 | fadeOut: function(callback) { 20 | var el = this.el; 21 | el.style.opacity = 0; 22 | setTimeout(callback, 300); 23 | } 24 | }; -------------------------------------------------------------------------------- /src/components/app-checkbox/images/unchecked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/components/app-checkbox/style.less: -------------------------------------------------------------------------------- 1 | .app-button.app-checkbox { 2 | background-color: @button-secondary-bg; 3 | color: @button-secondary-fg; 4 | } 5 | 6 | .app-button.app-checkbox.checked { 7 | background-color: @button-bg; 8 | color: @button-fg; 9 | } 10 | 11 | .app-checkbox-icon { 12 | background-image: url(./images/unchecked.svg); 13 | background-size: contain; 14 | width: 18px; 15 | height: 18px; 16 | display: inline-block; 17 | background-repeat: no-repeat; 18 | opacity: 0.2; 19 | margin-right: 4px; 20 | } 21 | 22 | .app-checkbox.checked .app-checkbox-icon { 23 | background-image: url(./images/checked.svg); 24 | opacity: 1.0; 25 | } -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node" : true, 3 | "esnext" : true, 4 | "browser" : true, 5 | "boss" : false, 6 | "curly": false, 7 | "debug": false, 8 | "devel": false, 9 | "eqeqeq": true, 10 | "evil": true, 11 | "forin": false, 12 | "immed": true, 13 | "laxbreak": false, 14 | "newcap": true, 15 | "noarg": true, 16 | "noempty": false, 17 | "nonew": true, 18 | "nomen": false, 19 | "onevar": false, 20 | "plusplus": false, 21 | "regexp": false, 22 | "undef": true, 23 | "sub": true, 24 | "white": false, 25 | "eqeqeq": false, 26 | "latedef": true, 27 | "unused": "vars", 28 | "strict": false, 29 | "eqnull": true 30 | } -------------------------------------------------------------------------------- /src/components/app-notification/style.less: -------------------------------------------------------------------------------- 1 | @notification-bg: #2ecc71; 2 | @notification-border-color: darken(@notification-bg, 20%); 3 | 4 | .app-notification { 5 | opacity: 0; 6 | transition-property: max-height, opacity; 7 | transition-duration: .3s; 8 | transition-timing-function: ease-out; 9 | max-height: 0px; 10 | margin-top: 8px; 11 | background-color: @notification-bg; 12 | color: white; 13 | width: 100%; 14 | border: 2px solid @notification-border-color; 15 | padding-left: 1em; 16 | padding-right: 1em; 17 | line-height: 40px; 18 | vertical-align: middle; 19 | border-radius: 4px; 20 | box-shadow: 3px 3px 3px rgba(51, 65, 80, 0.35); 21 | } -------------------------------------------------------------------------------- /src/services/routes.js: -------------------------------------------------------------------------------- 1 | var usersService = require('./users'); 2 | 3 | module.exports = function(app) { 4 | app.get('/services/users', function(req, res) { 5 | var pageIndex = req.query.pageIndex; 6 | if (typeof pageIndex === 'string') { 7 | pageIndex = parseInt(pageIndex, 10); 8 | } else { 9 | pageIndex = 0; 10 | } 11 | 12 | usersService.getUsers({ pageIndex: pageIndex }) 13 | .then(function(data) { 14 | res.json(data); 15 | }) 16 | .catch(function(err) { 17 | console.log(err); 18 | res.status(500).send('Unable to load users'); 19 | }); 20 | }); 21 | }; -------------------------------------------------------------------------------- /src/services/users.js: -------------------------------------------------------------------------------- 1 | var mockUsersData = require('./mock-users-data.json'); 2 | 3 | const pageSize = 10; 4 | 5 | exports.getUsers = function(options) { 6 | var pageIndex = options.pageIndex || 0; 7 | var start = pageIndex * pageSize; 8 | 9 | var users = []; 10 | 11 | for (var i=start; i { 22 | setTimeout(function() { 23 | resolve(results); 24 | }, 1000); 25 | }); 26 | }; -------------------------------------------------------------------------------- /src/components/app-overlay/index.marko: -------------------------------------------------------------------------------- 1 |
2 |
4 | 5 |
7 |
8 | 9 |
10 | 21 |
22 |
-------------------------------------------------------------------------------- /src/components/app-checkbox/images/checked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/components/app-sections/index.marko: -------------------------------------------------------------------------------- 1 | import './style.less' 2 | 3 | static function getAnchorName(section) { 4 | if (!section.anchorName) { 5 | section.anchorName = section.title.replace(/[^a-zA-Z]+/g, '-'); 6 | } 7 | 8 | return section.anchorName; 9 | } 10 | 11 |
12 |
13 | 18 |
19 |
20 |
21 |

${section.title}

22 |
23 | 24 |
25 |
26 |
27 |
-------------------------------------------------------------------------------- /src/components/app-button/style.less: -------------------------------------------------------------------------------- 1 | .app-button { 2 | display: inline-block; 3 | border-radius: 8px; 4 | padding: 12px; 5 | background-color: @button-bg; 6 | color: @button-fg; 7 | 8 | transition-property: background-color; 9 | transition-duration: .3s; 10 | transition-timing-function: ease-out; 11 | } 12 | 13 | .app-button:hover { 14 | background-color: lighten(@button-bg, 10%); 15 | } 16 | 17 | 18 | /* Variants */ 19 | .app-button-secondary { 20 | background-color: @button-secondary-bg; 21 | color: @button-secondary-fg; 22 | } 23 | 24 | .app-button-secondary:hover { 25 | background-color: lighten(@button-secondary-bg, 10%); 26 | } 27 | 28 | /* Sizes */ 29 | .app-button-small { 30 | font-size: 0.9em; 31 | padding-top: 6px; 32 | padding-bottom: 6px; 33 | } 34 | 35 | .app-button-large { 36 | font-size: 1.2em; 37 | font-weight: 100; 38 | } -------------------------------------------------------------------------------- /src/components/app-progress-bar/index.marko: -------------------------------------------------------------------------------- 1 |
2 | 3 |
5 | 6 | 7 | 8 |
9 |
10 |
11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 |
-------------------------------------------------------------------------------- /src/layouts/default/index.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <include(data.title)/> 7 | 8 | 9 | 12 | 13 | 14 | 15 |
16 |

17 | 18 |

19 | 20 |
21 | 22 |
23 |
24 | 25 | 28 | 29 | 30 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/components/app-map/index.marko: -------------------------------------------------------------------------------- 1 | class { 2 | onMount() { 3 | var el = this.el; 4 | var google = window.google; 5 | 6 | var lat = this.input.lat; 7 | var lng = this.input.lng; 8 | 9 | // If there is no internet connection then 10 | // the Google Maps API will fail to load and 11 | // window.google will be undefined 12 | if (google && google.maps && google.maps.Map) { 13 | var Map = google.maps.Map; 14 | var LatLng = google.maps.LatLng; 15 | 16 | this._map = new Map(el, { 17 | zoom: 8, 18 | center: new LatLng( 19 | lat, 20 | lng) 21 | }); 22 | } else { 23 | this.innerHTML = 'Failed to load Google Maps API. Is your internet connection working?'; 24 | } 25 | } 26 | } 27 | 28 | $ var height=input.height 29 | $ var width=input.width 30 | 31 |
32 |
33 | -------------------------------------------------------------------------------- /src/components/app-button/index.marko: -------------------------------------------------------------------------------- 1 | class { 2 | onInput(input) { 3 | return { 4 | size: input.size || 'normal', 5 | variant: input.variant || 'primary', 6 | body: input.label || input.renderBody, 7 | className: input['class'] 8 | }; 9 | } 10 | 11 | handleClick(event) { 12 | // Every Widget instance is also an EventEmitter instance. 13 | // We will emit a custom "click" event when a DOM click event 14 | // is triggered 15 | this.emit('click', { 16 | event: event // Pass along the DOM event in case it is helpful to others 17 | }); 18 | } 19 | } 20 | 21 | $ var variantClassName = (input.variant !== 'primary' && 'app-button-' + input.variant); 22 | $ var sizeClassName = (input.size !== 'normal' && 'app-button-' + input.size); 23 | 24 | -------------------------------------------------------------------------------- /src/components/app-number-spinner/index.marko: -------------------------------------------------------------------------------- 1 | import './style.css' 2 | 3 | static function getClassNameForValue(value) { 4 | if (value < 0) { 5 | return 'negative'; 6 | } else if (value > 0) { 7 | return 'positive'; 8 | } 9 | } 10 | 11 | class { 12 | onInput(input) { 13 | var value = input.value || 0; 14 | 15 | this.state = { 16 | value: value 17 | }; 18 | } 19 | 20 | handleIncrementClick(delta) { 21 | this.state.value += delta; 22 | } 23 | 24 | handleInputKeyUp(event, el) { 25 | var newValue = el.value; 26 | if (/^-?[0-9]+$/.test(newValue)) { 27 | this.state.value = parseInt(newValue, 10); 28 | } 29 | } 30 | } 31 | 32 | $ var value=state.value; 33 | 34 |
35 | 36 | 39 | 40 | 42 | 43 | 46 | 47 |
-------------------------------------------------------------------------------- /src/components/app-tabs/style.less: -------------------------------------------------------------------------------- 1 | .app-tabs .tab { 2 | 3 | } 4 | 5 | .app-tabs ul.tab-nav { 6 | padding-left: 0; 7 | list-style: none; 8 | } 9 | 10 | .app-tabs ul.tab-nav > li { 11 | float: left; 12 | } 13 | 14 | .app-tabs ul.tab-nav > li > a { 15 | margin-right: 2px; 16 | line-height: 1.42857143; 17 | border: 1px solid @button-secondary-bg; 18 | margin-left: 10px; 19 | border-radius: 4px 4px 0 0; 20 | padding-left: 1em; 21 | padding-right: 1em; 22 | padding-bottom: 0.5em; 23 | padding-top: 0.5em; 24 | display: inline-block; 25 | margin-bottom: -1px; 26 | background-color: @button-secondary-bg; 27 | color: @button-secondary-fg; 28 | } 29 | 30 | .app-tabs ul.tab-nav > li:first-child > a { 31 | margin-left: 0px; 32 | } 33 | 34 | .app-tabs .tab.active > a { 35 | background-color: transparent; 36 | border-bottom: 1px solid white; 37 | color: inherit; 38 | } 39 | 40 | .app-tabs .tab-panes { 41 | clear: both; 42 | 43 | } 44 | 45 | .app-tabs .tab-pane { 46 | display: none; 47 | border: 1px solid @button-secondary-bg; 48 | padding: 1em; 49 | } 50 | 51 | .app-tabs .tab-pane.active { 52 | display: block; 53 | } -------------------------------------------------------------------------------- /src/components/app-number-spinner/style.css: -------------------------------------------------------------------------------- 1 | .number-spinner button { 2 | background: #4285f4; 3 | color: #ffffff; 4 | border: 1px solid #1266f1; 5 | display: inline-block; 6 | padding: 12px 32px; 7 | height: 26px; 8 | line-height: 26px; 9 | vertical-align: middle; 10 | text-align: center; 11 | font-family: Helvetica, sans-serif; 12 | font-weight: 600; 13 | font-size: 16px; 14 | outline: 0; 15 | transition: none; 16 | margin: 0; 17 | padding: 0; 18 | padding-left: 13px; 19 | padding-right: 13px; 20 | cursor: pointer; 21 | } 22 | 23 | .number-spinner input { 24 | background: #fff; 25 | border: 1px solid #1266f1; 26 | display: inline-block; 27 | height: 26px; 28 | line-height: 26px; 29 | vertical-align: middle; 30 | text-align: center; 31 | font-family: Helvetica, sans-serif; 32 | font-weight: 600; 33 | font-size: 16px; 34 | outline: 0; 35 | transition: none; 36 | margin: 0; 37 | padding: 0; 38 | padding-left: 13px; 39 | padding-right: 13px; 40 | } 41 | 42 | .number-spinner.positive input { 43 | background: rgb(86, 239, 165); 44 | } 45 | 46 | .number-spinner.negative input { 47 | background: rgb(235, 182, 176); 48 | } -------------------------------------------------------------------------------- /src/components/app-progress-bar/style.less: -------------------------------------------------------------------------------- 1 | .app-progress-bar .progress-step { 2 | display: inline-block; 3 | height: 2em; 4 | } 5 | 6 | .app-progress-bar a.progress-step { 7 | display: inline-block; 8 | background-color: @button-secondary-bg; 9 | color: @button-secondary-fg; 10 | padding-left: 28px; 11 | padding-right: 8px; 12 | height: 2em; 13 | font-size: 1em; 14 | line-height: 2em; 15 | vertical-align: middle; 16 | } 17 | 18 | .app-progress-bar div.progress-step:first-child a.progress-step { 19 | padding-left: 8px; 20 | } 21 | 22 | .app-progress-bar .progress-step.active a.progress-step { 23 | background-color: @button-bg; 24 | color: @button-fg; 25 | } 26 | 27 | div.progress-step-end { 28 | display: inline-block; 29 | width: 20px; 30 | height: 2em; 31 | position: relative; 32 | font-size: 1em; 33 | line-height: 2em; 34 | vertical-align: middle; 35 | margin-right: -20px; 36 | } 37 | 38 | svg.progress-step-end { 39 | display: inline-block; 40 | width: 100%; 41 | height: 100%; 42 | } 43 | 44 | 45 | polygon.progress-step-end { 46 | fill: @button-secondary-bg; 47 | } 48 | 49 | .app-progress-bar .progress-step.active polygon.progress-step-end { 50 | fill: @button-bg; 51 | } -------------------------------------------------------------------------------- /src/components/app-tabs/index.marko: -------------------------------------------------------------------------------- 1 | class { 2 | onInput(input) { 3 | var activeIndex = 0; 4 | 5 | var tabs = input.tabs; 6 | 7 | if (tabs) { 8 | tabs.forEach(function(tab, i) { 9 | if (tab.active) { 10 | activeIndex = i; 11 | } 12 | }); 13 | } 14 | 15 | this.state = { 16 | activeIndex: activeIndex 17 | }; 18 | } 19 | 20 | setActiveIndex(newActiveIndex) { 21 | this.state.activeIndex = newActiveIndex; 22 | } 23 | 24 | handleTabClick(tabIndex, event) { 25 | this.setActiveIndex(tabIndex); 26 | event.preventDefault(); 27 | } 28 | } 29 | 30 |
31 | 40 |
41 |
42 |
44 | 45 |
46 |
47 |
-------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ui-components-playground", 3 | "version": "1.0.0", 4 | "description": "Sample app that demonstrates the power of building UI components using Marko and Marko Widgets", 5 | "main": "server.js", 6 | "scripts": { 7 | "start": "node server.js", 8 | "browser-refresh": "browser-refresh server.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/marko-js-samples/ui-components-playground.git" 13 | }, 14 | "author": "Patrick Steele-idem ", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/marko-js-samples/ui-components-playground/issues" 18 | }, 19 | "homepage": "https://github.com/marko-js-samples/ui-components-playground", 20 | "dependencies": { 21 | "browser-refresh": "^1.7.1", 22 | "browser-refresh-taglib": "^1.1.0", 23 | "compression": "^1.6.2", 24 | "express": "^4.14.0", 25 | "jquery": "^2.2.4", 26 | "lasso": "^2.10.0", 27 | "lasso-less": "^2.4.0", 28 | "lasso-marko": "^2.2.1", 29 | "marked": "^0.3.6", 30 | "marko": "^4.0.0-rc.24", 31 | "minprops": "^1.0.0", 32 | "purecss": "^0.6.2", 33 | "raptor-pubsub": "^1.0.5", 34 | "raptor-util": "^1.1.1", 35 | "require-self-ref": "^2.0.1", 36 | "serve-static": "^1.11.1", 37 | "whatwg-fetch": "^2.0.1" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/components/app-checkbox/index.marko: -------------------------------------------------------------------------------- 1 | class { 2 | 3 | onInput(input) { 4 | this.state = { 5 | checked: input.checked === true, 6 | }; 7 | } 8 | 9 | isChecked() { 10 | return this.state.checked === true; 11 | } 12 | 13 | setChecked(newChecked) { 14 | this.state.checked = newChecked 15 | } 16 | 17 | toggle() { 18 | this.state.checked = !this.state.checked; 19 | } 20 | 21 | getData() { 22 | return this.input.data; 23 | } 24 | 25 | handleClick() { 26 | var newChecked = !this.state.checked; 27 | 28 | var defaultPrevented = false; 29 | 30 | this.emit('toggle', { 31 | checked: newChecked, 32 | data: this.getData(), 33 | preventDefault: function() { 34 | defaultPrevented = true; 35 | } 36 | }); 37 | 38 | if (!defaultPrevented) { 39 | this.state.checked = newChecked; 40 | } 41 | } 42 | } 43 | 44 | 45 | $ var classNames=[ 46 | 'app-checkbox', 47 | input['class'], 48 | state.checked && 'checked' 49 | ]; 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/components/app-progress-bar/component.js: -------------------------------------------------------------------------------- 1 | require('./style.less'); 2 | 3 | module.exports = { 4 | onInput: function(input) { 5 | var steps = input.steps || []; 6 | var activeIndex = 0; 7 | 8 | 9 | steps.forEach(function(step) { 10 | if (step.active) { 11 | activeIndex = steps.length; 12 | } 13 | }); 14 | 15 | this.state = { 16 | steps: steps, 17 | activeIndex: activeIndex 18 | }; 19 | }, 20 | 21 | setCurrentStepIndex: function(index) { 22 | if (this.state.activeIndex === index) { 23 | return; 24 | } 25 | 26 | var defaultPrevented = false; 27 | 28 | this.emit('beforeChange', { 29 | step: this.state.steps[this.state.activeIndex], 30 | preventDefault: function() { 31 | defaultPrevented = true; 32 | } 33 | }); 34 | 35 | if (defaultPrevented) { 36 | return; 37 | } 38 | 39 | var newStep = this.state.steps[index]; 40 | 41 | this.state.activeIndex = index; 42 | 43 | this.emit('change', { 44 | name: newStep.name, 45 | index: index 46 | }); 47 | }, 48 | 49 | handleStepClick: function(stepIndex, event) { 50 | event.preventDefault(); 51 | this.setCurrentStepIndex(stepIndex); 52 | } 53 | }; -------------------------------------------------------------------------------- /src/components/app-state-select/index.marko: -------------------------------------------------------------------------------- 1 | static { 2 | var states = [ 3 | { 4 | name: 'Colorado', 5 | value: 'CO' 6 | }, 7 | { 8 | name: 'California', 9 | value: 'CA' 10 | } 11 | ]; 12 | } 13 | 14 | class { 15 | onInput() { 16 | this.state = { 17 | stateIndex: null 18 | } 19 | } 20 | 21 | handleSelectChange(event, selectEl) { 22 | if (selectEl.selectedIndex === 0) { 23 | this.state.stateIndex = null; 24 | } else { 25 | this.state.stateIndex = selectEl.selectedIndex - 1; 26 | } 27 | } 28 | } 29 | 30 | style.css { 31 | .state-icon { 32 | width: 75px; 33 | height: 50px; 34 | } 35 | 36 | .state-icon.CA { 37 | background-image: url('./CA.png') 38 | } 39 | 40 | .state-icon.CO { 41 | background-image: url('./CO.png') 42 | } 43 | } 44 | 45 |
46 |

Choose a state

47 | 55 | 56 |
57 | You selected: 58 |
59 |
60 |
-------------------------------------------------------------------------------- /src/components/app-notifications/component.js: -------------------------------------------------------------------------------- 1 | var raptorPubsub = require('raptor-pubsub'); 2 | 3 | var nextId = 0; 4 | 5 | module.exports = { 6 | onInput: function() { 7 | this.state = { 8 | notifications: [] 9 | }; 10 | }, 11 | 12 | onMount: function() { 13 | var self = this; 14 | 15 | this.subscribeTo(raptorPubsub) 16 | .on('notification', function(eventArgs) { 17 | var message = eventArgs.message; 18 | self.addNotification(message); 19 | }); 20 | }, 21 | 22 | addNotification: function(message) { 23 | var notifications = this.state.notifications; 24 | var notificationId = 'notification' + (nextId++); 25 | notifications = [ 26 | { 27 | message: message, 28 | id: notificationId 29 | } 30 | ].concat(notifications); 31 | 32 | this.setState('notifications', notifications); 33 | 34 | setTimeout(function() { 35 | this.removeNotification(notificationId); 36 | }.bind(this), 3000); 37 | }, 38 | 39 | removeNotification: function(notificationId) { 40 | var notificationWidget = this.getComponent(notificationId); 41 | notificationWidget.fadeOut(function() { 42 | var notifications = this.state.notifications.filter(function(notification) { 43 | return notification.id !== notificationId; 44 | }); 45 | this.setState('notifications', notifications); 46 | }.bind(this)); 47 | } 48 | }; -------------------------------------------------------------------------------- /src/components/app-overlay/style.less: -------------------------------------------------------------------------------- 1 | .app-overlay > .app-overlay-mask { 2 | position: fixed; 3 | top: 0px; 4 | left: 0px; 5 | right: 0px; 6 | bottom: 0px; 7 | visibility: hidden; 8 | background-color: #000; 9 | opacity: 0; 10 | transition-property: opacity, visibility; 11 | transition-duration: .3s; 12 | transition-timing-function: ease-out; 13 | } 14 | 15 | .app-overlay.visible > .app-overlay-mask { 16 | visibility: visible; 17 | opacity: 0.8; 18 | z-index: 999; 19 | } 20 | 21 | .app-overlay > .app-overlay-container { 22 | position: fixed; 23 | top: -50%; 24 | transform: translateX(-50%) translateY(-50%); 25 | left: 50%; 26 | background-color: white; 27 | opacity: 0; 28 | transition-property: opacity, top; 29 | transition-duration: .2s; 30 | transition-timing-function: ease-out; 31 | border-radius: 5px; 32 | overflow: auto; 33 | z-index: 1000; 34 | } 35 | 36 | .app-overlay.visible > .app-overlay-container { 37 | top: 50%; 38 | opacity: 1; 39 | } 40 | 41 | .app-overlay-body { 42 | padding: 1em; 43 | } 44 | 45 | .app-overlay-footer { 46 | width: 100%; 47 | bottom: 0px; 48 | left: 0px; 49 | text-align: right; 50 | padding: 1em; 51 | padding-top: 2em; 52 | } 53 | 54 | 55 | .app-overlay > .app-overlay-container .app-overlay > .app-overlay-container { 56 | height: 100%; 57 | } 58 | 59 | .app-overlay > .app-overlay-container .app-overlay > .app-overlay-container .app-overlay-footer { 60 | position: absolute; 61 | height: 48px; 62 | left: 0px; 63 | bottom: 0px; 64 | width: 100%; 65 | padding-top: 0px; 66 | } -------------------------------------------------------------------------------- /src/components/app-overlay/component.js: -------------------------------------------------------------------------------- 1 | require('./style.less'); 2 | 3 | module.exports = { 4 | onInput: function(input) { 5 | this.state = { 6 | width: input.width || '80%', 7 | visible: input.visible === true ? true : false, 8 | body: input.renderBody 9 | }; 10 | }, 11 | 12 | onMount: function() { 13 | this.fixPageScrolling(); 14 | }, 15 | 16 | onUpdate: function() { 17 | this.fixPageScrolling(); 18 | }, 19 | 20 | fixPageScrolling: function() { 21 | if (this.state.visible === true) { 22 | document.body.style.overflow = 'hidden'; 23 | } else { 24 | document.body.style.overflow = ''; 25 | } 26 | }, 27 | 28 | hide: function() { 29 | this.setVisibility(false); 30 | }, 31 | show: function() { 32 | this.setVisibility(true); 33 | }, 34 | 35 | setVisibility: function(visible) { 36 | if (this.state.visible === visible) { 37 | // Visibility did not change... nothing to do 38 | return; 39 | } 40 | 41 | if (visible) { 42 | this.emit('show'); 43 | } else { 44 | this.emit('hide'); 45 | } 46 | 47 | this.setState('visible', visible); 48 | }, 49 | 50 | handleMaskClick: function() { 51 | this.hide(); 52 | }, 53 | handleCancelButtonClick: function() { 54 | this.emit('cancel', {}); 55 | this.hide(); 56 | }, 57 | handleDoneButtonClick: function() { 58 | var preventDefault = false; 59 | 60 | this.emit('ok', { 61 | preventDefault: function() { 62 | preventDefault = true; 63 | } 64 | }); 65 | 66 | if (!preventDefault) { 67 | this.hide(); 68 | } 69 | } 70 | }; -------------------------------------------------------------------------------- /src/global-style/style.less: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: @font-family; 3 | color: @font-color; 4 | padding: 0; 5 | margin: 0; 6 | } 7 | 8 | * { 9 | -moz-box-sizing: border-box; 10 | -webkit-box-sizing: border-box; 11 | box-sizing: border-box; 12 | } 13 | 14 | button::-moz-focus-inner, 15 | input::-moz-focus-inner { 16 | border: 0; 17 | padding: 0; 18 | } 19 | 20 | ul, 21 | ol { 22 | margin-top: 0; 23 | margin-bottom: 0; 24 | padding-top: 0; 25 | padding-bottom: 0; 26 | } 27 | 28 | form, 29 | img { 30 | margin: 0; 31 | padding: 0; 32 | } 33 | 34 | img { 35 | border-width: 0; 36 | } 37 | 38 | textarea, 39 | input { 40 | font-size: 14px; 41 | font-family: @font-family; 42 | } 43 | 44 | select { 45 | margin: 0; 46 | } 47 | 48 | table { 49 | border-collapse: separate; 50 | border-spacing: 0; 51 | } 52 | 53 | td { 54 | padding: 0; 55 | margin: 0; 56 | border-width: 0; 57 | } 58 | 59 | pre { 60 | margin: 0; 61 | padding: 0; 62 | } 63 | 64 | h1, h2, h3 { 65 | margin-top: 0; 66 | padding-top: 0.5em; 67 | margin-bottom: 0.2em; 68 | } 69 | 70 | h1 { 71 | font-size: 1.5em; 72 | color: @dark-color; 73 | 74 | a { 75 | color: @dark-color; 76 | } 77 | } 78 | 79 | h2 { 80 | font-size: 1.25em; 81 | } 82 | 83 | h3 { 84 | font-size: 1.0em; 85 | } 86 | 87 | label { 88 | display: block; 89 | font-size: 0.9em; 90 | } 91 | 92 | button, input, select, textarea { 93 | font-size: 100%; 94 | margin: 0; 95 | } 96 | 97 | button { 98 | padding: 0; 99 | cursor: pointer; 100 | line-height: normal; 101 | border: 0; 102 | } 103 | 104 | a { 105 | color: @link-color; 106 | text-decoration: none; 107 | } 108 | 109 | input[type=text] { 110 | border: 1px solid #c0c0c0; 111 | } -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | require('require-self-ref'); 2 | 3 | require('marko/express'); 4 | require('marko/node-require'); 5 | require('lasso/node-require-no-op').enable('.less', '.css'); 6 | 7 | var express = require('express'); 8 | var compression = require('compression'); // Provides gzip compression for the HTTP response 9 | var serveStatic = require('serve-static'); 10 | 11 | var isProduction = process.env.NODE_ENV === 'production'; 12 | 13 | // Configure the RaptorJS Optimizer to control how JS/CSS/etc. is 14 | // delivered to the browser 15 | require('lasso').configure({ 16 | plugins: [ 17 | 'lasso-less', // Allow Less files to be rendered to CSS 18 | 'lasso-marko' // Allow Marko templates to be compiled and transported to the browser 19 | ], 20 | outputDir: __dirname + '/static', // Place all generated JS/CSS/etc. files into the "static" dir 21 | bundlingEnabled: isProduction, // Only enable bundling in production 22 | minify: isProduction, // Only minify JS and CSS code in production 23 | fingerprintsEnabled: isProduction, // Only add fingerprints to URLs in production 24 | }); 25 | 26 | var app = express(); 27 | 28 | var port = process.env.PORT || 8080; 29 | 30 | // Enable gzip compression for all HTTP responses 31 | app.use(compression()); 32 | 33 | // Allow all of the generated files under "static" to be served up by Express 34 | app.use('/static', serveStatic(__dirname + '/static')); 35 | 36 | require('./src/services/routes')(app); 37 | 38 | // Map the "/" route to the home page 39 | app.get('/', require('./src/pages/home')); 40 | 41 | app.listen(port, function(err) { 42 | if (err) { 43 | throw err; 44 | } 45 | console.log('Listening on port %d', port); 46 | 47 | // The browser-refresh module uses this event to know that the 48 | // process is ready to serve traffic after the restart 49 | if (process.send) { 50 | process.send('online'); 51 | } 52 | }); -------------------------------------------------------------------------------- /src/components/app-fetch-data/index.marko: -------------------------------------------------------------------------------- 1 | import { getUsers } from '~/src/services/users'; 2 | import 'purecss/build/tables.css'; 3 | 4 | class { 5 | onInput(input) { 6 | var users = []; 7 | var pageIndex = -1; 8 | 9 | var usersData = input.usersData; 10 | if (usersData) { 11 | users = usersData.users; 12 | pageIndex = usersData.pageIndex; 13 | } 14 | 15 | this.state = { 16 | loading: false, 17 | users: users, 18 | pageIndex: pageIndex 19 | }; 20 | } 21 | 22 | onMount() { 23 | this.fetchPromise = Promise.resolve(); 24 | 25 | if (this.state.users.length === 0) { 26 | this.loadMore(); 27 | } 28 | } 29 | 30 | loadMore() { 31 | this.state.loading = true; 32 | 33 | var state = this.state; 34 | 35 | this.fetchPromise = this.fetchPromise 36 | .then(function() { 37 | return getUsers({ 38 | pageIndex: ++state.pageIndex 39 | }); 40 | }) 41 | .then(function(usersData) { 42 | state.users = state.users.concat(usersData.users); 43 | state.loading = false; 44 | }) 45 | .catch(function(e) { 46 | state.loading = false; 47 | console.log('Fetch failed:', e); 48 | }); 49 | } 50 | 51 | handleLoadMoreClick() { 52 | this.loadMore(); 53 | } 54 | 55 | onUpdate() { 56 | if (this.state.pageIndex > 0) { 57 | var tableContainer = this.getEl('tableContainer'); 58 | tableContainer.scrollTop = tableContainer.scrollHeight; 59 | } 60 | } 61 | } 62 | 63 | 64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 |
IDAvatarNameEmail
${user.id}${user.firstName} ${user.lastName}${user.email}
83 |
84 | 85 | 86 |
-------------------------------------------------------------------------------- /src/components/app-fetch-data/loading.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/app/component.js: -------------------------------------------------------------------------------- 1 | require('./style.less'); 2 | 3 | var raptorPubsub = require('raptor-pubsub'); 4 | var button = require('~/src/components/app-button'); 5 | var checkbox = require('~/src/components/app-checkbox'); 6 | var progressBar = require('~/src/components/app-progress-bar'); 7 | var extend = require('raptor-util/extend'); 8 | 9 | var buttonSizes = ['small', 'normal', 'large']; 10 | var buttonVariants = ['primary', 'secondary']; 11 | 12 | var currentButtonSize = 0; 13 | var currentButtonVariant = 0; 14 | 15 | module.exports = { 16 | onInput: function(input) { 17 | var now = (new Date()).toString(); 18 | 19 | this.state = { 20 | buttonSize: input.buttonSize || 'small', 21 | buttonVariant: input.buttonVariant || 'primary', 22 | overlayVisible: false, 23 | checked: input.checked || { 24 | foo: false, 25 | bar: true, 26 | baz: false 27 | }, 28 | dynamicTabs: [ 29 | { 30 | timestamp: now 31 | }, 32 | { 33 | timestamp: now 34 | } 35 | ] 36 | }; 37 | }, 38 | 39 | handleCheckboxToggle: function(event, sourceWidget) { 40 | // event.preventDefault(); 41 | 42 | var name = event.data.name; 43 | 44 | // We treat complex objects stored in the state as immutable 45 | // since only a shallow compare is done to see if the state 46 | // has changed. Instead of modifying the "checked" object, 47 | // we create a new object with the updated state of what is 48 | // checked. 49 | var newChecked = extend({}, this.state.checked); 50 | newChecked[name] = event.checked; 51 | this.setState('checked', newChecked); 52 | }, 53 | 54 | /** 55 | * This demonstrates how to provide a custom state transition handler to avoid 56 | * a full rerender. 57 | */ 58 | update_overlayVisible: function(overlayVisible) { 59 | this.getComponent('overlay').setVisibility(overlayVisible); 60 | }, 61 | 62 | handleShowOverlayButtonClick: function() { 63 | // this.setState('overlayVisible', true); 64 | this.getComponent('overlay').show(); 65 | }, 66 | 67 | handleOverlayHide: function() { 68 | // Synchronize the updated state of the o 69 | this.setState('overlayVisible', false); 70 | }, 71 | 72 | handleOverlayShow: function() { 73 | this.setState('overlayVisible', true); 74 | }, 75 | 76 | handleShowNotificationButtonClick: function() { 77 | raptorPubsub.emit('notification', { 78 | message: 'This is a notification' 79 | }); 80 | }, 81 | 82 | handleOverlayOk: function() { 83 | raptorPubsub.emit('notification', { 84 | message: 'You clicked the "Done" button!' 85 | }); 86 | }, 87 | 88 | handleOverlayCancel: function() { 89 | raptorPubsub.emit('notification', { 90 | message: 'You clicked the "Cancel" button!' 91 | }); 92 | }, 93 | 94 | handleRenderButtonClick: function() { 95 | button.renderSync({ 96 | label: 'Hello World' 97 | }) 98 | .appendTo(this.getEl('renderTarget')); 99 | }, 100 | 101 | handleRenderCheckboxButtonClick: function() { 102 | checkbox.renderSync({ 103 | label: 'Hello World', 104 | checked: true 105 | }) 106 | .appendTo(this.getEl('renderTarget')); 107 | }, 108 | 109 | handleRenderProgressBarButtonClick: function() { 110 | progressBar.renderSync({ 111 | steps: [ 112 | { 113 | label: 'Step 1' 114 | }, 115 | { 116 | label: 'Step 2' 117 | }, 118 | { 119 | label: 'Step 3', 120 | active: true 121 | }, 122 | { 123 | label: 'Step 4' 124 | } 125 | ] 126 | }) 127 | .appendTo(this.getEl('renderTarget')); 128 | }, 129 | 130 | handleChangeButtonSizeClick: function() { 131 | var nextButtonSize = buttonSizes[++currentButtonSize % buttonSizes.length]; 132 | this.state.buttonSize = nextButtonSize; 133 | }, 134 | 135 | handleChangeButtonVariantClick: function() { 136 | var nextButtonVariant = buttonVariants[++currentButtonVariant % buttonVariants.length]; 137 | this.state.buttonVariant = nextButtonVariant; 138 | }, 139 | 140 | handleToggleCheckboxButtonClick: function(event) { 141 | var checkbox = this.getComponent('toggleCheckbox'); 142 | checkbox.toggle(); 143 | }, 144 | 145 | handleAddTabButtonClick: function() { 146 | this.state.dynamicTabs = this.state.dynamicTabs.concat({ 147 | timestamp: '' + new Date() 148 | }); 149 | } 150 | }; -------------------------------------------------------------------------------- /src/components/app/index.marko: -------------------------------------------------------------------------------- 1 |
2 | 3 | <@section title="Buttons"> 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | 20 | 21 |
Primary: 8 | 9 | 10 | 11 |
Secondary:  16 | 17 | 18 | 19 |
22 | 23 |
24 | 28 | 31 |
32 | 33 | 34 | 35 | <@section title="Checkboxes"> 36 |

37 | 42 | 46 | 51 |

52 |

53 | 57 |

58 |

59 | Checked: 60 |

    61 | 62 |
  • 63 | ${key} 64 |
  • 65 | 66 |
67 |

68 |

69 | 70 | 71 | 73 |

74 | 75 | 76 | <@section title="Overlays"> 77 | 80 | 81 | 84 | 85 | 86 | 87 | 94 |

Overlay Demo

95 | This is an overlay! 96 |
97 | 98 | 99 | <@section title="Tabs"> 100 | 101 |

Static tabs

102 | 103 | 104 | <@tab label="Home"> 105 | Content for Home 106 | 107 | <@tab label="Profile"> 108 | Content for Profile 109 | 110 | <@tab label="Messages"> 111 | Content for Messages 112 | 113 | 114 | 115 |

Dynamic tabs

116 | 117 | 118 | 119 | <@tab label=('Tab ' + tabIndex)> 120 | Content for tab ${tabIndex}: ${tab.timestamp} 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | <@section title="Miscellaneous"> 130 | 131 | <@step name="contact-info"> 132 | Contact Info 133 | 134 | <@step name="interests"> 135 | Interests 136 | 137 | <@step name="family"> 138 | Family 139 | 140 | 141 |
142 | 143 |
144 | 145 | 146 | 147 | <@section title="Client-side Rendering"> 148 | 149 | 151 | 152 | 154 | 155 | 157 | 158 |
159 | 160 | 161 | <@section title="Fetch data"> 162 | 163 | 164 | 165 | 166 | <@section title="Maps"> 167 | 168 | 174 | 175 | <@section title="Markdown"> 176 | 177 | --- 178 | 179 | > This section demonstrates Markdown in Marko 180 | 181 | ## Marko Features 182 | 183 | - High performance 184 | - Small 185 | - Intuitive 186 | 187 | # H1 188 | ## H2 189 | ### H3 190 | #### H4 191 | ##### H5 192 | ###### H6 193 | 194 | [markojs.com](http://markojs.com/) 195 | 196 | _emphasis_ 197 | __strong__ 198 | 199 | --- 200 | 201 | 202 | 203 |
-------------------------------------------------------------------------------- /src/services/mock-users-data.json: -------------------------------------------------------------------------------- 1 | [{"id":1,"firstName":"Evelyn","lastName":"Patterson","email":"epatterson0@ehow.com","avatar":"https://robohash.org/quinihilomnis.bmp?size=50x50&set=set1"}, 2 | {"id":2,"firstName":"Matthew","lastName":"Moore","email":"mmoore1@squidoo.com","avatar":"https://robohash.org/eaquemolestiasdistinctio.png?size=50x50&set=set1"}, 3 | {"id":3,"firstName":"Ryan","lastName":"Mendoza","email":"rmendoza2@bloglines.com","avatar":"https://robohash.org/corruptiipsumlabore.png?size=50x50&set=set1"}, 4 | {"id":4,"firstName":"Matthew","lastName":"Rice","email":"mrice3@cafepress.com","avatar":"https://robohash.org/voluptatererumpariatur.bmp?size=50x50&set=set1"}, 5 | {"id":5,"firstName":"Ryan","lastName":"Bradley","email":"rbradley4@yahoo.com","avatar":"https://robohash.org/inconsequaturtempora.bmp?size=50x50&set=set1"}, 6 | {"id":6,"firstName":"James","lastName":"Simmons","email":"jsimmons5@nbcnews.com","avatar":"https://robohash.org/iustoadest.jpg?size=50x50&set=set1"}, 7 | {"id":7,"firstName":"Heather","lastName":"Wagner","email":"hwagner6@state.tx.us","avatar":"https://robohash.org/sitlaborumdolorem.png?size=50x50&set=set1"}, 8 | {"id":8,"firstName":"Norma","lastName":"Payne","email":"npayne7@kickstarter.com","avatar":"https://robohash.org/undeetducimus.bmp?size=50x50&set=set1"}, 9 | {"id":9,"firstName":"Jeremy","lastName":"Wilson","email":"jwilson8@amazonaws.com","avatar":"https://robohash.org/quisutlaboriosam.png?size=50x50&set=set1"}, 10 | {"id":10,"firstName":"Sean","lastName":"Palmer","email":"spalmer9@eepurl.com","avatar":"https://robohash.org/quibusdamnullacorporis.jpg?size=50x50&set=set1"}, 11 | {"id":11,"firstName":"Tina","lastName":"Wilson","email":"twilsona@businesswire.com","avatar":"https://robohash.org/ipsumdebitisfugiat.png?size=50x50&set=set1"}, 12 | {"id":12,"firstName":"Andrew","lastName":"Carter","email":"acarterb@admin.ch","avatar":"https://robohash.org/consequaturidipsa.jpg?size=50x50&set=set1"}, 13 | {"id":13,"firstName":"Mildred","lastName":"Palmer","email":"mpalmerc@e-recht24.de","avatar":"https://robohash.org/nequereiciendisomnis.png?size=50x50&set=set1"}, 14 | {"id":14,"firstName":"Theresa","lastName":"Bowman","email":"tbowmand@cocolog-nifty.com","avatar":"https://robohash.org/quosexpeditaest.bmp?size=50x50&set=set1"}, 15 | {"id":15,"firstName":"Denise","lastName":"Dixon","email":"ddixone@bigcartel.com","avatar":"https://robohash.org/utrepudiandaesequi.png?size=50x50&set=set1"}, 16 | {"id":16,"firstName":"Nancy","lastName":"Gardner","email":"ngardnerf@godaddy.com","avatar":"https://robohash.org/molestiaeoditvoluptatibus.png?size=50x50&set=set1"}, 17 | {"id":17,"firstName":"Susan","lastName":"Taylor","email":"staylorg@php.net","avatar":"https://robohash.org/reiciendisetrepellendus.bmp?size=50x50&set=set1"}, 18 | {"id":18,"firstName":"Christopher","lastName":"Olson","email":"colsonh@shop-pro.jp","avatar":"https://robohash.org/estautfugit.bmp?size=50x50&set=set1"}, 19 | {"id":19,"firstName":"Kathleen","lastName":"Hall","email":"khalli@psu.edu","avatar":"https://robohash.org/illoutcorrupti.jpg?size=50x50&set=set1"}, 20 | {"id":20,"firstName":"Catherine","lastName":"Dixon","email":"cdixonj@4shared.com","avatar":"https://robohash.org/estatquepraesentium.png?size=50x50&set=set1"}, 21 | {"id":21,"firstName":"Jason","lastName":"Jones","email":"jjonesk@scribd.com","avatar":"https://robohash.org/sapienteinventoreesse.jpg?size=50x50&set=set1"}, 22 | {"id":22,"firstName":"Michelle","lastName":"Barnes","email":"mbarnesl@ycombinator.com","avatar":"https://robohash.org/excepturietnobis.jpg?size=50x50&set=set1"}, 23 | {"id":23,"firstName":"Roy","lastName":"Hunt","email":"rhuntm@mit.edu","avatar":"https://robohash.org/voluptaspossimustenetur.bmp?size=50x50&set=set1"}, 24 | {"id":24,"firstName":"Samuel","lastName":"Olson","email":"solsonn@blog.com","avatar":"https://robohash.org/utlaboreprovident.png?size=50x50&set=set1"}, 25 | {"id":25,"firstName":"Pamela","lastName":"Garcia","email":"pgarciao@nydailynews.com","avatar":"https://robohash.org/cumplaceatamet.bmp?size=50x50&set=set1"}, 26 | {"id":26,"firstName":"Janet","lastName":"Lawrence","email":"jlawrencep@google.pl","avatar":"https://robohash.org/autnatusmolestiae.bmp?size=50x50&set=set1"}, 27 | {"id":27,"firstName":"Charles","lastName":"Myers","email":"cmyersq@ask.com","avatar":"https://robohash.org/quasiplaceatomnis.jpg?size=50x50&set=set1"}, 28 | {"id":28,"firstName":"Kathleen","lastName":"Moore","email":"kmoorer@deviantart.com","avatar":"https://robohash.org/impeditrerumvel.bmp?size=50x50&set=set1"}, 29 | {"id":29,"firstName":"Jerry","lastName":"Price","email":"jprices@google.com","avatar":"https://robohash.org/nostrumetdolores.png?size=50x50&set=set1"}, 30 | {"id":30,"firstName":"Tammy","lastName":"Kelly","email":"tkellyt@unicef.org","avatar":"https://robohash.org/quibusdamsedquos.png?size=50x50&set=set1"}, 31 | {"id":31,"firstName":"Katherine","lastName":"Ford","email":"kfordu@tmall.com","avatar":"https://robohash.org/explicaboautdolorem.png?size=50x50&set=set1"}, 32 | {"id":32,"firstName":"Eric","lastName":"Kelley","email":"ekelleyv@amazon.co.uk","avatar":"https://robohash.org/inciduntquiaaut.bmp?size=50x50&set=set1"}, 33 | {"id":33,"firstName":"Paula","lastName":"Fernandez","email":"pfernandezw@clickbank.net","avatar":"https://robohash.org/accusamusestdoloribus.jpg?size=50x50&set=set1"}, 34 | {"id":34,"firstName":"Christopher","lastName":"Robertson","email":"crobertsonx@reference.com","avatar":"https://robohash.org/quamquisconsequatur.bmp?size=50x50&set=set1"}, 35 | {"id":35,"firstName":"Janet","lastName":"Alexander","email":"jalexandery@bing.com","avatar":"https://robohash.org/etmolestiaeoccaecati.bmp?size=50x50&set=set1"}, 36 | {"id":36,"firstName":"Melissa","lastName":"Harrison","email":"mharrisonz@nih.gov","avatar":"https://robohash.org/ipsumsitveritatis.png?size=50x50&set=set1"}, 37 | {"id":37,"firstName":"Lori","lastName":"Sanders","email":"lsanders10@friendfeed.com","avatar":"https://robohash.org/deseruntcupiditateet.png?size=50x50&set=set1"}, 38 | {"id":38,"firstName":"Janice","lastName":"Bradley","email":"jbradley11@jimdo.com","avatar":"https://robohash.org/voluptatumutiste.bmp?size=50x50&set=set1"}, 39 | {"id":39,"firstName":"Sharon","lastName":"Hernandez","email":"shernandez12@stanford.edu","avatar":"https://robohash.org/quiacumenim.png?size=50x50&set=set1"}, 40 | {"id":40,"firstName":"Frank","lastName":"Dunn","email":"fdunn13@hp.com","avatar":"https://robohash.org/quosedsit.png?size=50x50&set=set1"}, 41 | {"id":41,"firstName":"Dorothy","lastName":"Reid","email":"dreid14@ucoz.com","avatar":"https://robohash.org/minusquosnon.bmp?size=50x50&set=set1"}, 42 | {"id":42,"firstName":"Norma","lastName":"Rodriguez","email":"nrodriguez15@vkontakte.ru","avatar":"https://robohash.org/autmaximeeum.jpg?size=50x50&set=set1"}, 43 | {"id":43,"firstName":"Anna","lastName":"Ryan","email":"aryan16@quantcast.com","avatar":"https://robohash.org/dolorautquisquam.jpg?size=50x50&set=set1"}, 44 | {"id":44,"firstName":"Eric","lastName":"Foster","email":"efoster17@spotify.com","avatar":"https://robohash.org/doloresveroad.bmp?size=50x50&set=set1"}, 45 | {"id":45,"firstName":"Rebecca","lastName":"Ray","email":"rray18@tiny.cc","avatar":"https://robohash.org/nihilipsamin.png?size=50x50&set=set1"}, 46 | {"id":46,"firstName":"Marilyn","lastName":"Burke","email":"mburke19@accuweather.com","avatar":"https://robohash.org/aututdelectus.bmp?size=50x50&set=set1"}, 47 | {"id":47,"firstName":"Randy","lastName":"Daniels","email":"rdaniels1a@ox.ac.uk","avatar":"https://robohash.org/voluptaseumipsa.png?size=50x50&set=set1"}, 48 | {"id":48,"firstName":"Jeremy","lastName":"Arnold","email":"jarnold1b@uiuc.edu","avatar":"https://robohash.org/rerumeaquelabore.png?size=50x50&set=set1"}, 49 | {"id":49,"firstName":"Lisa","lastName":"Riley","email":"lriley1c@cpanel.net","avatar":"https://robohash.org/eiusautaliquid.jpg?size=50x50&set=set1"}, 50 | {"id":50,"firstName":"Kevin","lastName":"Franklin","email":"kfranklin1d@google.ru","avatar":"https://robohash.org/omnissuscipitquis.png?size=50x50&set=set1"}, 51 | {"id":51,"firstName":"Craig","lastName":"Mason","email":"cmason1e@geocities.com","avatar":"https://robohash.org/doloremdignissimoscum.jpg?size=50x50&set=set1"}, 52 | {"id":52,"firstName":"Juan","lastName":"Hart","email":"jhart1f@apache.org","avatar":"https://robohash.org/omniscorporisimpedit.bmp?size=50x50&set=set1"}, 53 | {"id":53,"firstName":"Helen","lastName":"Allen","email":"hallen1g@cnn.com","avatar":"https://robohash.org/corruptidistinctioquaerat.bmp?size=50x50&set=set1"}, 54 | {"id":54,"firstName":"Chris","lastName":"Boyd","email":"cboyd1h@vistaprint.com","avatar":"https://robohash.org/totamquaeratassumenda.png?size=50x50&set=set1"}, 55 | {"id":55,"firstName":"Barbara","lastName":"Bradley","email":"bbradley1i@google.co.uk","avatar":"https://robohash.org/explicaboquiadignissimos.png?size=50x50&set=set1"}, 56 | {"id":56,"firstName":"Linda","lastName":"Boyd","email":"lboyd1j@miitbeian.gov.cn","avatar":"https://robohash.org/sednumquameos.bmp?size=50x50&set=set1"}, 57 | {"id":57,"firstName":"Laura","lastName":"Green","email":"lgreen1k@si.edu","avatar":"https://robohash.org/voluptasquoharum.jpg?size=50x50&set=set1"}, 58 | {"id":58,"firstName":"Doris","lastName":"Thomas","email":"dthomas1l@github.com","avatar":"https://robohash.org/quisitvoluptas.bmp?size=50x50&set=set1"}, 59 | {"id":59,"firstName":"Willie","lastName":"Romero","email":"wromero1m@ycombinator.com","avatar":"https://robohash.org/distinctioexsed.png?size=50x50&set=set1"}, 60 | {"id":60,"firstName":"Virginia","lastName":"Cole","email":"vcole1n@imgur.com","avatar":"https://robohash.org/idcommodiiure.png?size=50x50&set=set1"}, 61 | {"id":61,"firstName":"Larry","lastName":"Rogers","email":"lrogers1o@mediafire.com","avatar":"https://robohash.org/consecteturveleos.jpg?size=50x50&set=set1"}, 62 | {"id":62,"firstName":"Stephen","lastName":"Brooks","email":"sbrooks1p@narod.ru","avatar":"https://robohash.org/etsuntunde.jpg?size=50x50&set=set1"}, 63 | {"id":63,"firstName":"Joseph","lastName":"Lee","email":"jlee1q@deviantart.com","avatar":"https://robohash.org/exnamqui.png?size=50x50&set=set1"}, 64 | {"id":64,"firstName":"Roger","lastName":"Long","email":"rlong1r@businessweek.com","avatar":"https://robohash.org/velnonnesciunt.bmp?size=50x50&set=set1"}, 65 | {"id":65,"firstName":"Virginia","lastName":"Harper","email":"vharper1s@stanford.edu","avatar":"https://robohash.org/delenitidoloresdolores.jpg?size=50x50&set=set1"}, 66 | {"id":66,"firstName":"Fred","lastName":"Robertson","email":"frobertson1t@tripod.com","avatar":"https://robohash.org/quononcumque.bmp?size=50x50&set=set1"}, 67 | {"id":67,"firstName":"Ernest","lastName":"Price","email":"eprice1u@devhub.com","avatar":"https://robohash.org/consequunturestesse.bmp?size=50x50&set=set1"}, 68 | {"id":68,"firstName":"Linda","lastName":"Murray","email":"lmurray1v@google.it","avatar":"https://robohash.org/ipsameligendiquia.bmp?size=50x50&set=set1"}, 69 | {"id":69,"firstName":"Peter","lastName":"Dean","email":"pdean1w@webnode.com","avatar":"https://robohash.org/auttotamporro.jpg?size=50x50&set=set1"}, 70 | {"id":70,"firstName":"Steven","lastName":"Baker","email":"sbaker1x@abc.net.au","avatar":"https://robohash.org/enimharumlaborum.jpg?size=50x50&set=set1"}, 71 | {"id":71,"firstName":"Linda","lastName":"Smith","email":"lsmith1y@google.it","avatar":"https://robohash.org/sitautsit.jpg?size=50x50&set=set1"}, 72 | {"id":72,"firstName":"Lillian","lastName":"Diaz","email":"ldiaz1z@exblog.jp","avatar":"https://robohash.org/autperspiciatisrepellat.jpg?size=50x50&set=set1"}, 73 | {"id":73,"firstName":"Alan","lastName":"Smith","email":"asmith20@cpanel.net","avatar":"https://robohash.org/minusquiaest.png?size=50x50&set=set1"}, 74 | {"id":74,"firstName":"Clarence","lastName":"Hill","email":"chill21@prweb.com","avatar":"https://robohash.org/ametetnostrum.bmp?size=50x50&set=set1"}, 75 | {"id":75,"firstName":"Paula","lastName":"White","email":"pwhite22@cocolog-nifty.com","avatar":"https://robohash.org/assumendaomnisearum.png?size=50x50&set=set1"}, 76 | {"id":76,"firstName":"Kathryn","lastName":"Wright","email":"kwright23@msu.edu","avatar":"https://robohash.org/temporesaepeenim.bmp?size=50x50&set=set1"}, 77 | {"id":77,"firstName":"Roger","lastName":"Hill","email":"rhill24@tripod.com","avatar":"https://robohash.org/erroretquia.bmp?size=50x50&set=set1"}, 78 | {"id":78,"firstName":"Todd","lastName":"Moreno","email":"tmoreno25@mit.edu","avatar":"https://robohash.org/quodinciduntmodi.jpg?size=50x50&set=set1"}, 79 | {"id":79,"firstName":"George","lastName":"Brown","email":"gbrown26@myspace.com","avatar":"https://robohash.org/mollitiaminusexercitationem.jpg?size=50x50&set=set1"}, 80 | {"id":80,"firstName":"Harry","lastName":"Dean","email":"hdean27@de.vu","avatar":"https://robohash.org/veldolordolorum.jpg?size=50x50&set=set1"}, 81 | {"id":81,"firstName":"Norma","lastName":"Perez","email":"nperez28@ebay.com","avatar":"https://robohash.org/totamesseexplicabo.png?size=50x50&set=set1"}, 82 | {"id":82,"firstName":"Cheryl","lastName":"Gilbert","email":"cgilbert29@ucsd.edu","avatar":"https://robohash.org/fugiatabfacere.bmp?size=50x50&set=set1"}, 83 | {"id":83,"firstName":"Willie","lastName":"Myers","email":"wmyers2a@ow.ly","avatar":"https://robohash.org/earumnoniste.bmp?size=50x50&set=set1"}, 84 | {"id":84,"firstName":"Fred","lastName":"Turner","email":"fturner2b@nasa.gov","avatar":"https://robohash.org/quisquamautemillo.bmp?size=50x50&set=set1"}, 85 | {"id":85,"firstName":"Harold","lastName":"Garza","email":"hgarza2c@simplemachines.org","avatar":"https://robohash.org/voluptassuntdebitis.bmp?size=50x50&set=set1"}, 86 | {"id":86,"firstName":"Judith","lastName":"Edwards","email":"jedwards2d@about.com","avatar":"https://robohash.org/inciduntinnesciunt.bmp?size=50x50&set=set1"}, 87 | {"id":87,"firstName":"James","lastName":"Hall","email":"jhall2e@infoseek.co.jp","avatar":"https://robohash.org/placeatquianemo.bmp?size=50x50&set=set1"}, 88 | {"id":88,"firstName":"Earl","lastName":"Phillips","email":"ephillips2f@technorati.com","avatar":"https://robohash.org/quodestcommodi.jpg?size=50x50&set=set1"}, 89 | {"id":89,"firstName":"Bruce","lastName":"Garza","email":"bgarza2g@php.net","avatar":"https://robohash.org/sapienteeosautem.bmp?size=50x50&set=set1"}, 90 | {"id":90,"firstName":"Joyce","lastName":"Simmons","email":"jsimmons2h@devhub.com","avatar":"https://robohash.org/voluptatemvelitofficiis.png?size=50x50&set=set1"}, 91 | {"id":91,"firstName":"Pamela","lastName":"Carr","email":"pcarr2i@scientificamerican.com","avatar":"https://robohash.org/quiiustoadipisci.bmp?size=50x50&set=set1"}, 92 | {"id":92,"firstName":"Debra","lastName":"Cox","email":"dcox2j@ucoz.com","avatar":"https://robohash.org/atquequoet.png?size=50x50&set=set1"}, 93 | {"id":93,"firstName":"Cynthia","lastName":"Murray","email":"cmurray2k@trellian.com","avatar":"https://robohash.org/voluptassuscipitipsa.bmp?size=50x50&set=set1"}, 94 | {"id":94,"firstName":"Margaret","lastName":"Bennett","email":"mbennett2l@jugem.jp","avatar":"https://robohash.org/magniettempore.png?size=50x50&set=set1"}, 95 | {"id":95,"firstName":"Dennis","lastName":"Gonzalez","email":"dgonzalez2m@prlog.org","avatar":"https://robohash.org/laboriosamconsequaturinventore.bmp?size=50x50&set=set1"}, 96 | {"id":96,"firstName":"Janice","lastName":"Adams","email":"jadams2n@vk.com","avatar":"https://robohash.org/facilismolestiaedeserunt.png?size=50x50&set=set1"}, 97 | {"id":97,"firstName":"Billy","lastName":"Miller","email":"bmiller2o@pen.io","avatar":"https://robohash.org/ullamreiciendiset.png?size=50x50&set=set1"}, 98 | {"id":98,"firstName":"Sara","lastName":"Stevens","email":"sstevens2p@vimeo.com","avatar":"https://robohash.org/utquasiquia.bmp?size=50x50&set=set1"}, 99 | {"id":99,"firstName":"Julia","lastName":"Gonzales","email":"jgonzales2q@chicagotribune.com","avatar":"https://robohash.org/ipsalaudantiumexercitationem.bmp?size=50x50&set=set1"}, 100 | {"id":100,"firstName":"Theresa","lastName":"Carter","email":"tcarter2r@google.fr","avatar":"https://robohash.org/quiconsequaturvoluptas.jpg?size=50x50&set=set1"}, 101 | {"id":101,"firstName":"Robin","lastName":"Henderson","email":"rhenderson2s@wufoo.com","avatar":"https://robohash.org/suntdoloresquaerat.jpg?size=50x50&set=set1"}, 102 | {"id":102,"firstName":"Helen","lastName":"Evans","email":"hevans2t@hc360.com","avatar":"https://robohash.org/cupiditatesolutavelit.jpg?size=50x50&set=set1"}, 103 | {"id":103,"firstName":"Paula","lastName":"Dunn","email":"pdunn2u@mapquest.com","avatar":"https://robohash.org/similiquesequinatus.bmp?size=50x50&set=set1"}, 104 | {"id":104,"firstName":"Lawrence","lastName":"Burke","email":"lburke2v@cloudflare.com","avatar":"https://robohash.org/veniaminventoresit.bmp?size=50x50&set=set1"}, 105 | {"id":105,"firstName":"Sharon","lastName":"Carr","email":"scarr2w@google.com.hk","avatar":"https://robohash.org/etaliquamaut.jpg?size=50x50&set=set1"}, 106 | {"id":106,"firstName":"Stephanie","lastName":"Brooks","email":"sbrooks2x@shareasale.com","avatar":"https://robohash.org/quiacorporisquia.bmp?size=50x50&set=set1"}, 107 | {"id":107,"firstName":"Catherine","lastName":"Stone","email":"cstone2y@jigsy.com","avatar":"https://robohash.org/nonvoluptateaperiam.jpg?size=50x50&set=set1"}, 108 | {"id":108,"firstName":"Russell","lastName":"Taylor","email":"rtaylor2z@lycos.com","avatar":"https://robohash.org/aliquamomnisomnis.bmp?size=50x50&set=set1"}, 109 | {"id":109,"firstName":"Keith","lastName":"Perez","email":"kperez30@digg.com","avatar":"https://robohash.org/etlaborumnisi.jpg?size=50x50&set=set1"}, 110 | {"id":110,"firstName":"Judith","lastName":"Hart","email":"jhart31@globo.com","avatar":"https://robohash.org/fugiatvitaequam.png?size=50x50&set=set1"}, 111 | {"id":111,"firstName":"Harold","lastName":"George","email":"hgeorge32@xrea.com","avatar":"https://robohash.org/providentquianimi.jpg?size=50x50&set=set1"}, 112 | {"id":112,"firstName":"Martin","lastName":"Knight","email":"mknight33@dagondesign.com","avatar":"https://robohash.org/voluptateprovidentquos.bmp?size=50x50&set=set1"}, 113 | {"id":113,"firstName":"James","lastName":"Martinez","email":"jmartinez34@shop-pro.jp","avatar":"https://robohash.org/saeperepellendusbeatae.jpg?size=50x50&set=set1"}, 114 | {"id":114,"firstName":"Evelyn","lastName":"Riley","email":"eriley35@hud.gov","avatar":"https://robohash.org/oditquaeratet.png?size=50x50&set=set1"}, 115 | {"id":115,"firstName":"William","lastName":"White","email":"wwhite36@independent.co.uk","avatar":"https://robohash.org/etlaboriosamea.bmp?size=50x50&set=set1"}, 116 | {"id":116,"firstName":"Anne","lastName":"Brooks","email":"abrooks37@rediff.com","avatar":"https://robohash.org/esseofficiaest.bmp?size=50x50&set=set1"}, 117 | {"id":117,"firstName":"Kathy","lastName":"Roberts","email":"kroberts38@alibaba.com","avatar":"https://robohash.org/saepeexpeditamolestiae.jpg?size=50x50&set=set1"}, 118 | {"id":118,"firstName":"Robin","lastName":"Garrett","email":"rgarrett39@europa.eu","avatar":"https://robohash.org/sapienteetofficiis.png?size=50x50&set=set1"}, 119 | {"id":119,"firstName":"Lois","lastName":"Bell","email":"lbell3a@ucoz.ru","avatar":"https://robohash.org/solutaquisdolore.png?size=50x50&set=set1"}, 120 | {"id":120,"firstName":"Robin","lastName":"Willis","email":"rwillis3b@arstechnica.com","avatar":"https://robohash.org/abvoluptasaut.jpg?size=50x50&set=set1"}, 121 | {"id":121,"firstName":"Juan","lastName":"Smith","email":"jsmith3c@cbsnews.com","avatar":"https://robohash.org/veletet.bmp?size=50x50&set=set1"}, 122 | {"id":122,"firstName":"Mark","lastName":"Greene","email":"mgreene3d@intel.com","avatar":"https://robohash.org/nihilmodiaut.jpg?size=50x50&set=set1"}, 123 | {"id":123,"firstName":"Janet","lastName":"Welch","email":"jwelch3e@alibaba.com","avatar":"https://robohash.org/undequamdolores.jpg?size=50x50&set=set1"}, 124 | {"id":124,"firstName":"Jean","lastName":"Ford","email":"jford3f@mashable.com","avatar":"https://robohash.org/ideta.bmp?size=50x50&set=set1"}, 125 | {"id":125,"firstName":"Jessica","lastName":"Fisher","email":"jfisher3g@flickr.com","avatar":"https://robohash.org/etdelectusnecessitatibus.png?size=50x50&set=set1"}, 126 | {"id":126,"firstName":"Elizabeth","lastName":"Daniels","email":"edaniels3h@pcworld.com","avatar":"https://robohash.org/exdoloremrerum.png?size=50x50&set=set1"}, 127 | {"id":127,"firstName":"Terry","lastName":"Cook","email":"tcook3i@tiny.cc","avatar":"https://robohash.org/ullamistemagni.bmp?size=50x50&set=set1"}, 128 | {"id":128,"firstName":"Frances","lastName":"Hart","email":"fhart3j@jugem.jp","avatar":"https://robohash.org/voluptasquodrepellendus.png?size=50x50&set=set1"}, 129 | {"id":129,"firstName":"Jesse","lastName":"Johnson","email":"jjohnson3k@fotki.com","avatar":"https://robohash.org/oditoptioculpa.bmp?size=50x50&set=set1"}, 130 | {"id":130,"firstName":"Michael","lastName":"Stevens","email":"mstevens3l@sfgate.com","avatar":"https://robohash.org/veroadiste.bmp?size=50x50&set=set1"}, 131 | {"id":131,"firstName":"Angela","lastName":"Bowman","email":"abowman3m@indiegogo.com","avatar":"https://robohash.org/etinaut.bmp?size=50x50&set=set1"}, 132 | {"id":132,"firstName":"Gerald","lastName":"Ward","email":"gward3n@plala.or.jp","avatar":"https://robohash.org/etvoluptatibusnostrum.jpg?size=50x50&set=set1"}, 133 | {"id":133,"firstName":"Jack","lastName":"Russell","email":"jrussell3o@bloglovin.com","avatar":"https://robohash.org/autvitaeillum.jpg?size=50x50&set=set1"}, 134 | {"id":134,"firstName":"Pamela","lastName":"Stevens","email":"pstevens3p@si.edu","avatar":"https://robohash.org/veroutdebitis.bmp?size=50x50&set=set1"}, 135 | {"id":135,"firstName":"Craig","lastName":"Holmes","email":"cholmes3q@earthlink.net","avatar":"https://robohash.org/quisednecessitatibus.bmp?size=50x50&set=set1"}, 136 | {"id":136,"firstName":"Victor","lastName":"Hill","email":"vhill3r@yellowbook.com","avatar":"https://robohash.org/accusantiumquiomnis.jpg?size=50x50&set=set1"}, 137 | {"id":137,"firstName":"Jose","lastName":"Sullivan","email":"jsullivan3s@dropbox.com","avatar":"https://robohash.org/blanditiisducimusvoluptas.jpg?size=50x50&set=set1"}, 138 | {"id":138,"firstName":"Susan","lastName":"Coleman","email":"scoleman3t@liveinternet.ru","avatar":"https://robohash.org/mollitiavoluptasvoluptate.png?size=50x50&set=set1"}, 139 | {"id":139,"firstName":"Gloria","lastName":"Foster","email":"gfoster3u@wordpress.org","avatar":"https://robohash.org/quammodiquisquam.png?size=50x50&set=set1"}, 140 | {"id":140,"firstName":"Anne","lastName":"Welch","email":"awelch3v@hostgator.com","avatar":"https://robohash.org/quisequivoluptas.png?size=50x50&set=set1"}, 141 | {"id":141,"firstName":"Louise","lastName":"Peterson","email":"lpeterson3w@house.gov","avatar":"https://robohash.org/delenitisedharum.png?size=50x50&set=set1"}, 142 | {"id":142,"firstName":"Nancy","lastName":"Coleman","email":"ncoleman3x@nytimes.com","avatar":"https://robohash.org/eligendivoluptasrepellat.png?size=50x50&set=set1"}, 143 | {"id":143,"firstName":"Howard","lastName":"Torres","email":"htorres3y@i2i.jp","avatar":"https://robohash.org/accusantiummaximererum.jpg?size=50x50&set=set1"}, 144 | {"id":144,"firstName":"Linda","lastName":"Patterson","email":"lpatterson3z@uol.com.br","avatar":"https://robohash.org/consequaturveritatistempore.bmp?size=50x50&set=set1"}, 145 | {"id":145,"firstName":"Julie","lastName":"Gilbert","email":"jgilbert40@ask.com","avatar":"https://robohash.org/quiaquiminus.bmp?size=50x50&set=set1"}, 146 | {"id":146,"firstName":"Harold","lastName":"Alvarez","email":"halvarez41@baidu.com","avatar":"https://robohash.org/quisconsequaturquis.bmp?size=50x50&set=set1"}, 147 | {"id":147,"firstName":"Walter","lastName":"Little","email":"wlittle42@i2i.jp","avatar":"https://robohash.org/dolorumutnumquam.png?size=50x50&set=set1"}, 148 | {"id":148,"firstName":"Mildred","lastName":"Matthews","email":"mmatthews43@example.com","avatar":"https://robohash.org/undequasrepellat.png?size=50x50&set=set1"}, 149 | {"id":149,"firstName":"Pamela","lastName":"Wheeler","email":"pwheeler44@microsoft.com","avatar":"https://robohash.org/itaqueestnisi.bmp?size=50x50&set=set1"}, 150 | {"id":150,"firstName":"Adam","lastName":"Gilbert","email":"agilbert45@shop-pro.jp","avatar":"https://robohash.org/utettotam.png?size=50x50&set=set1"}, 151 | {"id":151,"firstName":"Raymond","lastName":"Roberts","email":"rroberts46@shareasale.com","avatar":"https://robohash.org/autexblanditiis.bmp?size=50x50&set=set1"}, 152 | {"id":152,"firstName":"Lori","lastName":"Morales","email":"lmorales47@biblegateway.com","avatar":"https://robohash.org/doloresatet.jpg?size=50x50&set=set1"}, 153 | {"id":153,"firstName":"Louise","lastName":"Hall","email":"lhall48@fotki.com","avatar":"https://robohash.org/auteumodit.jpg?size=50x50&set=set1"}, 154 | {"id":154,"firstName":"Joyce","lastName":"Fuller","email":"jfuller49@prnewswire.com","avatar":"https://robohash.org/faceretemporaeum.png?size=50x50&set=set1"}, 155 | {"id":155,"firstName":"Martin","lastName":"Torres","email":"mtorres4a@geocities.com","avatar":"https://robohash.org/quoblanditiisautem.bmp?size=50x50&set=set1"}, 156 | {"id":156,"firstName":"Marie","lastName":"Duncan","email":"mduncan4b@ox.ac.uk","avatar":"https://robohash.org/quisquamsuntarchitecto.jpg?size=50x50&set=set1"}, 157 | {"id":157,"firstName":"Joseph","lastName":"Hill","email":"jhill4c@comsenz.com","avatar":"https://robohash.org/repellendussuntin.png?size=50x50&set=set1"}, 158 | {"id":158,"firstName":"Clarence","lastName":"Chavez","email":"cchavez4d@bbb.org","avatar":"https://robohash.org/veniammodivitae.png?size=50x50&set=set1"}, 159 | {"id":159,"firstName":"Linda","lastName":"Wheeler","email":"lwheeler4e@themeforest.net","avatar":"https://robohash.org/nobissimiliquenulla.png?size=50x50&set=set1"}, 160 | {"id":160,"firstName":"Fred","lastName":"Cole","email":"fcole4f@hud.gov","avatar":"https://robohash.org/quiaquiblanditiis.jpg?size=50x50&set=set1"}, 161 | {"id":161,"firstName":"Joan","lastName":"Henderson","email":"jhenderson4g@pcworld.com","avatar":"https://robohash.org/corporispraesentiumdolores.png?size=50x50&set=set1"}, 162 | {"id":162,"firstName":"Kathy","lastName":"Gordon","email":"kgordon4h@state.gov","avatar":"https://robohash.org/nihiloditqui.jpg?size=50x50&set=set1"}, 163 | {"id":163,"firstName":"Frank","lastName":"Crawford","email":"fcrawford4i@dion.ne.jp","avatar":"https://robohash.org/veloptioplaceat.jpg?size=50x50&set=set1"}, 164 | {"id":164,"firstName":"Kevin","lastName":"Freeman","email":"kfreeman4j@marketwatch.com","avatar":"https://robohash.org/quaseaquetemporibus.bmp?size=50x50&set=set1"}, 165 | {"id":165,"firstName":"Betty","lastName":"Fields","email":"bfields4k@nationalgeographic.com","avatar":"https://robohash.org/undeaperiamblanditiis.png?size=50x50&set=set1"}, 166 | {"id":166,"firstName":"Johnny","lastName":"Alvarez","email":"jalvarez4l@yale.edu","avatar":"https://robohash.org/estutnesciunt.jpg?size=50x50&set=set1"}, 167 | {"id":167,"firstName":"Timothy","lastName":"Roberts","email":"troberts4m@bandcamp.com","avatar":"https://robohash.org/necessitatibusnondolores.jpg?size=50x50&set=set1"}, 168 | {"id":168,"firstName":"Martin","lastName":"Hughes","email":"mhughes4n@huffingtonpost.com","avatar":"https://robohash.org/sintexpeditaquos.png?size=50x50&set=set1"}, 169 | {"id":169,"firstName":"Julia","lastName":"Gibson","email":"jgibson4o@e-recht24.de","avatar":"https://robohash.org/quasettempore.jpg?size=50x50&set=set1"}, 170 | {"id":170,"firstName":"Jessica","lastName":"Harris","email":"jharris4p@bigcartel.com","avatar":"https://robohash.org/quisimiliquearchitecto.bmp?size=50x50&set=set1"}, 171 | {"id":171,"firstName":"Samuel","lastName":"George","email":"sgeorge4q@cmu.edu","avatar":"https://robohash.org/utipsavoluptatem.bmp?size=50x50&set=set1"}, 172 | {"id":172,"firstName":"Todd","lastName":"Elliott","email":"telliott4r@ow.ly","avatar":"https://robohash.org/placeatnisia.bmp?size=50x50&set=set1"}, 173 | {"id":173,"firstName":"Albert","lastName":"Romero","email":"aromero4s@behance.net","avatar":"https://robohash.org/corruptiutlaboriosam.png?size=50x50&set=set1"}, 174 | {"id":174,"firstName":"Heather","lastName":"Palmer","email":"hpalmer4t@xing.com","avatar":"https://robohash.org/teneturmaioresaliquam.jpg?size=50x50&set=set1"}, 175 | {"id":175,"firstName":"Joseph","lastName":"Fox","email":"jfox4u@japanpost.jp","avatar":"https://robohash.org/impeditiurevel.bmp?size=50x50&set=set1"}, 176 | {"id":176,"firstName":"Angela","lastName":"Robertson","email":"arobertson4v@artisteer.com","avatar":"https://robohash.org/repellatoditquasi.bmp?size=50x50&set=set1"}, 177 | {"id":177,"firstName":"Lisa","lastName":"Chapman","email":"lchapman4w@gravatar.com","avatar":"https://robohash.org/natusnobismagni.bmp?size=50x50&set=set1"}, 178 | {"id":178,"firstName":"Kathy","lastName":"Myers","email":"kmyers4x@geocities.com","avatar":"https://robohash.org/etdolorenam.png?size=50x50&set=set1"}, 179 | {"id":179,"firstName":"Adam","lastName":"Lee","email":"alee4y@cdbaby.com","avatar":"https://robohash.org/nonblanditiisid.jpg?size=50x50&set=set1"}, 180 | {"id":180,"firstName":"Charles","lastName":"Daniels","email":"cdaniels4z@craigslist.org","avatar":"https://robohash.org/quimollitiadoloribus.png?size=50x50&set=set1"}, 181 | {"id":181,"firstName":"Edward","lastName":"Bennett","email":"ebennett50@delicious.com","avatar":"https://robohash.org/maioresquiamodi.png?size=50x50&set=set1"}, 182 | {"id":182,"firstName":"Wanda","lastName":"Carr","email":"wcarr51@shutterfly.com","avatar":"https://robohash.org/aspernaturrepellendusodio.jpg?size=50x50&set=set1"}, 183 | {"id":183,"firstName":"John","lastName":"Morris","email":"jmorris52@home.pl","avatar":"https://robohash.org/reprehenderitpraesentiumomnis.png?size=50x50&set=set1"}, 184 | {"id":184,"firstName":"Paul","lastName":"Anderson","email":"panderson53@diigo.com","avatar":"https://robohash.org/earepellatet.png?size=50x50&set=set1"}, 185 | {"id":185,"firstName":"Aaron","lastName":"Ryan","email":"aryan54@boston.com","avatar":"https://robohash.org/quietsuscipit.bmp?size=50x50&set=set1"}, 186 | {"id":186,"firstName":"Anthony","lastName":"Perry","email":"aperry55@google.fr","avatar":"https://robohash.org/aspernaturutnumquam.bmp?size=50x50&set=set1"}, 187 | {"id":187,"firstName":"Frances","lastName":"Simmons","email":"fsimmons56@economist.com","avatar":"https://robohash.org/illuminciduntdolores.bmp?size=50x50&set=set1"}, 188 | {"id":188,"firstName":"Jesse","lastName":"Sullivan","email":"jsullivan57@last.fm","avatar":"https://robohash.org/quisednostrum.png?size=50x50&set=set1"}, 189 | {"id":189,"firstName":"Joyce","lastName":"Wheeler","email":"jwheeler58@usa.gov","avatar":"https://robohash.org/doloretet.bmp?size=50x50&set=set1"}, 190 | {"id":190,"firstName":"Mildred","lastName":"Young","email":"myoung59@hubpages.com","avatar":"https://robohash.org/minimaarchitectoporro.bmp?size=50x50&set=set1"}, 191 | {"id":191,"firstName":"Susan","lastName":"Fields","email":"sfields5a@github.com","avatar":"https://robohash.org/autullameos.png?size=50x50&set=set1"}, 192 | {"id":192,"firstName":"John","lastName":"Daniels","email":"jdaniels5b@mapquest.com","avatar":"https://robohash.org/estnihilquos.jpg?size=50x50&set=set1"}, 193 | {"id":193,"firstName":"Eric","lastName":"Garza","email":"egarza5c@macromedia.com","avatar":"https://robohash.org/sitipsumeum.png?size=50x50&set=set1"}, 194 | {"id":194,"firstName":"Catherine","lastName":"Wilson","email":"cwilson5d@nydailynews.com","avatar":"https://robohash.org/aliasiustofacere.bmp?size=50x50&set=set1"}, 195 | {"id":195,"firstName":"Teresa","lastName":"Garza","email":"tgarza5e@hexun.com","avatar":"https://robohash.org/fugamodinon.bmp?size=50x50&set=set1"}, 196 | {"id":196,"firstName":"Nancy","lastName":"Foster","email":"nfoster5f@pcworld.com","avatar":"https://robohash.org/estnumquamaut.jpg?size=50x50&set=set1"}, 197 | {"id":197,"firstName":"Lois","lastName":"Wright","email":"lwright5g@princeton.edu","avatar":"https://robohash.org/sedvoluptatumratione.png?size=50x50&set=set1"}, 198 | {"id":198,"firstName":"Sandra","lastName":"Parker","email":"sparker5h@toplist.cz","avatar":"https://robohash.org/atqueeumomnis.bmp?size=50x50&set=set1"}, 199 | {"id":199,"firstName":"Patrick","lastName":"Sullivan","email":"psullivan5i@weather.com","avatar":"https://robohash.org/quaeratvoluptatumtotam.png?size=50x50&set=set1"}, 200 | {"id":200,"firstName":"Jeremy","lastName":"Lopez","email":"jlopez5j@issuu.com","avatar":"https://robohash.org/adipiscifugiatquam.jpg?size=50x50&set=set1"}, 201 | {"id":201,"firstName":"Brenda","lastName":"Lynch","email":"blynch5k@alexa.com","avatar":"https://robohash.org/placeatnisiodit.png?size=50x50&set=set1"}, 202 | {"id":202,"firstName":"Donald","lastName":"Peterson","email":"dpeterson5l@ted.com","avatar":"https://robohash.org/etevenietvelit.jpg?size=50x50&set=set1"}, 203 | {"id":203,"firstName":"Billy","lastName":"Fields","email":"bfields5m@shareasale.com","avatar":"https://robohash.org/quivitaesed.png?size=50x50&set=set1"}, 204 | {"id":204,"firstName":"Sandra","lastName":"Oliver","email":"soliver5n@so-net.ne.jp","avatar":"https://robohash.org/quiaexfacilis.bmp?size=50x50&set=set1"}, 205 | {"id":205,"firstName":"Edward","lastName":"Rodriguez","email":"erodriguez5o@icq.com","avatar":"https://robohash.org/dolorumharumquaerat.bmp?size=50x50&set=set1"}, 206 | {"id":206,"firstName":"Randy","lastName":"Rose","email":"rrose5p@springer.com","avatar":"https://robohash.org/sitculpaquia.jpg?size=50x50&set=set1"}, 207 | {"id":207,"firstName":"Norma","lastName":"James","email":"njames5q@yahoo.com","avatar":"https://robohash.org/omnisdoloret.bmp?size=50x50&set=set1"}, 208 | {"id":208,"firstName":"Pamela","lastName":"Reed","email":"preed5r@oaic.gov.au","avatar":"https://robohash.org/quaesitmollitia.bmp?size=50x50&set=set1"}, 209 | {"id":209,"firstName":"Ruth","lastName":"Woods","email":"rwoods5s@ovh.net","avatar":"https://robohash.org/laboriosamveritatisassumenda.png?size=50x50&set=set1"}, 210 | {"id":210,"firstName":"Harry","lastName":"Turner","email":"hturner5t@is.gd","avatar":"https://robohash.org/quisomnisatque.jpg?size=50x50&set=set1"}, 211 | {"id":211,"firstName":"Richard","lastName":"Black","email":"rblack5u@newyorker.com","avatar":"https://robohash.org/doloremqueeiuscumque.jpg?size=50x50&set=set1"}, 212 | {"id":212,"firstName":"Anna","lastName":"Jenkins","email":"ajenkins5v@wordpress.org","avatar":"https://robohash.org/quiisteaspernatur.bmp?size=50x50&set=set1"}, 213 | {"id":213,"firstName":"Sara","lastName":"Gomez","email":"sgomez5w@opensource.org","avatar":"https://robohash.org/estaperiamvel.jpg?size=50x50&set=set1"}, 214 | {"id":214,"firstName":"Heather","lastName":"Simpson","email":"hsimpson5x@istockphoto.com","avatar":"https://robohash.org/nihilquiplaceat.jpg?size=50x50&set=set1"}, 215 | {"id":215,"firstName":"Joseph","lastName":"Graham","email":"jgraham5y@ezinearticles.com","avatar":"https://robohash.org/quossimiliquenam.jpg?size=50x50&set=set1"}, 216 | {"id":216,"firstName":"Wanda","lastName":"Andrews","email":"wandrews5z@yahoo.com","avatar":"https://robohash.org/illodoloresnam.bmp?size=50x50&set=set1"}, 217 | {"id":217,"firstName":"Roger","lastName":"Lynch","email":"rlynch60@t-online.de","avatar":"https://robohash.org/voluptatumblanditiisest.png?size=50x50&set=set1"}, 218 | {"id":218,"firstName":"Lisa","lastName":"Alvarez","email":"lalvarez61@miitbeian.gov.cn","avatar":"https://robohash.org/evenietsitconsequatur.bmp?size=50x50&set=set1"}, 219 | {"id":219,"firstName":"Kevin","lastName":"Black","email":"kblack62@seattletimes.com","avatar":"https://robohash.org/quaeratestcorporis.jpg?size=50x50&set=set1"}, 220 | {"id":220,"firstName":"Catherine","lastName":"Nguyen","email":"cnguyen63@squidoo.com","avatar":"https://robohash.org/velitnemoet.bmp?size=50x50&set=set1"}, 221 | {"id":221,"firstName":"Roger","lastName":"Sullivan","email":"rsullivan64@sphinn.com","avatar":"https://robohash.org/aspernaturetnatus.png?size=50x50&set=set1"}, 222 | {"id":222,"firstName":"Roger","lastName":"Hansen","email":"rhansen65@latimes.com","avatar":"https://robohash.org/dolortenetursit.jpg?size=50x50&set=set1"}, 223 | {"id":223,"firstName":"Jennifer","lastName":"Scott","email":"jscott66@patch.com","avatar":"https://robohash.org/esttotamvoluptatum.png?size=50x50&set=set1"}, 224 | {"id":224,"firstName":"Charles","lastName":"Dean","email":"cdean67@salon.com","avatar":"https://robohash.org/omnisveritatismollitia.png?size=50x50&set=set1"}, 225 | {"id":225,"firstName":"Patrick","lastName":"Taylor","email":"ptaylor68@vk.com","avatar":"https://robohash.org/fugiatcommodinihil.png?size=50x50&set=set1"}, 226 | {"id":226,"firstName":"Mildred","lastName":"Cooper","email":"mcooper69@zimbio.com","avatar":"https://robohash.org/excepturiautmolestiae.bmp?size=50x50&set=set1"}, 227 | {"id":227,"firstName":"Barbara","lastName":"Moreno","email":"bmoreno6a@bravesites.com","avatar":"https://robohash.org/nonarchitectoquibusdam.png?size=50x50&set=set1"}, 228 | {"id":228,"firstName":"Andrew","lastName":"Scott","email":"ascott6b@epa.gov","avatar":"https://robohash.org/voluptatumeiusin.png?size=50x50&set=set1"}, 229 | {"id":229,"firstName":"Sharon","lastName":"Carter","email":"scarter6c@vistaprint.com","avatar":"https://robohash.org/nostrumutdicta.jpg?size=50x50&set=set1"}, 230 | {"id":230,"firstName":"Willie","lastName":"Baker","email":"wbaker6d@chicagotribune.com","avatar":"https://robohash.org/cumquesaepeofficiis.jpg?size=50x50&set=set1"}, 231 | {"id":231,"firstName":"Kathryn","lastName":"Meyer","email":"kmeyer6e@toplist.cz","avatar":"https://robohash.org/odioquistemporibus.bmp?size=50x50&set=set1"}, 232 | {"id":232,"firstName":"Nicole","lastName":"Nguyen","email":"nnguyen6f@pcworld.com","avatar":"https://robohash.org/similiqueofficianeque.bmp?size=50x50&set=set1"}, 233 | {"id":233,"firstName":"Sarah","lastName":"Stephens","email":"sstephens6g@uiuc.edu","avatar":"https://robohash.org/doloressedexpedita.bmp?size=50x50&set=set1"}, 234 | {"id":234,"firstName":"Douglas","lastName":"Mccoy","email":"dmccoy6h@reuters.com","avatar":"https://robohash.org/etinreprehenderit.bmp?size=50x50&set=set1"}, 235 | {"id":235,"firstName":"Deborah","lastName":"Hall","email":"dhall6i@nydailynews.com","avatar":"https://robohash.org/enimiurequis.jpg?size=50x50&set=set1"}, 236 | {"id":236,"firstName":"Joyce","lastName":"Robertson","email":"jrobertson6j@indiatimes.com","avatar":"https://robohash.org/odioquamunde.png?size=50x50&set=set1"}, 237 | {"id":237,"firstName":"Ashley","lastName":"Price","email":"aprice6k@ihg.com","avatar":"https://robohash.org/doloremrerumalias.jpg?size=50x50&set=set1"}, 238 | {"id":238,"firstName":"Gary","lastName":"Garrett","email":"ggarrett6l@over-blog.com","avatar":"https://robohash.org/totamvelinventore.bmp?size=50x50&set=set1"}, 239 | {"id":239,"firstName":"Sandra","lastName":"Harrison","email":"sharrison6m@weather.com","avatar":"https://robohash.org/occaecatiinventoreconsequatur.bmp?size=50x50&set=set1"}, 240 | {"id":240,"firstName":"Mark","lastName":"Gilbert","email":"mgilbert6n@hc360.com","avatar":"https://robohash.org/mollitiavoluptasvero.jpg?size=50x50&set=set1"}, 241 | {"id":241,"firstName":"Gregory","lastName":"Carpenter","email":"gcarpenter6o@feedburner.com","avatar":"https://robohash.org/consecteturtemporenihil.png?size=50x50&set=set1"}, 242 | {"id":242,"firstName":"Henry","lastName":"Webb","email":"hwebb6p@army.mil","avatar":"https://robohash.org/assumendaliberoaliquam.png?size=50x50&set=set1"}, 243 | {"id":243,"firstName":"Gary","lastName":"Nelson","email":"gnelson6q@chicagotribune.com","avatar":"https://robohash.org/etsitassumenda.bmp?size=50x50&set=set1"}, 244 | {"id":244,"firstName":"Jason","lastName":"Lawrence","email":"jlawrence6r@ifeng.com","avatar":"https://robohash.org/enimsaepeincidunt.png?size=50x50&set=set1"}, 245 | {"id":245,"firstName":"Alice","lastName":"Jones","email":"ajones6s@nbcnews.com","avatar":"https://robohash.org/etmolestiasharum.png?size=50x50&set=set1"}, 246 | {"id":246,"firstName":"Carol","lastName":"Stanley","email":"cstanley6t@ifeng.com","avatar":"https://robohash.org/omnisdolorveritatis.png?size=50x50&set=set1"}, 247 | {"id":247,"firstName":"Harry","lastName":"Bennett","email":"hbennett6u@eepurl.com","avatar":"https://robohash.org/minimaporroet.bmp?size=50x50&set=set1"}, 248 | {"id":248,"firstName":"Gary","lastName":"Bailey","email":"gbailey6v@about.me","avatar":"https://robohash.org/minimanemoaccusantium.png?size=50x50&set=set1"}, 249 | {"id":249,"firstName":"James","lastName":"Rose","email":"jrose6w@gizmodo.com","avatar":"https://robohash.org/consequunturincidunteligendi.bmp?size=50x50&set=set1"}, 250 | {"id":250,"firstName":"Philip","lastName":"Webb","email":"pwebb6x@myspace.com","avatar":"https://robohash.org/laborumconsequatursapiente.jpg?size=50x50&set=set1"}, 251 | {"id":251,"firstName":"Joan","lastName":"Carter","email":"jcarter6y@apache.org","avatar":"https://robohash.org/inutiste.png?size=50x50&set=set1"}, 252 | {"id":252,"firstName":"Deborah","lastName":"Moore","email":"dmoore6z@google.fr","avatar":"https://robohash.org/minusutquidem.bmp?size=50x50&set=set1"}, 253 | {"id":253,"firstName":"Patrick","lastName":"Price","email":"pprice70@stumbleupon.com","avatar":"https://robohash.org/quisquamrecusandaedolores.jpg?size=50x50&set=set1"}, 254 | {"id":254,"firstName":"Annie","lastName":"Rivera","email":"arivera71@whitehouse.gov","avatar":"https://robohash.org/distinctiomodirepellendus.png?size=50x50&set=set1"}, 255 | {"id":255,"firstName":"Ralph","lastName":"Morales","email":"rmorales72@bloglines.com","avatar":"https://robohash.org/fugaautoptio.jpg?size=50x50&set=set1"}, 256 | {"id":256,"firstName":"Adam","lastName":"Griffin","email":"agriffin73@apple.com","avatar":"https://robohash.org/illumdoloremiure.jpg?size=50x50&set=set1"}, 257 | {"id":257,"firstName":"Johnny","lastName":"Rogers","email":"jrogers74@time.com","avatar":"https://robohash.org/omnishicvoluptates.bmp?size=50x50&set=set1"}, 258 | {"id":258,"firstName":"Linda","lastName":"Flores","email":"lflores75@dailymail.co.uk","avatar":"https://robohash.org/dolorvelqui.jpg?size=50x50&set=set1"}, 259 | {"id":259,"firstName":"Frances","lastName":"Gilbert","email":"fgilbert76@free.fr","avatar":"https://robohash.org/nobisutunde.bmp?size=50x50&set=set1"}, 260 | {"id":260,"firstName":"Virginia","lastName":"Kim","email":"vkim77@google.it","avatar":"https://robohash.org/sedomnisenim.png?size=50x50&set=set1"}, 261 | {"id":261,"firstName":"John","lastName":"Ruiz","email":"jruiz78@plala.or.jp","avatar":"https://robohash.org/rerumenimanimi.png?size=50x50&set=set1"}, 262 | {"id":262,"firstName":"Judith","lastName":"Jones","email":"jjones79@seattletimes.com","avatar":"https://robohash.org/ducimuscommodiaspernatur.png?size=50x50&set=set1"}, 263 | {"id":263,"firstName":"Sara","lastName":"Gilbert","email":"sgilbert7a@mac.com","avatar":"https://robohash.org/vitaequiaratione.bmp?size=50x50&set=set1"}, 264 | {"id":264,"firstName":"Timothy","lastName":"Wells","email":"twells7b@disqus.com","avatar":"https://robohash.org/solutaexplicaboet.bmp?size=50x50&set=set1"}, 265 | {"id":265,"firstName":"Richard","lastName":"Armstrong","email":"rarmstrong7c@columbia.edu","avatar":"https://robohash.org/repellendusmollitiaodio.jpg?size=50x50&set=set1"}, 266 | {"id":266,"firstName":"Brenda","lastName":"Lewis","email":"blewis7d@amazon.de","avatar":"https://robohash.org/molestiaeetvitae.jpg?size=50x50&set=set1"}, 267 | {"id":267,"firstName":"George","lastName":"Adams","email":"gadams7e@qq.com","avatar":"https://robohash.org/exidcumque.jpg?size=50x50&set=set1"}, 268 | {"id":268,"firstName":"Alan","lastName":"Butler","email":"abutler7f@1688.com","avatar":"https://robohash.org/quisnobisprovident.png?size=50x50&set=set1"}, 269 | {"id":269,"firstName":"Michelle","lastName":"Riley","email":"mriley7g@sina.com.cn","avatar":"https://robohash.org/assumendarationevelit.jpg?size=50x50&set=set1"}, 270 | {"id":270,"firstName":"Sara","lastName":"Olson","email":"solson7h@liveinternet.ru","avatar":"https://robohash.org/sitquoaperiam.bmp?size=50x50&set=set1"}, 271 | {"id":271,"firstName":"Katherine","lastName":"Gibson","email":"kgibson7i@e-recht24.de","avatar":"https://robohash.org/numquamfugitillo.bmp?size=50x50&set=set1"}, 272 | {"id":272,"firstName":"Janice","lastName":"Diaz","email":"jdiaz7j@myspace.com","avatar":"https://robohash.org/utoditquia.bmp?size=50x50&set=set1"}, 273 | {"id":273,"firstName":"Anna","lastName":"Carter","email":"acarter7k@admin.ch","avatar":"https://robohash.org/excepturinecessitatibusiusto.bmp?size=50x50&set=set1"}, 274 | {"id":274,"firstName":"Dorothy","lastName":"Mitchell","email":"dmitchell7l@printfriendly.com","avatar":"https://robohash.org/omnisliberout.bmp?size=50x50&set=set1"}, 275 | {"id":275,"firstName":"Amy","lastName":"Mccoy","email":"amccoy7m@nhs.uk","avatar":"https://robohash.org/veritatisoccaecatiincidunt.png?size=50x50&set=set1"}, 276 | {"id":276,"firstName":"Marie","lastName":"Crawford","email":"mcrawford7n@nytimes.com","avatar":"https://robohash.org/velitutaut.bmp?size=50x50&set=set1"}, 277 | {"id":277,"firstName":"Henry","lastName":"Perkins","email":"hperkins7o@163.com","avatar":"https://robohash.org/officiisdoloret.png?size=50x50&set=set1"}, 278 | {"id":278,"firstName":"Juan","lastName":"Owens","email":"jowens7p@google.co.uk","avatar":"https://robohash.org/quisquiiusto.jpg?size=50x50&set=set1"}, 279 | {"id":279,"firstName":"Marie","lastName":"Dean","email":"mdean7q@sphinn.com","avatar":"https://robohash.org/laborumsinteos.png?size=50x50&set=set1"}, 280 | {"id":280,"firstName":"James","lastName":"Wilson","email":"jwilson7r@webmd.com","avatar":"https://robohash.org/aspernaturillumaut.bmp?size=50x50&set=set1"}, 281 | {"id":281,"firstName":"Anne","lastName":"Baker","email":"abaker7s@hatena.ne.jp","avatar":"https://robohash.org/suntetut.png?size=50x50&set=set1"}, 282 | {"id":282,"firstName":"Kelly","lastName":"Mason","email":"kmason7t@nasa.gov","avatar":"https://robohash.org/quamaperiamut.jpg?size=50x50&set=set1"}, 283 | {"id":283,"firstName":"Ryan","lastName":"Carr","email":"rcarr7u@samsung.com","avatar":"https://robohash.org/quiscommodiculpa.png?size=50x50&set=set1"}, 284 | {"id":284,"firstName":"Bonnie","lastName":"Bennett","email":"bbennett7v@virginia.edu","avatar":"https://robohash.org/itaquequisut.png?size=50x50&set=set1"}, 285 | {"id":285,"firstName":"Alan","lastName":"Ramos","email":"aramos7w@hp.com","avatar":"https://robohash.org/ipsaautad.png?size=50x50&set=set1"}, 286 | {"id":286,"firstName":"Jack","lastName":"Bryant","email":"jbryant7x@cnbc.com","avatar":"https://robohash.org/doloresdolorcupiditate.bmp?size=50x50&set=set1"}, 287 | {"id":287,"firstName":"Elizabeth","lastName":"Miller","email":"emiller7y@cnbc.com","avatar":"https://robohash.org/minimaautlabore.bmp?size=50x50&set=set1"}, 288 | {"id":288,"firstName":"Chris","lastName":"Morrison","email":"cmorrison7z@slate.com","avatar":"https://robohash.org/nostrumvoluptateet.png?size=50x50&set=set1"}, 289 | {"id":289,"firstName":"Kenneth","lastName":"Kennedy","email":"kkennedy80@dion.ne.jp","avatar":"https://robohash.org/eaqueitaqueex.png?size=50x50&set=set1"}, 290 | {"id":290,"firstName":"Thomas","lastName":"Andrews","email":"tandrews81@topsy.com","avatar":"https://robohash.org/natusasperioresaut.bmp?size=50x50&set=set1"}, 291 | {"id":291,"firstName":"Anthony","lastName":"Berry","email":"aberry82@netscape.com","avatar":"https://robohash.org/porrovelillum.jpg?size=50x50&set=set1"}, 292 | {"id":292,"firstName":"Henry","lastName":"Bailey","email":"hbailey83@blogs.com","avatar":"https://robohash.org/quaeratetitaque.jpg?size=50x50&set=set1"}, 293 | {"id":293,"firstName":"Jean","lastName":"Davis","email":"jdavis84@guardian.co.uk","avatar":"https://robohash.org/quisquamquiminus.jpg?size=50x50&set=set1"}, 294 | {"id":294,"firstName":"Cynthia","lastName":"Freeman","email":"cfreeman85@yelp.com","avatar":"https://robohash.org/cupiditateminimaexplicabo.bmp?size=50x50&set=set1"}, 295 | {"id":295,"firstName":"Terry","lastName":"James","email":"tjames86@google.co.uk","avatar":"https://robohash.org/ullamquisquamipsum.png?size=50x50&set=set1"}, 296 | {"id":296,"firstName":"Samuel","lastName":"Lewis","email":"slewis87@huffingtonpost.com","avatar":"https://robohash.org/perferendisrationeaut.bmp?size=50x50&set=set1"}, 297 | {"id":297,"firstName":"Helen","lastName":"Watkins","email":"hwatkins88@vistaprint.com","avatar":"https://robohash.org/deseruntetitaque.jpg?size=50x50&set=set1"}, 298 | {"id":298,"firstName":"Roger","lastName":"Scott","email":"rscott89@jugem.jp","avatar":"https://robohash.org/veritatisinvel.png?size=50x50&set=set1"}, 299 | {"id":299,"firstName":"Kenneth","lastName":"Cruz","email":"kcruz8a@rambler.ru","avatar":"https://robohash.org/quisquamquiaqui.jpg?size=50x50&set=set1"}, 300 | {"id":300,"firstName":"Donald","lastName":"Dean","email":"ddean8b@i2i.jp","avatar":"https://robohash.org/eaeosvoluptatem.png?size=50x50&set=set1"} 301 | ] --------------------------------------------------------------------------------