diff --git a/assets/views/home.jsx b/assets/views/home.jsx new file mode 100644 index 00000000..cc65611e --- /dev/null +++ b/assets/views/home.jsx @@ -0,0 +1,34 @@ +'use strict'; + +const React = require('react'); +const moment = require('moment'); + +class Home extends React.Component { + render() { + return ( + + + + + + + + + + + {this.props.releases.map(release => ( + + + + + + + + + ))} +
DateIDShoot ID / Entry IDSiteTitleActors
{ moment(release.date).format('YYYY-MM-DD') }{ release.id }{ release.shootId || release.entryId }{ release.site.name }{ release.title }{ release.actors && release.actors.map(actor => actor.name).join(', ') }
+ ); + } +} + +module.exports = Home; diff --git a/config/default.js b/config/default.js index 69ecefea..c10eedef 100644 --- a/config/default.js +++ b/config/default.js @@ -1,6 +1,15 @@ 'use strict'; module.exports = { + database: { + host: '127.0.0.1', + user: 'user', + password: 'password', + database: 'traxxx', + }, + web: { + port: 5000, + }, include: [ '21sextury', 'blowpass', diff --git a/knexfile.js b/knexfile.js index 841316a6..8d6615e0 100644 --- a/knexfile.js +++ b/knexfile.js @@ -1,9 +1,8 @@ -// Update with your config settings. +// use strict +// +const config = require('config'); module.exports = { - client: 'sqlite3', - connection: { - filename: './db.sqlite', - }, - useNullAsDefault: true, + client: 'pg', + connection: config.database, }; diff --git a/migrations/20190325001339_releases.js b/migrations/20190325001339_releases.js index c441382d..3368bc2a 100644 --- a/migrations/20190325001339_releases.js +++ b/migrations/20190325001339_releases.js @@ -4,7 +4,9 @@ exports.up = knex => Promise.resolve() .then(() => knex.schema.createTable('actors', (table) => { table.increments('id', 8); - table.string('name'); + table.string('name') + .unique() + .notNullable(); table.string('gender', 18); table.integer('alias_for', 8) @@ -23,17 +25,20 @@ exports.up = knex => Promise.resolve() table.string('group', 20) .primary(); - table.string('name', 20); + table.string('name', 32); })) .then(() => knex.schema.createTable('tags', (table) => { - table.string('tag', 20) + table.string('tag', 32) .primary(); + table.integer('capitalization', 1) + .defaultTo(0); + table.string('group_id', 20) .references('group') .inTable('tags_groups'); - table.string('alias_for', 20) + table.string('alias_for', 32) .references('tag') .inTable('tags'); })) @@ -43,14 +48,12 @@ exports.up = knex => Promise.resolve() table.string('name'); table.string('url'); - table.string('description'); + table.text('description'); })) .then(() => knex.schema.createTable('sites', (table) => { table.string('id', 32) .primary(); - table.string('label', 6); - table.string('network_id', 32) .notNullable() .references('id') @@ -58,7 +61,7 @@ exports.up = knex => Promise.resolve() table.string('name'); table.string('url'); - table.string('description'); + table.text('description'); table.string('parameters'); })) .then(() => knex.schema.createTable('releases', (table) => { @@ -94,6 +97,9 @@ exports.up = knex => Promise.resolve() table.integer('rating') .unsigned(); + + table.datetime('created_at') + .defaultTo(knex.fn.now()); })) .then(() => knex.schema.createTable('actors_associated', (table) => { table.increments('id', 16); @@ -118,7 +124,7 @@ exports.up = knex => Promise.resolve() .references('id') .inTable('sites'); - table.string('release_id') + table.integer('release_id', 12) .references('id') .inTable('releases'); })); @@ -126,10 +132,10 @@ exports.up = knex => Promise.resolve() exports.down = knex => Promise.resolve() .then(() => knex.schema.dropTable('tags_associated')) .then(() => knex.schema.dropTable('actors_associated')) + .then(() => knex.schema.dropTable('tags')) + .then(() => knex.schema.dropTable('tags_groups')) + .then(() => knex.schema.dropTable('actors')) .then(() => knex.schema.dropTable('releases')) .then(() => knex.schema.dropTable('sites')) - .then(() => knex.schema.dropTable('networks')) - .then(() => knex.schema.dropTable('actors')) .then(() => knex.schema.dropTable('directors')) - .then(() => knex.schema.dropTable('tags_groups')) - .then(() => knex.schema.dropTable('tags')); + .then(() => knex.schema.dropTable('networks')); diff --git a/package-lock.json b/package-lock.json index 200d86e3..c4845371 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", - "dev": true, "requires": { "@babel/highlight": "^7.0.0" } @@ -35,7 +34,6 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.3.4.tgz", "integrity": "sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA==", - "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/generator": "^7.3.4", @@ -57,7 +55,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -65,8 +62,7 @@ "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" } } }, @@ -74,7 +70,6 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.4.tgz", "integrity": "sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg==", - "dev": true, "requires": { "@babel/types": "^7.3.4", "jsesc": "^2.5.1", @@ -87,7 +82,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", - "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -96,7 +90,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", - "dev": true, "requires": { "@babel/helper-explode-assignable-expression": "^7.1.0", "@babel/types": "^7.0.0" @@ -106,7 +99,6 @@ "version": "7.3.0", "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz", "integrity": "sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw==", - "dev": true, "requires": { "@babel/types": "^7.3.0", "esutils": "^2.0.0" @@ -116,7 +108,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz", "integrity": "sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ==", - "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.0.0", "@babel/traverse": "^7.1.0", @@ -127,7 +118,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz", "integrity": "sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg==", - "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", "@babel/types": "^7.0.0", @@ -138,7 +128,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", - "dev": true, "requires": { "@babel/traverse": "^7.1.0", "@babel/types": "^7.0.0" @@ -148,7 +137,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.0.0", "@babel/template": "^7.1.0", @@ -159,7 +147,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", - "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -168,7 +155,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz", "integrity": "sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==", - "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -177,7 +163,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", - "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -186,7 +171,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", - "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -195,7 +179,6 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz", "integrity": "sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA==", - "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-simple-access": "^7.1.0", @@ -209,7 +192,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", - "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -217,14 +199,12 @@ "@babel/helper-plugin-utils": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", - "dev": true + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==" }, "@babel/helper-regex": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0.tgz", "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==", - "dev": true, "requires": { "lodash": "^4.17.10" } @@ -233,7 +213,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", "@babel/helper-wrap-function": "^7.1.0", @@ -246,7 +225,6 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.3.4.tgz", "integrity": "sha512-pvObL9WVf2ADs+ePg0jrqlhHoxRXlOa+SHRHzAXIz2xkYuOHfGl+fKxPMaS4Fq+uje8JQPobnertBBvyrWnQ1A==", - "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.0.0", "@babel/helper-optimise-call-expression": "^7.0.0", @@ -258,7 +236,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", - "dev": true, "requires": { "@babel/template": "^7.1.0", "@babel/types": "^7.0.0" @@ -268,7 +245,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", - "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -277,7 +253,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", - "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", "@babel/template": "^7.1.0", @@ -289,7 +264,6 @@ "version": "7.3.1", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.3.1.tgz", "integrity": "sha512-Q82R3jKsVpUV99mgX50gOPCWwco9Ec5Iln/8Vyu4osNIOQgSrd9RFrQeUvmvddFNoLwMyOUWU+5ckioEKpDoGA==", - "dev": true, "requires": { "@babel/template": "^7.1.2", "@babel/traverse": "^7.1.5", @@ -300,7 +274,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", - "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", @@ -310,14 +283,12 @@ "@babel/parser": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.4.tgz", - "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==", - "dev": true + "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==" }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-remap-async-to-generator": "^7.1.0", @@ -328,7 +299,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-json-strings": "^7.2.0" @@ -338,7 +308,6 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.4.tgz", "integrity": "sha512-j7VQmbbkA+qrzNqbKHrBsW3ddFnOeva6wzSe/zB7T+xaxGc+RCpwo44wCmRixAIGRoIpmVgvzFzNJqQcO3/9RA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-object-rest-spread": "^7.2.0" @@ -348,7 +317,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" @@ -358,7 +326,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz", "integrity": "sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.0.0", @@ -369,7 +336,14 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", - "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz", + "integrity": "sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -378,7 +352,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -387,7 +360,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -396,7 +368,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -405,7 +376,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -414,7 +384,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -423,7 +392,6 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.3.4.tgz", "integrity": "sha512-Y7nCzv2fw/jEZ9f678MuKdMo99MFDJMT/PvD9LisrR5JDFcJH6vYeH6RnjVt3p5tceyGRvTtEN0VOlU+rgHZjA==", - "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", @@ -434,7 +402,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -443,7 +410,6 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.3.4.tgz", "integrity": "sha512-blRr2O8IOZLAOJklXLV4WhcEzpYafYQKSGT3+R26lWG41u/FODJuBggehtOwilVAcFu393v3OFj+HmaE6tVjhA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "lodash": "^4.17.11" @@ -453,7 +419,6 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.3.4.tgz", "integrity": "sha512-J9fAvCFBkXEvBimgYxCjvaVDzL6thk0j0dBvCeZmIUDBwyt+nv6HfbImsSrWsYXfDNDivyANgJlFXDUWRTZBuA==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", "@babel/helper-define-map": "^7.1.0", @@ -469,7 +434,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -478,7 +442,6 @@ "version": "7.3.2", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.3.2.tgz", "integrity": "sha512-Lrj/u53Ufqxl/sGxyjsJ2XNtNuEjDyjpqdhMNh5aZ+XFOdThL46KBj27Uem4ggoezSYBxKWAil6Hu8HtwqesYw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -487,7 +450,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz", "integrity": "sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.0.0", @@ -498,7 +460,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -507,17 +468,24 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", - "dev": true, "requires": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0" } }, + "@babel/plugin-transform-flow-strip-types": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.0.tgz", + "integrity": "sha512-C4ZVNejHnfB22vI2TYN4RUp2oCmq6cSEAg4RygSvYZUECRqUu9O4PMEMNJ4wsemaRGg27BbgYctG4BZh+AgIHw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0" + } + }, "@babel/plugin-transform-for-of": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz", "integrity": "sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -526,7 +494,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz", "integrity": "sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ==", - "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0" @@ -545,7 +512,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -563,7 +529,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", - "dev": true, "requires": { "@babel/helper-module-transforms": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0" @@ -573,7 +538,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz", "integrity": "sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==", - "dev": true, "requires": { "@babel/helper-module-transforms": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0", @@ -584,7 +548,6 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.3.4.tgz", "integrity": "sha512-VZ4+jlGOF36S7TjKs8g4ojp4MEI+ebCQZdswWb/T9I4X84j8OtFAyjXjt/M16iIm5RIZn0UMQgg/VgIwo/87vw==", - "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0" @@ -594,7 +557,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", - "dev": true, "requires": { "@babel/helper-module-transforms": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0" @@ -604,7 +566,6 @@ "version": "7.3.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.3.0.tgz", "integrity": "sha512-NxIoNVhk9ZxS+9lSoAQ/LM0V2UEvARLttEHUrRDGKFaAxOYQcrkN/nLRE+BbbicCAvZPl7wMP0X60HsHE5DtQw==", - "dev": true, "requires": { "regexp-tree": "^0.1.0" } @@ -613,7 +574,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz", "integrity": "sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -622,7 +582,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-replace-supers": "^7.1.0" @@ -632,7 +591,6 @@ "version": "7.3.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.3.3.tgz", "integrity": "sha512-IrIP25VvXWu/VlBWTpsjGptpomtIkYrN/3aDp4UKm7xK6UxZY88kcJ1UwETbzHAlwN21MnNfwlar0u8y3KpiXw==", - "dev": true, "requires": { "@babel/helper-call-delegate": "^7.1.0", "@babel/helper-get-function-arity": "^7.0.0", @@ -662,7 +620,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz", "integrity": "sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -671,7 +628,6 @@ "version": "7.3.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz", "integrity": "sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg==", - "dev": true, "requires": { "@babel/helper-builder-react-jsx": "^7.3.0", "@babel/helper-plugin-utils": "^7.0.0", @@ -682,7 +638,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.2.0.tgz", "integrity": "sha512-v6S5L/myicZEy+jr6ielB0OR8h+EH/1QFx/YJ7c7Ua+7lqsjj/vW6fD5FR9hB/6y7mGbfT4vAURn3xqBxsUcdg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-jsx": "^7.2.0" @@ -692,7 +647,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz", "integrity": "sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-jsx": "^7.2.0" @@ -702,7 +656,6 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.3.4.tgz", "integrity": "sha512-hvJg8EReQvXT6G9H2MvNPXkv9zK36Vxa1+csAVTpE1J3j0zlHplw76uudEbJxgvqZzAq9Yh45FLD4pk5mKRFQA==", - "dev": true, "requires": { "regenerator-transform": "^0.13.4" } @@ -711,7 +664,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -720,7 +672,6 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -729,7 +680,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.0.0" @@ -739,7 +689,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz", "integrity": "sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0" @@ -749,7 +698,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -758,7 +706,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz", "integrity": "sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.0.0", @@ -778,7 +725,6 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.3.4.tgz", "integrity": "sha512-2mwqfYMK8weA0g0uBKOt4FE3iEodiHy9/CW0b+nWXcbL+pGzLx8ESYc+j9IIxr6LTDHWKgPm71i9smo02bw+gA==", - "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", @@ -829,7 +775,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.0.0.tgz", "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-transform-react-display-name": "^7.0.0", @@ -838,11 +783,30 @@ "@babel/plugin-transform-react-jsx-source": "^7.0.0" } }, + "@babel/register": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.4.0.tgz", + "integrity": "sha512-ekziebXBnS/7V6xk8sBfLSSD6YZuy6P29igBtR6OL/tswKdxOV+Yqq0nzICMguVYtGRZYUCGpfGV8J9Za2iBdw==", + "requires": { + "core-js": "^3.0.0", + "find-cache-dir": "^2.0.0", + "lodash": "^4.17.11", + "mkdirp": "^0.5.1", + "pirates": "^4.0.0", + "source-map-support": "^0.5.9" + }, + "dependencies": { + "core-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.0.1.tgz", + "integrity": "sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew==" + } + } + }, "@babel/template": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", - "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.2.2", @@ -853,7 +817,6 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.3.4.tgz", "integrity": "sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ==", - "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/generator": "^7.3.4", @@ -870,7 +833,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -878,8 +840,7 @@ "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" } } }, @@ -887,7 +848,6 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.4.tgz", "integrity": "sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ==", - "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.11", @@ -909,6 +869,15 @@ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, "acorn": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", @@ -1020,6 +989,11 @@ "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=" }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, "array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", @@ -1252,6 +1226,33 @@ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz", "integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==" }, + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -1305,7 +1306,6 @@ "version": "4.4.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.2.tgz", "integrity": "sha512-ISS/AIAiHERJ3d45Fz0AVYKkgcy+F/eJHzKEvv1j0wwKGKD9T3BrwKr/5g45L+Y4XIK5PlTqefHciRFcfE1Jxg==", - "dev": true, "requires": { "caniuse-lite": "^1.0.30000939", "electron-to-chromium": "^1.3.113", @@ -1317,6 +1317,16 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, + "buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -1347,8 +1357,7 @@ "caniuse-lite": { "version": "1.0.30000939", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000939.tgz", - "integrity": "sha512-oXB23ImDJOgQpGjRv1tCtzAvJr4/OvrHi5SO2vUgB0g0xpdZZoA/BxfImiWfdwoYdUTtQrPsXsvYU/dmCSM8gg==", - "dev": true + "integrity": "sha512-oXB23ImDJOgQpGjRv1tCtzAvJr4/OvrHi5SO2vUgB0g0xpdZZoA/BxfImiWfdwoYdUTtQrPsXsvYU/dmCSM8gg==" }, "caseless": { "version": "0.12.0", @@ -1562,6 +1571,11 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", @@ -1606,6 +1620,15 @@ } } }, + "config-chain": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", + "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", @@ -1617,15 +1640,34 @@ "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", "dev": true }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, "convert-source-map": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "dev": true, "requires": { "safe-buffer": "~5.1.1" } }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", @@ -1799,6 +1841,16 @@ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, "detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -1863,17 +1915,37 @@ "safer-buffer": "^2.1.0" } }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, "electron-to-chromium": { "version": "1.3.113", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz", - "integrity": "sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g==", - "dev": true + "integrity": "sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g==" }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", @@ -1926,6 +1998,11 @@ "is-symbol": "^1.0.2" } }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -2178,8 +2255,12 @@ "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, "execa": { "version": "1.0.0", @@ -2235,6 +2316,68 @@ "homedir-polyfill": "^1.0.1" } }, + "express": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.3", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.2", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "express-promise-router": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/express-promise-router/-/express-promise-router-3.0.3.tgz", + "integrity": "sha1-Xm0ipaPwE9cYMxcv6NereAw/a3A=", + "requires": { + "is-promise": "^2.1.0", + "lodash.flattendeep": "^4.0.0", + "methods": "^1.0.0" + } + }, + "express-react-views": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/express-react-views/-/express-react-views-0.11.0.tgz", + "integrity": "sha512-K1Yu0o6i5p6AULSJOs1Kb7j71Yofgg448lKFXejsEqkX+x45gIS8XT74YdPWVW7VOKBLf9E+Ji3UE10smnN+uw==", + "requires": { + "@babel/core": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "@babel/preset-react": "^7.0.0", + "@babel/register": "^7.0.0", + "js-beautify": "^1.7.3", + "lodash.escaperegexp": "^4.1.2", + "object-assign": "^4.1.1" + } + }, "extend": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-2.0.2.tgz", @@ -2389,6 +2532,78 @@ } } }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "requires": { + "find-up": "^3.0.0" + } + } + } + }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", @@ -2511,6 +2726,11 @@ "resolved": "https://registry.npmjs.org/form-fix-array/-/form-fix-array-1.0.0.tgz", "integrity": "sha1-oTR6R+UxF6t7zb8+Lz7JHGZ2m8g=" }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -2519,6 +2739,21 @@ "map-cache": "^0.2.2" } }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "fs-minipass": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", @@ -3212,14 +3447,12 @@ "globals": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", - "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", - "dev": true + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==" }, "graceful-fs": { "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" }, "har-schema": { "version": "2.0.0", @@ -3328,6 +3561,17 @@ } } }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -3456,6 +3700,11 @@ "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" }, + "ipaddr.js": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", + "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" + }, "is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", @@ -3609,8 +3858,7 @@ "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" }, "is-regex": { "version": "1.0.4", @@ -3686,11 +3934,22 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "js-beautify": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.9.1.tgz", + "integrity": "sha512-oxxvVZdOdUfzk8IOLBF2XUZvl2GoBEfA+b0of4u2EBY/46NlXasi8JdFvazA5lCrf9/lQhTjyVy2QCUW7iq0MQ==", + "requires": { + "config-chain": "^1.1.12", + "editorconfig": "^0.15.2", + "glob": "^7.1.3", + "mkdirp": "~0.5.0", + "nopt": "~4.0.1" + } + }, "js-levenshtein": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", - "dev": true + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==" }, "js-tokens": { "version": "4.0.0", @@ -3715,8 +3974,7 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, "json-schema": { "version": "0.2.3", @@ -3743,7 +4001,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", - "dev": true, "requires": { "minimist": "^1.2.0" }, @@ -3751,11 +4008,18 @@ "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" } } }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -3925,6 +4189,16 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=" + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -3947,6 +4221,22 @@ "yallist": "^2.1.2" } }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } + } + }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -3976,6 +4266,11 @@ "object-visit": "^1.0.0" } }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, "mem": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/mem/-/mem-4.2.0.tgz", @@ -3993,6 +4288,16 @@ } } }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -4158,6 +4463,11 @@ "sax": "^1.2.4" } }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, "neo-blessed": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/neo-blessed/-/neo-blessed-0.2.0.tgz", @@ -4168,6 +4478,11 @@ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" + }, "node-pre-gyp": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", @@ -4189,7 +4504,6 @@ "version": "1.1.9", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.9.tgz", "integrity": "sha512-oic3GT4OtbWWKfRolz5Syw0Xus0KRFxeorLNj0s93ofX6PWyuzKjsiGxsCtWktBwwmTF6DdRRf2KreGqeOk5KA==", - "dev": true, "requires": { "semver": "^5.3.0" } @@ -4371,6 +4685,14 @@ "isobject": "^3.0.1" } }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4489,6 +4811,11 @@ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, + "packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, "parent-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.0.tgz", @@ -4530,6 +4857,11 @@ "@types/node": "*" } }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -4580,6 +4912,11 @@ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=" }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", @@ -4594,17 +4931,81 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, + "pg": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-7.9.0.tgz", + "integrity": "sha512-GkzteBFpsIoIBCSuomqik3IGvhqAtTr32jclR24RmUg170Jrn6ypwR97YalFHrsE1iaW8T0aAH13dmij8QUQ0g==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "0.1.3", + "pg-pool": "^2.0.4", + "pg-types": "~2.0.0", + "pgpass": "1.x", + "semver": "4.3.2" + }, + "dependencies": { + "pg-connection-string": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz", + "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=" + }, + "semver": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", + "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" + } + } + }, "pg-connection-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.0.0.tgz", "integrity": "sha1-Pu/lmX4G2Ugh5NUC5CtqHHP434I=" }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-pool": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.6.tgz", + "integrity": "sha512-hod2zYQxM8Gt482q+qONGTYcg/qVcV32VHVPtktbBJs0us3Dj7xibISw0BAAXVMCzt8A/jhfJvpZaxUlqtqs0g==" + }, + "pg-types": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.0.1.tgz", + "integrity": "sha512-b7y6QM1VF5nOeX9ukMQ0h8a9z89mojrBHXfJeSug4mhL0YpxNBm83ot2TROyoAmX/ZOX3UbwVO4EbH7i1ZZNiw==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", + "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "requires": { + "split": "^1.0.0" + } + }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, "pkg-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", @@ -4619,6 +5020,36 @@ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" + }, + "postgres-date": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.4.tgz", + "integrity": "sha512-bESRvKVuTrjoBluEcpv2346+6kgB7UlnqWZsnbnCccTNq/pqfj1j6oBaN5+b/NrDXepYUT/HKadqv3iS9lJuVA==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + }, + "dependencies": { + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -4644,8 +5075,7 @@ "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" }, "process-nextick-args": { "version": "2.0.0", @@ -4658,6 +5088,30 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" + }, + "proxy-addr": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", + "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.8.0" + } + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -4687,6 +5141,32 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -4705,6 +5185,33 @@ } } }, + "react": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", + "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + }, + "react-dom": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", + "integrity": "sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + }, + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" + }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", @@ -4762,14 +5269,12 @@ "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" }, "regenerate-unicode-properties": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz", "integrity": "sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw==", - "dev": true, "requires": { "regenerate": "^1.4.0" } @@ -4783,7 +5288,6 @@ "version": "0.13.4", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.4.tgz", "integrity": "sha512-T0QMBjK3J0MtxjPmdIMXm72Wvj2Abb0Bd4HADdfijwMdoIsyQZ6fWC7kDFhk2YinBBEMZDL7Y7wh0J1sGx3S4A==", - "dev": true, "requires": { "private": "^0.1.6" } @@ -4800,8 +5304,7 @@ "regexp-tree": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.5.tgz", - "integrity": "sha512-nUmxvfJyAODw+0B13hj8CFVAxhe7fDEAgJgaotBu3nnR+IgGgZq59YedJP5VYTlkEfqjuK6TuRpnymKdatLZfQ==", - "dev": true + "integrity": "sha512-nUmxvfJyAODw+0B13hj8CFVAxhe7fDEAgJgaotBu3nnR+IgGgZq59YedJP5VYTlkEfqjuK6TuRpnymKdatLZfQ==" }, "regexpp": { "version": "2.0.1", @@ -4813,7 +5316,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.4.0.tgz", "integrity": "sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA==", - "dev": true, "requires": { "regenerate": "^1.4.0", "regenerate-unicode-properties": "^7.0.0", @@ -4826,14 +5328,12 @@ "regjsgen": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", - "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", - "dev": true + "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==" }, "regjsparser": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", - "dev": true, "requires": { "jsesc": "~0.5.0" }, @@ -4841,8 +5341,7 @@ "jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" } } }, @@ -5032,11 +5531,58 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, + "scheduler": { + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", + "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "semver": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "dependencies": { + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + } + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -5063,6 +5609,11 @@ } } }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -5076,6 +5627,11 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -5304,7 +5860,6 @@ "version": "0.5.10", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -5313,8 +5868,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -5355,6 +5909,14 @@ "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", "dev": true }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -5421,6 +5983,11 @@ } } }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, "stream-length": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-length/-/stream-length-1.0.2.tgz", @@ -5570,8 +6137,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "0.5.1", @@ -5643,8 +6209,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" }, "to-object-path": { "version": "0.3.0", @@ -5697,8 +6262,7 @@ "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" }, "tslib": { "version": "1.9.3", @@ -5832,6 +6396,15 @@ "prelude-ls": "~1.1.2" } }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -5854,14 +6427,12 @@ "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "dev": true + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==" }, "unicode-match-property-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "dev": true, "requires": { "unicode-canonical-property-names-ecmascript": "^1.0.4", "unicode-property-aliases-ecmascript": "^1.0.4" @@ -5870,14 +6441,12 @@ "unicode-match-property-value-ecmascript": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz", - "integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ==", - "dev": true + "integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ==" }, "unicode-property-aliases-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz", - "integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==", - "dev": true + "integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==" }, "unicons": { "version": "0.0.3", @@ -5917,6 +6486,16 @@ } } }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", @@ -5982,6 +6561,11 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, "uuid": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", @@ -6005,6 +6589,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", diff --git a/package.json b/package.json index a06907fc..359b8c53 100644 --- a/package.json +++ b/package.json @@ -44,11 +44,18 @@ "cheerio": "^1.0.0-rc.2", "clipboardy": "^1.2.3", "config": "^3.0.1", + "express": "^4.16.4", + "express-promise-router": "^3.0.3", + "express-react-views": "^0.11.0", + "fs-extra": "^7.0.1", "knex": "^0.16.3", "knex-migrate": "^1.7.1", "moment": "^2.24.0", "neo-blessed": "^0.2.0", "opn": "^5.4.0", + "pg": "^7.9.0", + "react": "^16.8.6", + "react-dom": "^16.8.6", "sqlite3": "^4.0.6", "tough-cookie": "^3.0.1", "tty-table": "^2.7.0", diff --git a/seeds/networks.js b/seeds/00_networks.js similarity index 91% rename from seeds/networks.js rename to seeds/00_networks.js index 22137894..aa072558 100644 --- a/seeds/networks.js +++ b/seeds/00_networks.js @@ -2,8 +2,7 @@ /* eslint-disable max-len */ exports.seed = knex => Promise.resolve() - .then(() => knex('networks').del()) - .then(() => knex('networks').insert([ + .then(() => knex.raw(`${knex('networks').insert([ { id: '21sextury', name: '21Sextury', @@ -69,6 +68,12 @@ exports.seed = knex => Promise.resolve() url: 'https://www.pervcity.com', description: '', }, + { + id: 'pornpros', + name: 'Porn Pros', + url: 'https://pornpros.com', + description: 'Watch the best HD exclusive movies and videos on Porn Pros. All the hottest new Pornstar and amateur girls in High Definition updated daily.', + }, { id: 'private', name: 'Private', @@ -93,4 +98,4 @@ exports.seed = knex => Promise.resolve() url: 'https://www.xempire.com', description: 'XEmpire.com brings you today\'s top pornstars in beautifully shot, HD sex scenes across 4 unique porn sites of gonzo porn, interracial, lesbian & erotica!', }, - ])); + ]).toString()} ON CONFLICT DO NOTHING`)); diff --git a/seeds/sites.js b/seeds/01_sites.js similarity index 96% rename from seeds/sites.js rename to seeds/01_sites.js index a69ecfdc..dbaa037a 100644 --- a/seeds/sites.js +++ b/seeds/01_sites.js @@ -2,13 +2,11 @@ /* eslint-disable max-len */ exports.seed = knex => Promise.resolve() - .then(() => knex('sites').del()) - .then(() => knex('sites').insert([ + .then(() => knex.raw(`${knex('sites').insert([ // 21Sextury { id: 'analteenangels', name: 'Anal Teen Angels', - label: 'atangl', url: 'https://www.analteenangels.com', description: 'AnalTeenAngels is presented by the 21Sextury nextwork and features young, European teens in hardcore anal porn. Watch these barely legal teens have their first anal sex and give up their ass for some anal pounding!', network_id: '21sextury', @@ -16,7 +14,6 @@ exports.seed = knex => Promise.resolve() { id: 'assholefever', name: 'Asshole Fever', - label: 'assfev', url: 'https://www.assholefever.com', description: 'Welcome to AssholeFever, the most hardcore anal site on the net. Watch your favorite pornstars and anal sluts from all over the world in big booty hardcore porn, anal gape, beads, anal creampie and more! Look inside if you dare!', network_id: '21sextury', @@ -24,7 +21,6 @@ exports.seed = knex => Promise.resolve() { id: 'buttplays', name: 'Butt Plays', - label: 'buttpl', url: 'https://www.buttplays.com', network_id: '21sextury', parameters: JSON.stringify({ filter: true }), @@ -32,7 +28,6 @@ exports.seed = knex => Promise.resolve() { id: 'clubsandy', name: 'Club Sandy', - label: 'csandy', url: 'https://www.clubsandy.com', network_id: '21sextury', parameters: JSON.stringify({ filter: true }), @@ -40,7 +35,6 @@ exports.seed = knex => Promise.resolve() { id: 'deepthroatfrenzy', name: 'Deepthroat Frenzy', - label: 'dfrenz', url: 'https://www.deepthroatfrenzy.com', network_id: '21sextury', parameters: JSON.stringify({ filter: true }), @@ -48,7 +42,6 @@ exports.seed = knex => Promise.resolve() { id: 'dpfanatics', name: 'DP Fanatics', - label: 'dpftic', url: 'https://www.dpfanatics.com', description: 'Welcome to DPFanatics, brought to you by 21Sextury. DP Fanatics brings you the best DP sex and double penetration porn you can find. Double vaginal penetration, double anal, amateur and teen DP inside!', network_id: '21sextury', @@ -56,7 +49,6 @@ exports.seed = knex => Promise.resolve() { id: 'footsiebabes', name: 'Footsie Babes', - label: 'footsi', url: 'https://www.footsiebabes.com', description: 'Welcome to FootsieBabes.com, bringing you the best foot porn, teen feet and foot worship you can find on the net. Watch stocking porn, footjobs, feet tickling and more inside!', network_id: '21sextury', @@ -64,7 +56,6 @@ exports.seed = knex => Promise.resolve() { id: 'gapeland', name: 'Gapeland', - label: 'gapeln', url: 'https://www.gapeland.com', network_id: '21sextury', parameters: JSON.stringify({ filter: true }), @@ -72,7 +63,6 @@ exports.seed = knex => Promise.resolve() { id: 'lezcuties', name: 'Lez Cuties', - label: 'lezcte', url: 'https://www.lezcuties.com', description: 'LezCuties brings you the cutest lesbian coeds and tiny teen lesbians in HD lesbian porn. Watch as European teens explore themselves and lick each other\'s tight lesbian pussy while their parents aren\'t home.', network_id: '21sextury', @@ -80,7 +70,6 @@ exports.seed = knex => Promise.resolve() { id: 'pixandvideo', name: 'Pix and Video', - label: 'pixvid', url: 'https://www.pixandvideo.com', network_id: '21sextury', parameters: JSON.stringify({ filter: true }), @@ -88,7 +77,6 @@ exports.seed = knex => Promise.resolve() // BANGBROS { id: 'assparade', - label: null, network_id: 'bangbros', name: 'Ass Parade', url: 'https://bangbros.com/websites/assparade', @@ -97,7 +85,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'avaspice', - label: null, network_id: 'bangbros', name: 'AvaSpice', url: 'https://bangbros.com/websites/avaspice', @@ -106,7 +93,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'backroomfacials', - label: null, network_id: 'bangbros', name: 'Back Room Facials', url: 'https://bangbros.com/websites/backroomfacials', @@ -115,7 +101,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'backroommilf', - label: null, network_id: 'bangbros', name: 'Backroom MILF', url: 'https://bangbros.com/websites/backroommilf', @@ -124,7 +109,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'ballhoneys', - label: null, network_id: 'bangbros', name: 'Ball Honeys', url: 'https://bangbros.com/websites/ballhoneys', @@ -133,7 +117,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'bangbros18', - label: null, network_id: 'bangbros', name: 'BangBros 18', url: 'https://bangbros.com/websites/bangbros18', @@ -142,7 +125,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'bangbrosangels', - label: null, network_id: 'bangbros', name: 'BangBros Angels', url: 'https://bangbros.com/websites/bangbrosangels', @@ -151,7 +133,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'bangbrosclips', - label: null, network_id: 'bangbros', name: 'Bangbros Clips', url: 'https://bangbros.com/websites/bangbrosclips', @@ -160,7 +141,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'bangbrosremastered', - label: null, network_id: 'bangbros', name: 'BangBros Remastered', url: 'https://bangbros.com/websites/bangbrosremastered', @@ -169,7 +149,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'bangbus', - label: null, network_id: 'bangbros', name: 'Bang Bus', url: 'https://bangbros.com/websites/bangbus', @@ -178,7 +157,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'bangcasting', - label: null, network_id: 'bangbros', name: 'Bang Casting', url: 'https://bangbros.com/websites/bangcasting', @@ -187,7 +165,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'bangpov', - label: null, network_id: 'bangbros', name: 'Bang POV', url: 'https://bangbros.com/websites/bangpov', @@ -196,7 +173,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'bangtryouts', - label: null, network_id: 'bangbros', name: 'Bang Tryouts', url: 'https://bangbros.com/websites/bangtryouts', @@ -205,7 +181,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'bigmouthfuls', - label: null, network_id: 'bangbros', name: 'Big Mouthfuls', url: 'https://bangbros.com/websites/bigmouthfuls', @@ -214,7 +189,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'bigtitcreampie', - label: null, network_id: 'bangbros', name: 'Big Tit Cream Pie', url: 'https://bangbros.com/websites/bigtitcreampie', @@ -223,7 +197,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'bigtitsroundasses', - label: null, network_id: 'bangbros', name: 'Big Tits, Round Asses', url: 'https://bangbros.com/websites/bigtitsroundasses', @@ -232,7 +205,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'blowjobfridays', - label: null, network_id: 'bangbros', name: 'BlowJob Fridays', url: 'https://bangbros.com/websites/blowjobfridays', @@ -241,7 +213,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'blowjobninjas', - label: null, network_id: 'bangbros', name: 'Blowjob Ninjas', url: 'https://bangbros.com/websites/blowjobninjas', @@ -250,7 +221,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'boobsquad', - label: null, network_id: 'bangbros', name: 'Boob Squad', url: 'https://bangbros.com/websites/boobsquad', @@ -259,7 +229,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'brownbunnies', - label: null, network_id: 'bangbros', name: 'Brown Bunnies', url: 'https://bangbros.com/websites/brownbunnies', @@ -268,7 +237,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'canhescore', - label: null, network_id: 'bangbros', name: 'Can He Score?', url: 'https://bangbros.com/websites/canhescore', @@ -277,7 +245,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'casting', - label: null, network_id: 'bangbros', name: 'Casting', url: 'https://bangbros.com/websites/casting', @@ -286,7 +253,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'chongas', - label: null, network_id: 'bangbros', name: 'Chongas', url: 'https://bangbros.com/websites/chongas', @@ -295,7 +261,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'colombiafuckfest', - label: null, network_id: 'bangbros', name: 'Colombia Fuck Fest', url: 'https://bangbros.com/websites/colombiafuckfest', @@ -304,7 +269,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'dirtyworldtour', - label: null, network_id: 'bangbros', name: 'Dirty World Tour', url: 'https://bangbros.com/websites/dirtyworldtour', @@ -313,7 +277,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'dorminvasion', - label: null, network_id: 'bangbros', name: 'Dorm Invasion', url: 'https://bangbros.com/websites/dorminvasion', @@ -322,7 +285,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'facialfest', - label: null, network_id: 'bangbros', name: 'Facial Fest', url: 'https://bangbros.com/websites/facialfest', @@ -331,7 +293,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'fuckteamfive', - label: null, network_id: 'bangbros', name: 'Fuck Team Five', url: 'https://bangbros.com/websites/fuckteamfive', @@ -340,7 +301,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'gloryholeloads', - label: null, network_id: 'bangbros', name: 'Glory Hole Loads', url: 'https://bangbros.com/websites/gloryholeloads', @@ -349,7 +309,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'latinarampage', - label: null, network_id: 'bangbros', name: 'Latina Rampage', url: 'https://bangbros.com/websites/latinarampage', @@ -358,7 +317,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'livingwithanna', - label: null, network_id: 'bangbros', name: 'Living With Anna', url: 'https://bangbros.com/websites/livingwithanna', @@ -367,7 +325,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'magicalfeet', - label: null, network_id: 'bangbros', name: 'Magical Feet', url: 'https://bangbros.com/websites/magicalfeet', @@ -376,7 +333,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'milflessons', - label: null, network_id: 'bangbros', name: 'MILF Lessons', url: 'https://bangbros.com/websites/milflessons', @@ -385,7 +341,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'milfsoup', - label: null, network_id: 'bangbros', name: 'Milf Soup', url: 'https://bangbros.com/websites/milfsoup', @@ -394,7 +349,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'momishorny', - label: null, network_id: 'bangbros', name: 'MomIsHorny', url: 'https://bangbros.com/websites/momishorny', @@ -403,7 +357,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'monstersofcock', - label: null, network_id: 'bangbros', name: 'Monsters of Cock', url: 'https://bangbros.com/websites/monstersofcock', @@ -412,7 +365,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'mranal', - label: null, network_id: 'bangbros', name: 'Mr. Anal', url: 'https://bangbros.com/websites/mranal', @@ -421,7 +373,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'mrcameltoe', - label: null, network_id: 'bangbros', name: 'Mr CamelToe', url: 'https://bangbros.com/websites/mrcameltoe', @@ -430,7 +381,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'mydirtymaid', - label: null, network_id: 'bangbros', name: 'My Dirty Maid', url: 'https://bangbros.com/websites/mydirtymaid', @@ -439,7 +389,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'mylifeinbrazil', - label: null, network_id: 'bangbros', name: 'My Life In Brazil', url: 'https://bangbros.com/websites/mylifeinbrazil', @@ -448,7 +397,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'newbieblack', - label: null, network_id: 'bangbros', name: 'Newbie Black', url: 'https://bangbros.com/websites/newbieblack', @@ -457,7 +405,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'partyof3', - label: null, network_id: 'bangbros', name: 'Party of 3', url: 'https://bangbros.com/websites/partyof3', @@ -466,7 +413,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'pawg', - label: null, network_id: 'bangbros', name: 'Pawg', url: 'https://bangbros.com/websites/pawg', @@ -475,7 +421,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'pennyshow', - label: null, network_id: 'bangbros', name: 'Penny Show', url: 'https://bangbros.com/websites/pennyshow', @@ -484,7 +429,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'pornstarspa', - label: null, network_id: 'bangbros', name: 'Porn Star Spa', url: 'https://bangbros.com/websites/pornstarspa', @@ -493,7 +437,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'powermunch', - label: null, network_id: 'bangbros', name: 'Power Munch', url: 'https://bangbros.com/websites/powermunch', @@ -502,7 +445,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'publicbang', - label: null, network_id: 'bangbros', name: 'Public Bang', url: 'https://bangbros.com/websites/publicbang', @@ -511,7 +453,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'sluttywhitegirls', - label: null, network_id: 'bangbros', name: 'Slutty White Girls', url: 'https://bangbros.com/websites/sluttywhitegirls', @@ -520,7 +461,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'stepmomvideos', - label: null, network_id: 'bangbros', name: 'Stepmom Videos', url: 'https://bangbros.com/websites/stepmomvideos', @@ -529,7 +469,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'streetranger', - label: null, network_id: 'bangbros', name: 'Street Ranger', url: 'https://bangbros.com/websites/streetranger', @@ -538,7 +477,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'tugjobs', - label: null, network_id: 'bangbros', name: 'Tugjobs', url: 'https://bangbros.com/websites/tugjobs', @@ -547,7 +485,6 @@ exports.seed = knex => Promise.resolve() }, { id: 'workinglatinas', - label: null, network_id: 'bangbros', name: 'Working Latinas', url: 'https://bangbros.com/websites/workinglatinas', @@ -558,7 +495,6 @@ exports.seed = knex => Promise.resolve() { id: '1000facials', name: '1000 Facials', - label: '1000fc', url: 'https://www.1000facials.com', description: 'Welcome to 1000Facials.com, your source for the best facial porn with huge cumshots on your favorite teen and MILF pornstars. Watch all the blowjob action inside!', network_id: 'blowpass', @@ -566,7 +502,6 @@ exports.seed = knex => Promise.resolve() { id: 'immorallive', name: 'Immoral Live', - label: 'imlive', url: 'https://www.immorallive.com', description: 'Watch live sex shows and videos on ImmoralLive.com, featuring wild and crazy sex orgies, group sex, blowjob competitions and toy play from the famous Porno Dan. The hottest pornstars and amateur girls cum hard inside', network_id: 'blowpass', @@ -574,7 +509,6 @@ exports.seed = knex => Promise.resolve() { id: 'mommyblowsbest', name: 'Mommy Blows Best', - label: 'momblb', url: 'https://www.mommyblowsbest.com', description: 'Welcome to MommyBlowsBest.com. Home to thousands of MILF blowjobs and hot mom porn! Come see why experience counts, right here at MommyBlowsBest.com!', network_id: 'blowpass', @@ -582,7 +516,6 @@ exports.seed = knex => Promise.resolve() { id: 'onlyteenblowjobs', name: 'Only Teen Blowjobs', - label: 'teenbj', url: 'https://www.onlyteenblowjobs.com', description: 'OnlyTeenBlowjobs.com brings you the best teen blowjob porn featuring today\'s hottest young pornstars and amateurs. Watch as teens use their little mouths to suck and deepthroat the biggest of cocks!', network_id: 'blowpass', @@ -590,7 +523,6 @@ exports.seed = knex => Promise.resolve() { id: 'throated', name: 'Throated', - label: 'throat', url: 'https://www.throated.com', description: 'Throated.com is your portal for extreme throat fuck porn, face fucking videos and deepthroat gagging pornstars. Watch teens and MILFs go balls deep, swallowing cock in HD!', network_id: 'blowpass', @@ -599,7 +531,6 @@ exports.seed = knex => Promise.resolve() { id: 'momsincontrol', name: 'Moms in Control', - label: 'MIC', url: 'https://www.brazzers.com/sites/view/id/155/moms-in-control', description: "There's nothing hotter than seeing a wholesome MILf get dirty, and that's exactly what MILFs in Control is all about: the hottest, sluttiest cougars in the business taking control of sexy situations to get exactly what they want. Feast your eyes as these mature beauties suck and fuck huge cocks, dominating big-dick studs and hot teen sluts until they get the cum that all MILFs crave!", network_id: 'brazzers', @@ -607,7 +538,6 @@ exports.seed = knex => Promise.resolve() { id: 'pornstarslikeitbig', name: 'Pornstars Like it Big', - label: 'PLIB', url: 'https://www.brazzers.com/sites/view/id/24/pornstars-like-it-big', description: "A real big dick, that's what everyone wants. Porn-stars are no exception, all the biggest stars agree; BIG COCK is for them. Check out how it stretches their tiny pussies and cums on their round tits. We've got the best chicks jocking the biggest dicks.", network_id: 'brazzers', @@ -615,7 +545,6 @@ exports.seed = knex => Promise.resolve() { id: 'bigtitsatwork', name: 'Big Tits at Work', - label: 'BTAW', url: 'https://www.brazzers.com/sites/view/id/15/big-tits-at-work', description: 'Sitting at your desk, wishing you can fuck every busty coworker you have? Well, stop dreaming and step inside Big Tits At Work where you can watch real life work adventures caught on tape. Nothing But Big Breasted Work Professionals getting drilled all day long...', network_id: 'brazzers', @@ -623,7 +552,6 @@ exports.seed = knex => Promise.resolve() { id: 'bigtitsatschool', name: 'Big Tits at School', - label: 'BTAS', url: 'https://www.brazzers.com/sites/view/id/20/big-tits-at-school', description: "The windows have been fogging up at Big Tits At School. Just take a peek inside one of our classrooms and you'll see our smoking hot busty students and big boobed dominant teachers getting their wet pussies stuffed with cock. Stay in your seat! you haven't been dismissed yet.", network_id: 'brazzers', @@ -631,7 +559,6 @@ exports.seed = knex => Promise.resolve() { id: 'babygotboobs', name: 'Baby Got Boobs', - label: 'BGB', url: 'https://www.brazzers.com/sites/view/id/9/baby-got-boobs', description: "From fresh-faced teen to total slut, baby has boobs and she isn't afraid to show them. But does she know how to use them? These teens crave monster cock in their tight pussies, whether they're ready for a big dicking is another matter.", network_id: 'brazzers', @@ -639,7 +566,6 @@ exports.seed = knex => Promise.resolve() { id: 'realwifestories', name: 'Real Wife Stories', - label: 'RWS', url: 'https://www.brazzers.com/sites/view/id/52/real-wife-stories', description: "You might bring home the bacon, but your wife is still starving. That slut is hungry for cock, she can't get enough, and if you starve her any more she'll get it wherever she can. Better leave work early, or your big-titted wife might just have some giant cock getting squeezed into her waiting pussy, and it won't be yours.", network_id: 'brazzers', @@ -647,7 +573,6 @@ exports.seed = knex => Promise.resolve() { id: 'teenslikeitbig', name: 'Teens Like It Big', - label: 'TLIB', url: 'https://www.brazzers.com/sites/view/id/51/teens-like-it-big', description: "Whether they know it or not, teens love big stiff cocks in their tight pussies. Nothing goes better together than a tight, willing teen and a huge dick. In her bedroom or sneaking out to her boyfriend's, teens just want it all. Cum inside to see greedy sluts get more than they asked for", network_id: 'brazzers', @@ -655,7 +580,6 @@ exports.seed = knex => Promise.resolve() { id: 'zzseries', name: 'ZZ Series', - label: 'ZZS', url: 'https://www.brazzers.com/sites/view/id/81/zz-series', description: 'This is the spot for all our high-end content. ZZ series is exclusive footage that offers only the best in terms of story, stars and action. Check out the hottest porn-stars having the nastiest sex here at the ZZ series', network_id: 'brazzers', @@ -663,7 +587,6 @@ exports.seed = knex => Promise.resolve() { id: 'mommygotboobs', name: 'Mommy Got Boobs', - label: 'MGB', url: 'https://www.brazzers.com/sites/view/id/10/mommy-got-boobs', description: "When hubby's away MILFS will play. Older women just crave cock, and they're experienced enough to know that only a young stud will do. Big-titted sluts everywhere are sucking and fucking in secret, giving it away to anybody they can. At Mommy Got Boobs, you can get some MILF of your own.", network_id: 'brazzers', @@ -671,7 +594,6 @@ exports.seed = knex => Promise.resolve() { id: 'milfslikeitbig', name: 'Milfs Like it Big', - label: 'MLIB', url: 'https://www.brazzers.com/sites/view/id/36/milfs-like-it-big', description: "When hubby's away milfy will play. These bored housewives want to get fucked and they want it now. They're experienced and know what they want. America's suburbs are full of these cum-de-sacs just waiting to get laid. Their round tits and thick asses are just begging for it. Cum inside, but don't park out front!", network_id: 'brazzers', @@ -679,7 +601,6 @@ exports.seed = knex => Promise.resolve() { id: 'bigtitsinuniform', name: 'Big Tits In Uniform', - label: 'BTIU', url: 'https://www.brazzers.com/sites/view/id/73/big-tits-in-uniform', description: "Big titted wonders are all around us, doing the toughest jobs in the tightest uniforms. Look at them just bursting out of that blouse, or over there, bulging under that nurse's uniform. You know when those tight uniforms come off these sluts go wild, sucking and fucking cocks left and right, their big tits just bouncing. I can't wait to punch the clock.", network_id: 'brazzers', @@ -687,7 +608,6 @@ exports.seed = knex => Promise.resolve() { id: 'doctoradventures', name: 'Doctor Adventures', - label: 'DA', url: 'https://www.brazzers.com/sites/view/id/5/doctor-adventures', description: 'Ever had fantasies about fucking your hot doctor? Live out your fantasies on doctoradventures.com. Countless doctor, patient scenarios come to life on this site with the sexiest and bustiest doctors imaginable! This is your one stop for the best in doctor porn in the world!', network_id: 'brazzers', @@ -695,7 +615,6 @@ exports.seed = knex => Promise.resolve() { id: 'brazzersexxtra', name: 'Brazzers Exxtra', - label: 'BEX', url: 'https://www.brazzers.com/sites/view/id/152/brazzers-exxtra', description: "\"Brazzers Exxtra\" is a doorway to new, unseen hardcore content! There are countless Brazzers videos that were not released throughout the years and we haven't been able to show them to you until now. Random videos staring the world's most popular pornstars, fresh new industry faces and a whole lot more! We'll even throw in an occasional free video from our friends at Mofos, Twisty's and Babes! Check it all out and let us know what you think. If you want more, we'll get it for you!", network_id: 'brazzers', @@ -703,7 +622,6 @@ exports.seed = knex => Promise.resolve() { id: 'bigtitsinsports', name: 'Big Tits In Sports', - label: 'BTIS', url: 'https://www.brazzers.com/sites/view/id/54/big-tits-in-sports', description: 'Watch them bounce, watch them score and look at the way they handle those balls! Big tits in sports is here and so are the best big titted, athletic babes. Facials on the court and threesomes on the field, these busty sluts are ready for anything, even if it means playing dirty. Could you take them 1 on 1?', network_id: 'brazzers', @@ -711,7 +629,6 @@ exports.seed = knex => Promise.resolve() { id: 'brazzersvault', name: 'Brazzers Vault', - label: 'BZV', url: 'https://www.brazzers.com/sites/view/id/56/brazzers-vault', description: "We've got a whole super computer full of this stuff, technicians are working round the clock in the basement just to keep the thing from overheating. Yeah, this porno is hot. We need to get it out of before the whole thing melts down, that's why it's on the net, for you our loyal Brazzers Members. All the best scenes from all the best girls. In the World. Period.", network_id: 'brazzers', @@ -719,7 +636,6 @@ exports.seed = knex => Promise.resolve() { id: 'bigbuttslikeitbig', name: 'Big Butts Like It Big', - label: 'BBLIB', url: 'https://www.brazzers.com/sites/view/id/53/big-butts-like-it-big', description: "You have to pair like with like. And big butts have to have big dicks to go with them. There's really no choice for these big round asses and the babes who fuck with them. Big assed bitches love it hard and deep, and won't have it any other way. Let the ass stuffing begin.", network_id: 'brazzers', @@ -727,7 +643,6 @@ exports.seed = knex => Promise.resolve() { id: 'bigwetbutts', name: 'Big Wet Butts', - label: 'BWB', url: 'https://www.brazzers.com/sites/view/id/8/big-wet-butts', description: 'A nice, big, round butt is a special shape. Begging for powerful doggy style or straight anal penetration, cover a big butt in oil and it becomes a big wet butt, a true rarity. Watch these soft, tight asses get slathered and pounded like you only wish you could. Look at it bounce!', network_id: 'brazzers', @@ -735,7 +650,6 @@ exports.seed = knex => Promise.resolve() { id: 'daywithapornstar', name: 'Day With A Pornstar', - label: 'DWP', url: 'https://www.brazzers.com/sites/view/id/59/day-with-a-pornstar', description: "We all know what our favorite stars can do on camera. We're familiar with the way they fuck and suck. What you don't get to see is what they do on their own time. Day With a Porn-star will show you everything, from crazy parties to total babe pals. Nobody else has access like this, it's the closest you get to living the dream.", network_id: 'brazzers', @@ -743,7 +657,6 @@ exports.seed = knex => Promise.resolve() { id: 'dirtymasseur', name: 'Dirty Masseur', - label: 'DM', url: 'https://www.brazzers.com/sites/view/id/150/dirty-masseur', description: "Take a moment and unwind. Lay down, relax, and enjoy watching and wanking to these luscious Brazzers beauties getting good and greasy. Boobs, butts, and other lady-parts are at their prettiest when shimmering with slick oil. Book an appointment, and slide on in with a lubed babe. Believe me when I say, you'll have the happiest of endings...", network_id: 'brazzers', @@ -751,7 +664,6 @@ exports.seed = knex => Promise.resolve() { id: 'hotandmean', name: 'Hot And Mean', - label: 'HAM', url: 'https://www.brazzers.com/sites/view/id/78/hot-and-mean', description: "The hottest bitches run together. Hot, mean lesbians love to fuck each other and hate each other for being so beautiful. These lesbo sluts can't get enough pussy and love girl on girl action. Forget the dicks, these chicks don't need 'em. You can watch though, they love that.", network_id: 'brazzers', @@ -759,7 +671,6 @@ exports.seed = knex => Promise.resolve() { id: 'brazzersenespanol', name: 'Brazzers en Español', - label: 'BZES', url: 'https://www.brazzers.com/sites/view/id/157/brazzers-en-espanol', description: 'Brazzers en Español - El mejor sitio porno en alta definición del mundo ¡Ofreciéndole los vídeos para adultos en alta definición, descargables y en streaming, más exclusivos de Internet! Brazzers cuenta con las estrellas porno más sexys a través de los sitios más calientes en la red. Las estrellas porno y las escenas más calientes en internet. ¡Tendrá acceso a más sexo anal, tetas grandes y culos calientes de los que jamás soñó!', network_id: 'brazzers', @@ -767,7 +678,6 @@ exports.seed = knex => Promise.resolve() { id: 'brazzerslive', name: 'Brazzers Live', - label: 'ZZL', url: 'https://www.brazzers.com/sites/view/id/156/brazzers-live', description: 'Brazzers is the industry leader for premium porn that breaks the mold. Pioneering its legendary LIVE SHOWS, ZZ is constantly redefining what hardcore erotica is about. Our wild fuck marathons are loaded with the steamiest improvised sex around. Catch a bevy of naked bodacious babes who ravage the biggest dicks with ease and in real-time. Our monster cock hunks rise to the occasion and feed these ravenous vixens who possess an insatiable appetite for cum.', network_id: 'brazzers', @@ -775,7 +685,6 @@ exports.seed = knex => Promise.resolve() { id: 'sexproadventures', name: 'SexPro Adventures', - label: 'SPA', url: 'https://www.brazzers.com/sites/view/id/23/sexpro-adventures', description: "Having trouble with your dick-style? The sex pros are here and they'll teach you everything you need to know to be a better man. At your place or theirs, these sluts just want to have a good time. Don't worry, she's a professional.", network_id: 'brazzers', @@ -783,7 +692,6 @@ exports.seed = knex => Promise.resolve() { id: 'shesgonnasquirt', name: 'Shes Gonna Squirt', - label: 'SGS', url: 'https://www.brazzers.com/sites/view/id/151/shes-gonna-squirt', description: "Enter the wet world of female ejaculation at shesgonnasquirt! Exclusive hardcore porn of your top pornstars squirting will excite you beyond belief. She's Gonna Squirt is home to the best in HD squirting sex videos. How to make a girl's pussy squirt is an art and should no longer remain a mystery, so join now to become a master.", network_id: 'brazzers', @@ -791,7 +699,6 @@ exports.seed = knex => Promise.resolve() { id: 'assesinpublic', name: 'Asses In Public', - label: 'AIP', url: 'https://www.brazzers.com/sites/view/id/50/asses-in-public', description: "Sex in public can present its challenges, never fear, we're willing to accept them. There's something hot about asses out in the street that we just can't deny. Porn-stars fucking on public or just hot girls showing their asses in the airport, we've got both and then some. Asses in Public has the roundest asses and the biggest tits just hanging out, where WILL we show up next?", network_id: 'brazzers', @@ -799,7 +706,6 @@ exports.seed = knex => Promise.resolve() { id: 'bustyz', name: 'Bustyz', - label: 'BTZ', url: 'https://www.brazzers.com/sites/view/id/6/bustyz', description: "If the internet was a town we'd have the biggest tits around. We still do though, because Bustyz features only the best endowed porn stars in solo and group action. Watch these big-titted babes take cock, suck twat and show off their massive jugs. Real or fake, we don't judge, everyone's welcome under the big tit tent", network_id: 'brazzers', @@ -807,7 +713,6 @@ exports.seed = knex => Promise.resolve() { id: 'bustyandreal', name: 'Busty & Real', - label: 'BAR', url: 'https://www.brazzers.com/sites/view/id/2/busty-real', description: "Sometimes you need to take a break from the silicon football set. Busty and real has all the real jugs you need. Round. Soft. and as real as they come. These babes are rocking exactly what momma gave them. They've not afraid to show off their assets and get slammed with dick in the process.", network_id: 'brazzers', @@ -815,7 +720,6 @@ exports.seed = knex => Promise.resolve() { id: 'hotchicksbigasses', name: 'Hot Chicks Big Asses', - label: 'HCBA', url: 'https://www.brazzers.com/sites/view/id/7/hot-chicks-big-asses', description: 'Everyone gather round; the giant ass. A babe can be hot in a lot of ways and having a big round ass is one of the best. All shapes, sizes and types these girls are the best of the best. Round, supple, jiggling asses taking on dicks and other pussies in equal measure.', network_id: 'brazzers', @@ -823,7 +727,6 @@ exports.seed = knex => Promise.resolve() { id: 'cfnm', name: 'CFNM', - label: 'CFNM', url: 'https://www.brazzers.com/sites/view/id/154/cfnm', description: "Welcome to the world of clothed female sluts fucking, humiliating and dominating naked men, giving them a dose of what it feels like to be owned. If you love women with power dominating wimpy guys and showing them who's boss; women who crave for cock but get it exactly how they want it, that's what you'll find here. Simply put, the guys don't fuck the women, the women fuck the guys and make them feel like whores!", network_id: 'brazzers', @@ -831,7 +734,6 @@ exports.seed = knex => Promise.resolve() { id: 'jugfuckers', name: 'JugFuckers', - label: 'JF', url: 'https://www.brazzers.com/sites/view/id/12/jugfuckers', description: "Like a sex hot-dog, a big dick fits nicely between two soft, round tits. Tit-fucking isn't easy and never will be. Our girls are pros and take big loads on their faces and tits with a smile. From DD to the smallest things going, we've got every type of tit- fuck around.", network_id: 'brazzers', @@ -839,7 +741,6 @@ exports.seed = knex => Promise.resolve() { id: 'teenslikeitblack', name: 'Teens Like It Black', - label: 'TLB', url: 'https://www.brazzers.com/sites/view/id/57/teens-like-it-black', description: "Teens just wanna piss their parents off; no rules, spring break, big black cocks. They love pushing things to the limit, how big and black can it be? Only teen girls know. Watch them get more than they bargained for, long black cocks drilling their tight, inexperienced pussies. It's an epic fuck when the biggest and the tightest meet.", network_id: 'brazzers', @@ -847,7 +748,6 @@ exports.seed = knex => Promise.resolve() { id: 'racksandblacks', name: 'Racks & Blacks', - label: 'RAB', url: 'https://www.brazzers.com/sites/view/id/11/racks-blacks', description: "All the interracial action you need is here. Big 'ol black cocks ramming and jamming pussies to the limit. All types of different girls fall prey to the venerable black dick. Wet pussies and fat asses? Bring it on. There's nothing our stable of asses can't handle, they'll keep cumming and cumming.", network_id: 'brazzers', @@ -855,7 +755,6 @@ exports.seed = knex => Promise.resolve() { id: 'buttsandblacks', name: 'Butts & Blacks', - label: 'BAB', url: 'https://www.brazzers.com/sites/view/id/3/butts-blacks', description: "Giant black dicks paired with round asses and garnished with the tightest pussies of all colors. Butts and Blacks delivers on its name sake, only the biggest dicks rocking the thickest chicks. These round honeys can take it all in and bounce around like it's a pogo stick. Come check out these soft round asses getting the attention they deserve.", network_id: 'brazzers', @@ -864,7 +763,6 @@ exports.seed = knex => Promise.resolve() { id: 'ddfbusty', name: 'DDF Busty', - label: 'ddfbus', url: 'https://ddfbusty.com', description: 'Gorgeous Babes with big tits and Euro pornstars with huge natural boobs filmed in Exclusive Full HD, 4K, & VR porn videos.', network_id: 'ddfnetwork', @@ -872,7 +770,6 @@ exports.seed = knex => Promise.resolve() { id: 'handsonhardcore', name: 'Hands on Hardcore', - label: 'ddfhoh', url: 'https://handsonhardcore.com', description: 'Hardcore Sex & Anal Fucking Exclusive XXX Videos in VR, 4K and full HD with Hot European Pornstars', network_id: 'ddfnetwork', @@ -880,7 +777,6 @@ exports.seed = knex => Promise.resolve() { id: 'houseoftaboo', name: 'House of Taboo', - label: 'htaboo', url: 'https://houseoftaboo.com', description: 'Exclusive BDSM Porn & Extreme Sex Videos Produced in VR, 4K and full HD with The Hottest European Fetish Pornstars', network_id: 'ddfnetwork', @@ -888,7 +784,6 @@ exports.seed = knex => Promise.resolve() { id: 'ddfnetworkvr', name: 'DDF Network VR', - label: 'ddfnvr', url: 'https://ddfnetworkvr.com', description: 'VR Porn Videos shot Exclusively in 180 3D 4K Virtual Reality featuring the Hottest European & American VR Pornstar Babes', network_id: 'ddfnetwork', @@ -896,7 +791,6 @@ exports.seed = knex => Promise.resolve() { id: 'eurogirlsongirls', name: 'Euro Girls on Girls', - label: 'eurgrl', url: 'https://eurogirlsongirls.com', description: 'Hot Lesbian Sex & Glamour Lesbian Porn Videos and Photos Starring Gorgeous European Pornstars in 4K and Full HD VR.', network_id: 'ddfnetwork', @@ -904,7 +798,6 @@ exports.seed = knex => Promise.resolve() { id: '1byday', name: '1By-Day', - label: '1byday', url: 'https://1by-day.com', description: 'Ultra Sexy Exclusive Solo Masturbation Videos in VR, 4K and full HD showcasing Glamour Babes & Intense Orgasms', network_id: 'ddfnetwork', @@ -912,7 +805,6 @@ exports.seed = knex => Promise.resolve() { id: 'euroteenerotica', name: 'Euro Teen Erotica', - label: 'eurero', url: 'https://euroteenerotica.com', description: 'Teen Threesomes & Barely Legal Porn Videos in 4K, VR and FULL HD with Hot Nymphomaniac Teen Babes', network_id: 'ddfnetwork', @@ -920,7 +812,6 @@ exports.seed = knex => Promise.resolve() { id: 'hotlegsandfeet', name: 'Hot Legs and Feet', - label: 'hotleg', url: 'https://hotlegsandfeet.com', description: 'Foot Fetish & Sexy Legs Porn Videos with Hot and Sexy Euro Pornstars', network_id: 'ddfnetwork', @@ -928,7 +819,6 @@ exports.seed = knex => Promise.resolve() { id: 'onlyblowjob', name: 'Only Blowjob', - label: 'onlbj', url: 'https://onlyblowjob.com', description: 'Fantasy Blowjobs & POV Cock Sucking Videos and Photos Produced in VR, 4K and full HD featuring Sexy European Pornstars', network_id: 'ddfnetwork', @@ -937,7 +827,6 @@ exports.seed = knex => Promise.resolve() { id: 'julesjordan', name: 'Jules Jordan', - label: 'julesj', url: 'https://www.julesjordan.com', description: 'Jules Jordan\'s Official Membership Site', network_id: 'julesjordan', @@ -946,7 +835,6 @@ exports.seed = knex => Promise.resolve() { id: 'thirtyminutesoftorment', name: '30 Minutes of Torment', - label: '30MTor', url: 'https://www.kink.com/channel/30minutesoftorment', description: 'Thick-Muscled Men Endure 30 Minutes Of BDSM Torment By A Pain-Inducing Dom. Can they take 30 Minutes of Torment? Watch as top gay pornstars take on the challenge of a lifetime. Bondage, BDSM, punishment, huge insertions, & more!', network_id: 'kink', @@ -954,7 +842,6 @@ exports.seed = knex => Promise.resolve() { id: 'boundgangbangs', name: 'Bound Gangbangs', - label: 'BoundG', url: 'https://www.kink.com/channel/boundgangbangs', description: 'Poweless whores tied in bondage and stuffed with a cock in every hole. At BoundGangbangs women get surprise extreme gangbangs, blindfolds, deepthroat blowjobs, sex punishment, bondage, double penetration and interracial sex.', network_id: 'kink', @@ -962,7 +849,6 @@ exports.seed = knex => Promise.resolve() { id: 'boundgods', name: 'Bound Gods', - label: 'BnGods', url: 'https://www.kink.com/channel/boundgods', description: 'Muscle Studs Are Bound, Gagged & Spread For A Deep Cock Pounding. Not even the most rock hard muscled studs can escape punishment & submission on BoundGods.com Watch the hottest studs get tied down, fucked & submitted.', network_id: 'kink', @@ -970,7 +856,6 @@ exports.seed = knex => Promise.resolve() { id: 'boundinpublic', name: 'Bound in Public', - label: 'BoundP', url: 'https://www.kink.com/channel/boundinpublic', description: 'Cum Starved Sluts Humiliated And Fucked Hard In Public By Hung Studs.', network_id: 'kink', @@ -978,7 +863,6 @@ exports.seed = knex => Promise.resolve() { id: 'brutalsessions', name: 'Brutal Sessions', - label: 'Brutal', url: 'https://www.kink.com/channel/brutalsessions', description: "Hardcore BDSM jam packed with XXX fucking in bondage! We're taking dungeon sex beyond the castle!", network_id: 'kink', @@ -986,7 +870,6 @@ exports.seed = knex => Promise.resolve() { id: 'buttmachineboys', name: 'Butt Machine Boys', - label: 'BMBoys', url: 'https://www.kink.com/channel/buttmachineboys', description: 'Powerful Fucking Machines Pound Hot Men Hard & Deep.', network_id: 'kink', @@ -994,7 +877,6 @@ exports.seed = knex => Promise.resolve() { id: 'devicebondage', name: 'Device Bondage', - label: 'DvBond', url: 'https://www.kink.com/channel/devicebondage', description: 'The Domination Of Sluts In Barbaric Metal Devices. Device Bondage takes BDSM porn to new levels with extreme restraints & unique devices with beautiful pornstars to huge, forced squirting orgasms.', network_id: 'kink', @@ -1002,7 +884,6 @@ exports.seed = knex => Promise.resolve() { id: 'devinebitches', name: 'Devine Bitches', - label: 'DBitch', url: 'https://www.kink.com/channel/divinebitches', description: 'Beautiful Women Dominate Submissive Men With Pain, Humiliation And Strap-On Fucking. The best in femdom and bondage. Men on Divine Bitches respond with obedience, ass worship, cunt worship, oral servitude, pantyhose worship, and foot worship.', network_id: 'kink', @@ -1010,7 +891,6 @@ exports.seed = knex => Promise.resolve() { id: 'electrosluts', name: 'Electrosluts', - label: 'ESluts', url: 'https://www.kink.com/channel/electrosluts', description: 'Lezdoms Take Submissive Sluts To Their Limits, Shocking & Tormenting Their Wet Hot Pussies. Pornstars live out their electric bondage fantasies while dominatrixes use electrodes, paddles, caddle prods, & more to bring them to intense orgasms!', network_id: 'kink', @@ -1018,7 +898,6 @@ exports.seed = knex => Promise.resolve() { id: 'everythingbutt', name: 'Everything Butt', - label: 'EvButt', url: 'https://www.kink.com/channel/everythingbutt', description: 'Gaping Anal Holes Are Stuffed & Stretched To The Max. Anal Fisting, Enemas & Rimming Has Never Tasted So Good. EverythingButt.com explores the extreme limits of FemDom lesbian anal. Watch asses get destroyed by brutal fistings, huge insertions, double anal & more!', network_id: 'kink', @@ -1026,7 +905,6 @@ exports.seed = knex => Promise.resolve() { id: 'familiestied', name: 'Families Tied', - label: 'FamTie', url: 'https://www.kink.com/channel/familiestied', description: 'Intense BDSM family role play threesomes & more.', network_id: 'kink', @@ -1034,7 +912,6 @@ exports.seed = knex => Promise.resolve() { id: 'footworship', name: 'Foot Worship', - label: 'FootWS', url: 'https://www.kink.com/channel/footworship', description: 'Satisfy Your Foot Fetish With The Kinkiest Foot Action. Enjoy Trampling, Foot Jobs, High Heels, And Pantyhose.', network_id: 'kink', @@ -1042,7 +919,6 @@ exports.seed = knex => Promise.resolve() { id: 'fuckedandbound', name: 'Fucked and Bound', - label: 'FBound', url: 'https://www.kink.com/channel/fuckedandbound', description: 'Extreme Anal, Rope Bondage, & Brutal Face Fucking.', network_id: 'kink', @@ -1050,7 +926,6 @@ exports.seed = knex => Promise.resolve() { id: 'fuckingmachines', name: 'Fucking Machines', - label: 'FMachi', url: 'https://www.kink.com/channel/fuckingmachines', description: 'Machines Fucking Squirting Pussies With Extreme Insertions. Fucking Machines is the ultimate hardcore sex toy porn. Huge dildos strapped to sex machines relentlessly fucking pornstars to real squirting oragsms!', network_id: 'kink', @@ -1058,7 +933,6 @@ exports.seed = knex => Promise.resolve() { id: 'hardcoregangbang', name: 'Hardcore Gangbang', - label: 'HardGB', url: 'https://www.kink.com/channel/hardcoregangbang', description: "Where all women's hardcore gangbang fantasies come true. Watch extreme, brutal gangbangs with pornstars, models, & MILFs that crave cock in every hole. HardcoreGangbang.com has the best creampie gang bangs online.", network_id: 'kink', @@ -1066,7 +940,6 @@ exports.seed = knex => Promise.resolve() { id: 'hogtied', name: 'Hogtied', - label: 'Hogtie', url: 'https://www.kink.com/channel/hogtied', description: 'Your favorite girls restrained with rope, punished & trained. Hogtied is the original extreme bondage porn website. Watch top pornstars and pain sluts in brutal bondage, getting tormented, and forced to orgasm!', network_id: 'kink', @@ -1074,7 +947,6 @@ exports.seed = knex => Promise.resolve() { id: 'kinkuniversity', name: 'Kink University', - label: 'KinkUn', url: 'https://www.kink.com/channel/kinkuniversity', description: 'Learn BDSM Technical Skills & Theories From Respected Teachers In The Kink Community. Learn BDSM skills and improve your sex techniques. Video tutorials feature top sex ed experts and hardcore demos on topics from bondage to relationships.', network_id: 'kink', @@ -1082,7 +954,6 @@ exports.seed = knex => Promise.resolve() { id: 'meninpain', name: 'Men In Pain', - label: 'MenInP', url: 'https://www.kink.com/channel/meninpain', description: 'Submissive Men Violated With Verbal Humiliation And Harsh Punishment By Beautiful Dominatrices.', network_id: 'kink', @@ -1090,7 +961,6 @@ exports.seed = knex => Promise.resolve() { id: 'menonedge', name: 'Men on Edge', - label: 'MOEdge', url: 'https://www.kink.com/channel/menonedge', description: "Hot Guys Begging To Cum Are Brought To The Edge Of Complete Submission And Allowed To Blow Their Loads. Men on Edge has perfected the art of gay BDSM & edging porn. Watch straight men bound up & edged by dominant gay pornstars until they can't help but cum!", network_id: 'kink', @@ -1098,7 +968,6 @@ exports.seed = knex => Promise.resolve() { id: 'nakedkombat', name: 'Naked Kombat', - label: 'Kombat', url: 'https://www.kink.com/channel/nakedkombat', description: 'Fight Fit Studs Go Head To Head In A Battle For Dominance. The Loser Gets Pinned And Punish Fucked Without Mercy', network_id: 'kink', @@ -1106,7 +975,6 @@ exports.seed = knex => Promise.resolve() { id: 'publicdisgrace', name: 'Public Disgrace', - label: 'PubDis', url: 'https://www.kink.com/channel/publicdisgrace', description: 'Women Bound Stripped And Punished In Public Get Hardcore Fucked Where Everyone Can See. Unscripted public humiliation & punishment of submissive slaves in real life locations. PublicDisgrace features the best outdoor BDSM & voyeur porn!', network_id: 'kink', @@ -1114,7 +982,6 @@ exports.seed = knex => Promise.resolve() { id: 'sadisticrope', name: 'Sadistic Rope', - label: 'SadisR', url: 'https://www.kink.com/channel/sadisticrope', description: 'Innocence Taken By Extreme Rope Bondage, Hardcore BDSM And Pussy-Destroying Orgasms.', network_id: 'kink', @@ -1122,7 +989,6 @@ exports.seed = knex => Promise.resolve() { id: 'sexandsubmission', name: 'Sex and Submission', - label: 'SexSub', url: 'https://www.kink.com/channel/sexandsubmission', description: 'Submissive Sluts Are Dominated With Rough Sex And Bondage. Real pornstars, hardcore bondage, master & slave roles are what SexAndSubmission.com is all about. Watch submissive sluts give in to total domination!', network_id: 'kink', @@ -1130,7 +996,6 @@ exports.seed = knex => Promise.resolve() { id: 'thetrainingofo', name: 'The Training of O', - label: 'TrainO', url: 'https://www.kink.com/channel/thetrainingofo', description: 'Slaves Are Trained And Rewarded With Hardcore Bondage And Sex. Watch real pornstars undergo extreme slave training through hardcore bondage & BDSM porn. The Training of O is the ultimate slave / master experience!', network_id: 'kink', @@ -1138,7 +1003,6 @@ exports.seed = knex => Promise.resolve() { id: 'theupperfloor', name: 'The Upper Floor', - label: 'UFloor', url: 'https://www.kink.com/channel/theupperfloor', description: 'Trained slaves serve the house and their master in intense BDSM and kinky threesomes. The Upper Floor is a voyeuristic look into BDSM and fetish porn shoots with real submissive pornstars living out their kinky fantasies live on cam.', network_id: 'kink', @@ -1146,7 +1010,6 @@ exports.seed = knex => Promise.resolve() { id: 'tspussyhunts', name: 'TS Pussy Hunters', - label: 'TSPuss', url: 'https://www.kink.com/channel/tspussyhunters', description: 'Hot TS cocks prey on the wet pussies of submissive ladies who are fucked hard till they cum. Dominant TS femme fatales with the hardest dicks, the softest tits, and the worst intentions dominate, bind, and punish bitches on the ultimate transfucking porn site.', network_id: 'kink', @@ -1154,7 +1017,6 @@ exports.seed = knex => Promise.resolve() { id: 'tsseduction', name: 'TS Seduction', - label: 'TSeduc', url: 'https://www.kink.com/channel/tsseduction', description: 'Sexy TS Women With Huge Cocks Dominate The Holes Of Straight Boys. Real TS women who are drop-dead gorgeous from their pretty faces to their big tits to their hard TS cocks. TS Seduction is the ultimate in transsexual bondage porn.', network_id: 'kink', @@ -1162,7 +1024,6 @@ exports.seed = knex => Promise.resolve() { id: 'ultimatesurrender', name: 'Ultimate Surrender', - label: 'UltSur', url: 'https://www.kink.com/channel/ultimatesurrender', description: 'Competitive Female Wrestling Where The Loser Gets Strap-On Punish Fucked. Ultimate Surrender features hardcore naked female wrestling porn videos where the winner gets to dominate the loser with some kinky lesbian FemDom!', network_id: 'kink', @@ -1170,7 +1031,6 @@ exports.seed = knex => Promise.resolve() { id: 'waterbondage', name: 'Water Bondage', - label: 'WaterB', url: 'https://www.kink.com/channel/waterbondage', description: 'Helpless Bound Beauties Sprayed, Dunked And Tormented Until They Cum Hard & Wet.', network_id: 'kink', @@ -1178,7 +1038,6 @@ exports.seed = knex => Promise.resolve() { id: 'whippedass', name: 'Whipped Ass', - label: 'WhipdA', url: 'https://www.kink.com/channel/whippedass', description: 'Beautiful Submissive Sluts Take A Hard Fucking From Powerful Dominant Women. Watch brutal lesbian dominatrixes push submissive sluts to their orgasmic breaking points on WhippedAss! Hardcore fisting, huge strapons & face sitting!', network_id: 'kink', @@ -1186,18 +1045,16 @@ exports.seed = knex => Promise.resolve() { id: 'wiredpussy', name: 'Wired Pussy', - label: 'WiredP', url: 'https://www.kink.com/channel/wiredpussy', description: 'Gorgeous Women Submit To Electricity, Are Zapped, Shocked & Prodded To Orgasm.', network_id: 'kink', }, - ])) - .then(() => knex('sites').insert([ + ]).toString()} ON CONFLICT DO NOTHING`)) + .then(() => knex.raw(`${knex('sites').insert([ // LEGALPORNO { id: 'legalporno', name: 'LegalPorno', - label: 'LegalP', url: 'https://www.legalporno.com', description: 'The Best HD Porn For You!', network_id: 'legalporno', @@ -1661,7 +1518,6 @@ exports.seed = knex => Promise.resolve() { id: 'analoverdose', name: 'Anal Overdose', - label: 'AnalOD', url: 'http://www.analoverdose.com', description: 'Before proceeding, use caution: the stunning pornstars of Anal Overdose are so fiery that they cause heavy breathing, throbbing cocks and volcanic loads of cum. If you think you can handle the heat of smoking tits, sweltering pussy and red hot ass.', network_id: 'pervcity', @@ -1670,7 +1526,6 @@ exports.seed = knex => Promise.resolve() { id: 'bangingbeauties', name: 'Banging Beauties', - label: 'BBeaus', description: "Banging Beauties isn't just a porn site; it's the gateway to all your pussy-obsessed fantasies! Our members' area is flowing with beautiful pornstars anticipating big dick throbbing in their syrupy pink slits. These experienced babes love brutal vaginal pounding! Similarly, they're eager for anal switch-hitting to shake things up. However, it's not only about gorgeous sexperts filling their hungry holes. Sometimes, it's all about innocent rookies earning their pornstar status in first time threesomes and premier interracial scenes.", url: 'http://www.bangingbeauties.com', network_id: 'pervcity', @@ -1679,7 +1534,6 @@ exports.seed = knex => Promise.resolve() { id: 'oraloverdose', name: 'Oral Overdose', - label: 'OralOD', description: "Oral Overdose is the only site you need to live out every saliva soaked blowjob of your dreams in HD POV! We've got the most stunning cocksuckers in the world going to town on big dick. These babes not only love cock, they can't get enough of it! In fact, there is no prick too huge for our hungry girls' throats. You'll find gorgeous, big tits pornstars exercising their gag reflex in intense balls deep facefuck scenes. We also feature fresh, young newbies taking on the gagging deepthroat challenge.", url: 'http://www.oraloverdose.com', network_id: 'pervcity', @@ -1688,7 +1542,6 @@ exports.seed = knex => Promise.resolve() { id: 'chocolatebjs', name: 'Chocolate BJs', - label: 'ChocBJ', description: "You've just won the golden ticket to the best Chocolate BJs on the planet! We've sought far and wide to bring you the most beautiful black and ethnic pornstars. And they're in our members' area now! They can't wait to suck your white lollipop and lick the thick cream shooting from your big dick. Of course, no matter how sweet the booty or juicy the big tits, these brown foxes aren't all sugar and spice. In fact, when it comes to giving head, these big ass ebony babes know what they want: huge white cocks filling their throats!", url: 'http://www.chocolatebjs.com', network_id: 'pervcity', @@ -1697,17 +1550,16 @@ exports.seed = knex => Promise.resolve() { id: 'upherasshole', name: 'Up Her Asshole', - label: 'UpHerA', description: "You don't need to travel the globe in search of the anal wonders of the world, because you get your own private tour right here on Up Her Asshole! Our stunning pornstars and rookie starlets welcome all ass fetish and anal sex fans, with their twerking bubble butts and winking assholes. However, big booty worship is just a slice of the fun. Combined with juicy tits (big and small), wet pussy (hairy and bald), these girls deliver a spectacular sensory experience in HD POV. Not only are you in danger of busting a nut before the going gets good, but also when the good turns remarkable with rimming, fingering and butt toys!", url: 'http://www.upherasshole.com', network_id: 'pervcity', parameters: JSON.stringify({ tourId: 9 }), }, + // PORN PROS // PRIVATE { id: 'analintroductions', name: 'Anal Introductions', - label: 'AIntro', description: 'Private\'s Anal Introductions is all about ass. Watch these girls get their asses broken in by fat hard cocks! Hot double penetrations, gaping wide assholes and anal creampies are all standard in this exclusive site. Many of these girls have never had cock in their ass before, while others are real addicts and can only cum when being savagely sodomised. Watch which girls can take it... Private style.', url: 'https://www.private.com/site/anal-introductions', network_id: 'private', @@ -1715,7 +1567,6 @@ exports.seed = knex => Promise.resolve() { id: 'iconfessfiles', name: 'I Confess Files', - label: 'confes', description: 'From the heart of the UK comes found footage exclusively provided to private.com which will shock and offend some viewers. Reality, perversion and unnatural lust come together perhaps as never before.', url: 'https://www.private.com/site/i-confess-files', network_id: 'private', @@ -1723,7 +1574,6 @@ exports.seed = knex => Promise.resolve() { id: 'missionasspossible', name: 'Mission: Ass Possible', - label: 'misass', description: 'From the streets of Europe, Private\'s team of professionals find and exploit clueless young sluts, for some great sex and for your viewing pleasure. See what young hot chicks will do when their desire for easy fame or money makes them vulnerable to some of the craziest schemes and plots imaginable. Private\'s hung studs are on a mission for ass and hungry for fun. All part of the Private network of sites.', url: 'https://www.private.com/site/mission-ass-possible', network_id: 'private', @@ -1731,7 +1581,6 @@ exports.seed = knex => Promise.resolve() { id: 'russianfakeagent', name: 'Russian Fake Agent', - label: 'rsfake', description: 'Direct from Russia, young naïve women pursue their dream of visas, Hollywood and fame. Eager to please and willing to do anything to get their break. Unfortunately, it’s a case of lies, sex and videotape as these gullible hotties perform for us. If these girls only knew the truth!', url: 'https://www.private.com/site/russian-fake-agent', network_id: 'private', @@ -1739,7 +1588,6 @@ exports.seed = knex => Promise.resolve() { id: 'sexonthebeach', name: 'Sex on the Beach', - label: 'sexbch', description: 'Amazing locations and steamy sex in the sun, www.privatetropics.com is a celebration of tropical lust and sand covered sluts. From Private\'s exclusive line of scenes in exotic countries, watch what happens when our hot models go naked and native.', url: 'https://www.private.com/site/sex-on-the-beach', network_id: 'private', @@ -1747,7 +1595,6 @@ exports.seed = knex => Promise.resolve() { id: 'tightandteen', name: 'Tight and Teen', - label: 'tightt', description: 'Europe\'s number one teen offering and part of the Private network of sites, Tight and Teen takes you to the place that every father dreads, as 18+ teens discover just how much fun pleasing a hung stud can be. Fresh tight pussies, virgin anal initiations and teen face fuckings all brought to you exclusively by Europe\'s leading adult brand.', url: 'https://www.private.com/site/tight-and-teen', network_id: 'private', @@ -1755,7 +1602,6 @@ exports.seed = knex => Promise.resolve() { id: 'blacksonsluts', name: 'Blacks on Sluts', - label: 'blslut', description: 'See what happens when European women discover hung black studs looking to breed. Blacks on Sluts is 100% white slut and cheating wives versus huge black dicks giving them something they will never forget. Private puts its stamp on these women as our stallions stretch them to their limits.', url: 'https://www.private.com/site/blacks-on-sluts', network_id: 'private', @@ -1763,7 +1609,6 @@ exports.seed = knex => Promise.resolve() { id: 'privatefetish', name: 'Private Fetish', - label: 'privft', description: 'www.privatefetish.com is here to give you that taste of dark desire that you secretly crave. Domination and Submission, Pleasure and Pain, are the drivers in this hardcore dungeon. What turns you on most? Being forced to beg for release from a sexy dominatrix or making that bitch next door beg for your cock? All part of Private\'s network of sites.', url: 'https://www.private.com/site/private-fetish', network_id: 'private', @@ -1771,7 +1616,6 @@ exports.seed = knex => Promise.resolve() { id: 'privatemilfs', name: 'Private MILFs', - label: 'prmilf', description: 'Part of the awesome network of Private sites, Private MILFs is all about moms who are getting what they need when their limp dicked husbands can\'t perform. From their daughters\' stud boyfriends to their husbands\' hung black co-workers to their sons\' friends, no one is safe from their cravings for hard cock and salty cum.', url: 'https://www.private.com/site/private-milfs', network_id: 'private', @@ -1779,7 +1623,6 @@ exports.seed = knex => Promise.resolve() { id: 'russianteenass', name: 'Russian Teen Ass', - label: 'rusass', description: 'Many people say that Russian girls are the most beautiful in the world, and at www.russianteenass.com we show you why. These sexy Soviet newcomers are ready to work hard for their visa and their big shot at stardom. These barely 18+ girls know what they want and Private gives them an exclusive opportunity to get it. From Russia with lust, come see these girls in action!', url: 'https://www.private.com/site/russian-teen-ass', network_id: 'private', @@ -1787,13 +1630,12 @@ exports.seed = knex => Promise.resolve() { id: 'privatestars', name: 'Private Stars', - label: 'prstar', description: 'Welcome to Private Stars. The name speaks for itself as only top-model babes and perfect girls can join this select group of stars, all shot in HD. Part of the Private network of sites, Private Stars brings you a sneak peek into the life of seductive glamour girls who could have easily stepped from the catwalks of Paris or Milan and straight into a world of torrid sex.', url: 'https://www.private.com/site/private-stars', network_id: 'private', }, - ])) - .then(() => knex('sites').insert([ + ]).toString()} ON CONFLICT DO NOTHING`)) + .then(() => knex.raw(`${knex('sites').insert([ // REALITY KINGS { id: 'momsbangteens', @@ -2123,7 +1965,6 @@ exports.seed = knex => Promise.resolve() { id: 'vixen', name: 'Vixen', - label: 'Vixen', description: 'Vixen.com features the world’s finest cinematic adult films with 4K quality and high-end erotic photography.', url: 'https://www.vixen.com', network_id: 'vixen', @@ -2131,7 +1972,6 @@ exports.seed = knex => Promise.resolve() { id: 'blacked', name: 'Blacked', - label: 'Blackd', description: 'Porn videos of beautiful girls in first time interracial porn videos. BLACKED has the hottest pornstars in HD sex videos.', url: 'https://www.blacked.com', network_id: 'vixen', @@ -2139,7 +1979,6 @@ exports.seed = knex => Promise.resolve() { id: 'tushy', name: 'Tushy', - label: 'Tushy', description: 'Watch the world\'s best HD Anal videos! Featuring beautiful, never before seen girls in first time anal. Exclusively on Tushy.com', url: 'https://www.tushy.com', network_id: 'vixen', @@ -2147,7 +1986,6 @@ exports.seed = knex => Promise.resolve() { id: 'blackedraw', name: 'Blacked Raw', - label: 'BlkRaw', description: 'Experience real women in interracial sex videos. Passionate sex with beautiful pornstars. No photoshop just the highest quality porn. Everything you see is real.', url: 'https://www.blackedraw.com', network_id: 'vixen', @@ -2155,7 +1993,6 @@ exports.seed = knex => Promise.resolve() { id: 'tushyraw', name: 'Tushy Raw', - label: 'TshRaw', description: 'Anal sex videos with beautiful models and pornstars being fucked in the ass. TUSHY RAW features famous pornstars in high quality anal porn videos.', url: 'https://www.tushyraw.com', network_id: 'vixen', @@ -2164,7 +2001,6 @@ exports.seed = knex => Promise.resolve() { id: 'hardx', name: 'HardX', - label: 'HardX', description: "Welcome to HardX.com, home of exclusive hardcore gonzo porn and first time anal scenes, DP, blowbangs and gangbangs from today's hottest porn stars!", url: 'https://www.hardx.com', network_id: 'xempire', @@ -2172,7 +2008,6 @@ exports.seed = knex => Promise.resolve() { id: 'eroticax', name: 'EroticaX', - label: 'EroX', description: 'EroticaX.com features intimate scenes of passionate, erotic sex. Watch the sensual side of hardcore porn as your favorite pornstars have real, intense orgasms.', url: 'https://www.eroticax.com', network_id: 'xempire', @@ -2180,7 +2015,6 @@ exports.seed = knex => Promise.resolve() { id: 'darkx', name: 'DarkX', - label: 'DarkX', description: 'Watch interracial BBC porn videos on DarkX.com, featuring the best pornstars taking big black cock in exclusive scenes. The best black on white porn inside!', url: 'https://www.darkx.com', network_id: 'xempire', @@ -2188,9 +2022,8 @@ exports.seed = knex => Promise.resolve() { id: 'lesbianx', name: 'LesbianX', - label: 'LesX', description: "LesbianX.com features today's top pornstars in hardcore lesbian porn. Watch passionate & intense girl on girl sex videos, from erotic kissing to pussy licking.", url: 'https://www.lesbianx.com', network_id: 'xempire', }, - ])); + ]).toString()} ON CONFLICT DO NOTHING`)); diff --git a/seeds/tags.js b/seeds/02_tags.js similarity index 92% rename from seeds/tags.js rename to seeds/02_tags.js index 3f4e76ea..ae240ebf 100644 --- a/seeds/tags.js +++ b/seeds/02_tags.js @@ -2,9 +2,7 @@ /* eslint-disable max-len */ exports.seed = knex => Promise.resolve() - .then(() => knex('tags').del()) - .then(() => knex('tags_groups').del()) - .then(() => knex('tags_groups').insert([ + .then(() => knex.raw(`${knex('tags_groups').insert([ { group: 'age', name: 'Age', @@ -45,8 +43,8 @@ exports.seed = knex => Promise.resolve() group: 'roleplay', name: 'Roleplay', }, - ])) - .then(() => knex('tags').insert([ + ]).toString()} ON CONFLICT DO NOTHING`)) + .then(() => knex.raw(`${knex('tags').insert([ { tag: '69', alias_for: null, @@ -62,9 +60,10 @@ exports.seed = knex => Promise.resolve() alias_for: null, }, { - tag: 'American', + tag: 'american', alias_for: null, group_id: 'ethnicity', + capitalization: 1, }, { tag: 'anal creampie', @@ -105,8 +104,9 @@ exports.seed = knex => Promise.resolve() group_id: 'body', }, { - tag: 'ATM', + tag: 'atm', alias_for: null, + capitalization: 2, }, { tag: 'ball licking', @@ -123,13 +123,15 @@ exports.seed = knex => Promise.resolve() group_id: 'location', }, { - tag: 'BDSM', + tag: 'bdsm', alias_for: null, + capitalization: 2, }, { - tag: 'BBC', + tag: 'bbc', alias_for: null, group_id: 'body', + capitalization: 2, }, { tag: 'big cock', @@ -224,24 +226,27 @@ exports.seed = knex => Promise.resolve() alias_for: null, }, { - tag: 'DAP', + tag: 'dap', alias_for: null, + capitalization: 2, }, { tag: 'deepthroat', alias_for: null, }, { - tag: 'DP', + tag: 'dp', alias_for: null, + capitalization: 2, }, { tag: 'dungeon', alias_for: null, }, { - tag: 'DVP', + tag: 'dvp', alias_for: null, + capitalization: 2, }, { tag: 'double blowjob', @@ -270,9 +275,10 @@ exports.seed = knex => Promise.resolve() alias_for: null, }, { - tag: 'European', + tag: 'european', alias_for: null, group_id: 'ethnicity', + capitalization: 1, }, { tag: 'facefuck', @@ -305,9 +311,10 @@ exports.seed = knex => Promise.resolve() alias_for: null, }, { - tag: 'FMF', + tag: 'fmf', alias_for: null, group_id: 'group', + capitalization: 2, }, { tag: 'gag', @@ -341,9 +348,10 @@ exports.seed = knex => Promise.resolve() group_id: 'clothing', }, { - tag: 'Hungarian', + tag: 'hungarian', alias_for: null, group_id: 'ethnicity', + capitalization: 1, }, { tag: 'humiliation', @@ -396,14 +404,16 @@ exports.seed = knex => Promise.resolve() alias_for: null, }, { - tag: 'MILF', + tag: 'milf', alias_for: null, group_id: 'age', + capitalization: 2, }, { - tag: 'MFM', + tag: 'mfm', alias_for: null, group_id: 'group', + capitalization: 2, }, { tag: 'miniskirt', @@ -484,9 +494,10 @@ exports.seed = knex => Promise.resolve() alias_for: null, }, { - tag: 'Russian', + tag: 'russian', alias_for: null, group_id: 'ethnicity', + capitalization: 1, }, { tag: 'saliva', @@ -594,8 +605,9 @@ exports.seed = knex => Promise.resolve() alias_for: null, }, { - tag: 'TP', + tag: 'tp', alias_for: null, + capitalization: 2, }, { tag: 'trimmed', @@ -631,12 +643,12 @@ exports.seed = knex => Promise.resolve() alias_for: null, group_id: 'location', }, - ])) - .then(() => knex('tags').insert([ + ]).toString()} ON CONFLICT DO NOTHING`)) + .then(() => knex.raw(`${knex('tags').insert([ // ALIASES { tag: '2-on-1', - alias_for: 'MFM', + alias_for: 'mfm', }, { tag: '3+ on 1', @@ -656,7 +668,7 @@ exports.seed = knex => Promise.resolve() }, { tag: 'ass to mouth', - alias_for: 'ATM', + alias_for: 'atm', }, { tag: 'bald pussy', @@ -668,7 +680,7 @@ exports.seed = knex => Promise.resolve() }, { tag: 'BGB', - alias_for: 'MFM', + alias_for: 'mfm', }, { tag: 'big ass', @@ -676,11 +688,11 @@ exports.seed = knex => Promise.resolve() }, { tag: 'big black cock', - alias_for: 'BBC', + alias_for: 'bbc', }, { tag: 'big black cocks', - alias_for: 'BBC', + alias_for: 'bbc', }, { tag: 'big cocks', @@ -840,11 +852,11 @@ exports.seed = knex => Promise.resolve() }, { tag: 'dom', - alias_for: 'BDSM', + alias_for: 'bdsm', }, { tag: 'domination', - alias_for: 'BDSM', + alias_for: 'bdsm', }, { tag: 'dominatrix', @@ -852,51 +864,51 @@ exports.seed = knex => Promise.resolve() }, { tag: 'double anal penetration', - alias_for: 'DAP', + alias_for: 'dap', }, { tag: 'double anal (dap)', - alias_for: 'DAP', + alias_for: 'dap', }, { tag: 'double anal penetration (dap)', - alias_for: 'DAP', + alias_for: 'dap', }, { tag: 'double penetration', - alias_for: 'DP', + alias_for: 'dp', }, { tag: 'double penetration (dp)', - alias_for: 'DP', + alias_for: 'dp', }, { - tag: 'DPP', - alias_for: 'DVP', + tag: 'dpP', + alias_for: 'dvp', }, { tag: 'double vaginal penetration', - alias_for: 'DVP', + alias_for: 'dvp', }, { tag: 'double vaginal (dvp)', - alias_for: 'DVP', + alias_for: 'dvp', }, { tag: 'double vaginal penetration (dvp)', - alias_for: 'DVP', + alias_for: 'dvp', }, { tag: 'double vaginal (dpp)', - alias_for: 'DVP', + alias_for: 'dvp', }, { tag: 'double pussy penetration', - alias_for: 'DVP', + alias_for: 'dvp', }, { tag: 'double pussy penetration (dpp)', - alias_for: 'DVP', + alias_for: 'dvp', }, { tag: 'drool', @@ -926,6 +938,10 @@ exports.seed = knex => Promise.resolve() tag: 'face sitting', alias_for: 'facesitting', }, + { + tag: 'facial cumshot', + alias_for: 'facial', + }, { tag: 'facials', alias_for: 'facial', @@ -995,12 +1011,12 @@ exports.seed = knex => Promise.resolve() alias_for: 'miniskirt', }, { - tag: 'MMF', - alias_for: 'MFM', + tag: 'mmf', + alias_for: 'mfm', }, { - tag: 'MFF', - alias_for: 'FMF', + tag: 'mff', + alias_for: 'fmf', }, { tag: 'natural', @@ -1076,11 +1092,11 @@ exports.seed = knex => Promise.resolve() }, { tag: 'sadomasochism', - alias_for: 'BDSM', + alias_for: 'bdsm', }, { tag: 'sadism', - alias_for: 'BDSM', + alias_for: 'bdsm', }, { tag: 'scissoring', @@ -1100,7 +1116,7 @@ exports.seed = knex => Promise.resolve() }, { tag: 'slave', - alias_for: 'BDSM', + alias_for: 'bdsm', }, { tag: 'small ass', @@ -1116,7 +1132,7 @@ exports.seed = knex => Promise.resolve() }, { tag: 'spitroast', - alias_for: 'MFM', + alias_for: 'mfm', }, { tag: 'standing doggystyle', @@ -1140,11 +1156,11 @@ exports.seed = knex => Promise.resolve() }, { tag: 'sub', - alias_for: 'BDSM', + alias_for: 'bdsm', }, { tag: 'submission', - alias_for: 'BDSM', + alias_for: 'bdsm', }, { tag: 'tattoos', @@ -1172,7 +1188,7 @@ exports.seed = knex => Promise.resolve() }, { tag: 'triple penetration', - alias_for: 'TP', + alias_for: 'tp', }, { tag: 'whipping', @@ -1190,4 +1206,4 @@ exports.seed = knex => Promise.resolve() tag: 'zapper', alias_for: 'electric shock', }, - ])); + ]).toString()} ON CONFLICT DO NOTHING`)); diff --git a/src/app.js b/src/app.js index f89d2400..862f0ad1 100644 --- a/src/app.js +++ b/src/app.js @@ -5,6 +5,7 @@ const clipboard = require('clipboardy'); const argv = require('./argv'); const { renderReleases, renderScene } = require('./tui/render'); +const initServer = require('./web/server'); const fetchReleases = require('./fetch-releases'); const fetchScene = require('./fetch-scene'); @@ -34,35 +35,43 @@ function getMethod() { }; } - return { - fetch: () => fetchReleases(), - render: renderReleases, - }; + if (argv.fetch) { + return { + fetch: () => fetchReleases(), + render: renderReleases, + }; + } + + return null; } async function init() { - const screen = argv.render && !argv.filename && initScreen(); + initServer(); + const screen = argv.render && !argv.filename && initScreen(); try { const method = getMethod(); - const result = await method.fetch(); - if (result) { - if (argv.copy && result.copy) { - clipboard.writeSync(result.copy); - console.log(`Result copied to clipboard: ${result.copy}`); - } + if (method) { + const result = await method.fetch(); - if (argv.filename && result.filename) { - console.log(result.filename); + if (result) { + if (argv.copy && result.copy) { + clipboard.writeSync(result.copy); + console.log(`Result copied to clipboard: ${result.copy}`); + } - // setTimeout(() => log(), 5000); - return; - } + if (argv.filename && result.filename) { + console.log(result.filename); - if (argv.render) { - method.render(result, screen); + // setTimeout(() => log(), 5000); + return; + } + + if (argv.render) { + method.render(result, screen); + } } } } catch (error) { diff --git a/src/argv.js b/src/argv.js index 7aa968ca..d7af6580 100644 --- a/src/argv.js +++ b/src/argv.js @@ -5,6 +5,16 @@ const yargs = require('yargs'); const { argv } = yargs .command('npm start') + .option('fetch', { + describe: 'Fetch latest releases', + type: 'boolean', + default: false, + }) + .option('deep', { + describe: 'Fetch details for all releases', + type: 'boolean', + default: false, + }) .option('networks', { describe: 'Networks to include (overrides config)', type: 'array', @@ -23,12 +33,12 @@ const { argv } = yargs .option('save', { describe: 'Save fetched releases to database', type: 'boolean', - default: true, + default: false, }) .option('render', { describe: 'Fetch data without rendering interface', type: 'boolean', - default: true, + default: false, }) .option('scene', { describe: 'Fetch scene info from URL', diff --git a/src/fetch-releases.js b/src/fetch-releases.js index dc138750..dba72a32 100644 --- a/src/fetch-releases.js +++ b/src/fetch-releases.js @@ -1,11 +1,13 @@ 'use strict'; const config = require('config'); +const Promise = require('bluebird'); const moment = require('moment'); const argv = require('./argv'); const knex = require('./knex'); const scrapers = require('./scrapers'); +const fetchScene = require('./fetch-scene'); function destructConfigNetworks(networks) { return networks.reduce((acc, network) => { @@ -72,32 +74,48 @@ async function findDuplicateReleases(latestReleases, _siteId) { .orWhereIn('entry_id', latestReleasesEntryIds); } -async function storeReleases(releases) { - const curatedReleases = releases.map(release => ({ - site_id: release.site.id, - shoot_id: release.shootId || null, - entry_id: release.entryId || null, - url: release.url, - title: release.title, - date: release.date, - description: release.description, - director: release.director, - duration: release.duration, - likes: release.rating && release.rating.likes, - dislikes: release.rating && release.rating.dislikes, - rating: release.rating && release.rating.stars, - })); +async function storeReleases(releases = []) { + return Promise.reduce(releases, async (acc, release) => { + await acc; - if (curatedReleases.length) { - console.log(`Saving ${curatedReleases.length} new releases to database`); + const curatedRelease = { + site_id: release.site.id, + shoot_id: release.shootId || null, + entry_id: release.entryId || null, + url: release.url, + title: release.title, + date: release.date, + description: release.description, + director: release.director, + duration: release.duration, + likes: release.rating && release.rating.likes, + dislikes: release.rating && release.rating.dislikes, + rating: release.rating && release.rating.stars, + }; - const insertQuery = knex('releases').insert(curatedReleases).toString(); - await knex.raw(insertQuery.replace('insert', 'INSERT OR IGNORE')); + const releaseQuery = `${knex('releases').insert(curatedRelease).toString()} ON CONFLICT DO NOTHING RETURNING *`; + const releaseEntry = await knex.raw(releaseQuery); - return curatedReleases; - } + if (release.actors && release.actors.length > 0) { + const actors = await knex('actors').whereIn('name', release.actors); + const newActors = release.actors.filter(actorName => !actors.some(actor => actor.name === actorName)); + const { rows: insertedActors } = newActors.length + ? await knex.raw(`${knex('actors').insert(newActors.map(actorName => ({ name: actorName })))} ON CONFLICT DO NOTHING RETURNING *`) + : { rows: [] }; - return []; + await knex('actors_associated').insert(actors.concat(insertedActors).map(actor => ({ + release_id: releaseEntry.rows[0].id, + actor_id: actor.id, + })), '*'); + } + + if (release.tags && release.tags.length > 0) { + await knex('tags_associated').insert(release.tags.map(tag => ({ + tag_id: tag, + release_id: releaseEntry.rows[0].id, + }))); + } + }, []); } async function fetchNewReleases(scraper, site, afterDate, accReleases = [], page = 1) { @@ -148,7 +166,21 @@ async function fetchReleases() { console.log(`${site.name}: Found ${newReleases.length} recent releases, ${upcomingReleases.length} upcoming releases`); if (argv.save) { - await storeReleases(newReleases); + const finalReleases = argv.deep + ? await Promise.all(newReleases.map(async (release) => { + if (release.url) { + return fetchScene(release.url); + } + + return release; + }), { + concurrency: 2, + }) + : newReleases; + + console.log(finalReleases); + + await storeReleases(finalReleases); } return [ @@ -176,8 +208,6 @@ async function fetchReleases() { return []; })); - knex.destroy(); - const accumulatedScenes = scenesPerSite.reduce((acc, siteScenes) => ([...acc, ...siteScenes]), []); const sortedScenes = accumulatedScenes.sort(({ date: dateA }, { date: dateB }) => moment(dateB).diff(dateA)); diff --git a/src/fetch-scene.js b/src/fetch-scene.js index ab2a1627..642bc1b3 100644 --- a/src/fetch-scene.js +++ b/src/fetch-scene.js @@ -4,6 +4,7 @@ const config = require('config'); const moment = require('moment'); const knex = require('./knex'); +const argv = require('./argv'); const scrapers = require('./scrapers'); async function findSite(url) { @@ -72,6 +73,33 @@ function deriveFilename(scene) { return filename; } +async function storeRelease(release) { + const curatedRelease = { + site_id: release.site.id, + shoot_id: release.shootId || null, + entry_id: release.entryId || null, + url: release.url, + title: release.title, + date: release.date, + description: release.description, + director: release.director, + duration: release.duration, + likes: release.rating && release.rating.likes, + dislikes: release.rating && release.rating.dislikes, + rating: release.rating && release.rating.stars, + }; + + console.log('Saving releases to database'); + await knex.raw(`${knex('releases').insert(curatedRelease).toString()} ON CONFLICT (site_id, shoot_id) DO UPDATE SET + description = EXCLUDED.description, + likes = EXCLUDED.likes, + dislikes = EXCLUDED.dislikes, + rating = EXCLUDED.rating + `); + + return release; +} + async function fetchScene(url) { const site = await findSite(url); const scraper = scrapers[site.id] || scrapers[site.network.id]; @@ -87,7 +115,11 @@ async function fetchScene(url) { const scene = await scraper.fetchScene(url, site); const filename = deriveFilename(scene); - knex.destroy(); + if (argv.save) { + await storeRelease(scene); + } + + // knex.destroy(); return { ...scene, diff --git a/src/knex.js b/src/knex.js index 200c6e86..0947d66a 100644 --- a/src/knex.js +++ b/src/knex.js @@ -1,11 +1,19 @@ 'use strict'; +const config = require('config'); const knex = require('knex'); +/* module.exports = knex({ client: 'sqlite3', connection: { - filename: './db.sqlite', + filename: path.join(__dirname, '../db.sqlite'), }, useNullAsDefault: true, }); +*/ + +module.exports = knex({ + client: 'pg', + connection: config.database, +}); diff --git a/src/releases.js b/src/releases.js new file mode 100644 index 00000000..c6a1d5e6 --- /dev/null +++ b/src/releases.js @@ -0,0 +1,52 @@ +'use strict'; + +const knex = require('./knex'); + +async function curateRelease(release) { + const actors = await knex('actors_associated') + .select('actors.id', 'actors.name', 'actors.gender') + .where({ release_id: release.id }) + .leftJoin('actors', 'actors.id', 'actors_associated.actor_id'); + + return { + id: release.id, + title: release.title, + date: release.date, + description: release.description, + url: release.url, + shootId: release.shoot_id, + entryId: release.entry_id, + actors, + director: release.director, + rating: { + likes: release.likes, + dislikes: release.dislikes, + stars: release.stars, + }, + site: { + id: release.site_id, + name: release.site_name, + network: release.network_id, + }, + }; +} + +function curateReleases(releases) { + return Promise.all(releases.map(async release => curateRelease(release))); +} + +async function fetchReleases() { + const releases = await knex('releases') + .select('releases.*', 'sites.name as site_name') + .leftJoin('sites', 'releases.site_id', 'sites.id') + .orderBy('date', 'desc') + .limit(100); + + // console.log(curateReleases(releases)); + + return curateReleases(releases); +} + +module.exports = { + fetchReleases, +}; diff --git a/src/scrapers/kink.js b/src/scrapers/kink.js index d91b9661..ef2e56c8 100644 --- a/src/scrapers/kink.js +++ b/src/scrapers/kink.js @@ -58,7 +58,7 @@ async function scrapeScene(html, url, shootId, ratingRes, site) { .toDate(); const actors = $(actorsRaw).find('span.names a').map((actorIndex, actorElement) => $(actorElement).text()).toArray(); - const description = $('.shoot-info .description').text(); + const description = $('.shoot-info .description').text().trim(); const { average: stars } = ratingRes.body; diff --git a/src/tags.js b/src/tags.js index 14337db7..d806e137 100644 --- a/src/tags.js +++ b/src/tags.js @@ -3,16 +3,9 @@ const knex = require('./knex'); async function matchTags(rawTags) { - const tagQuery = knex('tags') - .select(knex.raw('ifnull(original.tag, tags.tag) as tag'), knex.raw('ifnull(original.tag, tags.tag) as tag')) - .whereIn('tags.tag', rawTags) - .leftJoin('tags as original', 'tags.alias_for', 'original.tag') - .toString() - .replace('where `tags`.`tag` in', 'where `tags`.`tag` collate NOCASE in'); + const tagEntries = await knex('tags').whereIn('tags.tag', rawTags.map(tag => tag.toLowerCase())); - const tagEntries = await knex.raw(tagQuery); - - return Array.from(new Set(tagEntries.map(({ tag }) => tag))).sort(); // reduce to tag name and filter duplicates + return Array.from(new Set(tagEntries.map((tag => tag.alias_for || tag.tag)).sort())); // reduce to tag name and filter duplicates } module.exports = { matchTags }; diff --git a/src/utils/rename.js b/src/utils/rename.js new file mode 100644 index 00000000..a4346887 --- /dev/null +++ b/src/utils/rename.js @@ -0,0 +1,29 @@ +'use strict'; + +const path = require('path'); +const Promise = require('bluebird'); +const fs = require('fs-extra'); +const fetchScene = require('../fetch-scene'); + +const argv = require('../argv'); + +async function renameFiles() { + const filenames = await fs.readdir(process.cwd()); + + const curated = await Promise.map(filenames, async (filename) => { + const shootId = filename.split(' ')[1]; + const scene = await fetchScene(`https://kink.com/shoot/${shootId}`); + + if (argv.confirm) { + await fs.rename(path.join(process.cwd(), filename), path.join(process.cwd(), `${scene.filename}.mp4`)); + } + + return scene.filename; + }, { + concurrency: 5, + }); + + console.log(curated); +} + +renameFiles(); diff --git a/src/web/releases.js b/src/web/releases.js new file mode 100644 index 00000000..7fdd1f5a --- /dev/null +++ b/src/web/releases.js @@ -0,0 +1,13 @@ +'use strict'; + +const { fetchReleases } = require('../releases'); + +async function fetchReleasesApi(req, res) { + const releases = await fetchReleases(); + + res.render('home', { releases }); +} + +module.exports = { + fetchReleases: fetchReleasesApi, +}; diff --git a/src/web/server.js b/src/web/server.js new file mode 100644 index 00000000..a86b91de --- /dev/null +++ b/src/web/server.js @@ -0,0 +1,28 @@ +'use strict'; + +const path = require('path'); +const config = require('config'); +const express = require('express'); +const Router = require('express-promise-router'); +const { createEngine } = require('express-react-views'); + +const { fetchReleases } = require('./releases'); + +function initServer() { + const app = express(); + const router = Router(); + + app.set('views', path.join(__dirname, '../../assets/views')); + app.set('view engine', 'jsx'); + app.engine('jsx', createEngine()); + + router.get('/', fetchReleases); + + app.use(router); + + app.listen(config.web.port, () => { + console.log(`Web server listening on port ${config.web.port}`); + }); +} + +module.exports = initServer;